Skip to content

Commit bdde550

Browse files
committed
Add workspace report stats endpoint
1 parent 7a9dc0c commit bdde550

File tree

3 files changed

+89
-2
lines changed

3 files changed

+89
-2
lines changed

agent/stats.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ type ConnStats struct {
1616
RxBytes uint64 `json:"rx_bytes,omitempty"`
1717

1818
// TxBytes must be read with atomic.
19-
TxBytes uint64 `json:"tx_bytes,omitempty"`
20-
19+
TxBytes uint64 `json:"tx_bytes,omitempty"`
2120
net.Conn `json:"-"`
2221
}
2322

coderd/workspaceagents.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import (
88
"io"
99
"net"
1010
"net/http"
11+
"os"
1112
"strconv"
13+
"strings"
1214
"time"
1315

1416
"github.com/google/uuid"
@@ -17,6 +19,7 @@ import (
1719
"golang.org/x/xerrors"
1820
"inet.af/netaddr"
1921
"nhooyr.io/websocket"
22+
"nhooyr.io/websocket/wsjson"
2023
"tailscale.com/types/key"
2124

2225
"cdr.dev/slog"
@@ -152,6 +155,80 @@ func (api *API) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request)
152155
})
153156
}
154157

158+
var inTest = strings.HasSuffix(os.Args[0], ".test")
159+
160+
func (api *API) workspaceAgentReportStats(rw http.ResponseWriter, r *http.Request) {
161+
api.websocketWaitMutex.Lock()
162+
api.websocketWaitGroup.Add(1)
163+
api.websocketWaitMutex.Unlock()
164+
defer api.websocketWaitGroup.Done()
165+
166+
workspaceAgent := httpmw.WorkspaceAgent(r)
167+
workspace, err := api.Database.GetWorkspaceResourceByID(r.Context(), workspaceAgent.ResourceID)
168+
if err != nil {
169+
httpapi.Write(rw, http.StatusBadRequest, codersdk.Response{
170+
Message: "Failed to accept websocket.",
171+
Detail: err.Error(),
172+
})
173+
return
174+
}
175+
176+
conn, err := websocket.Accept(rw, r, &websocket.AcceptOptions{
177+
CompressionMode: websocket.CompressionDisabled,
178+
})
179+
if err != nil {
180+
httpapi.Write(rw, http.StatusBadRequest, codersdk.Response{
181+
Message: "Failed to accept websocket.",
182+
Detail: err.Error(),
183+
})
184+
return
185+
}
186+
defer conn.Close(websocket.StatusAbnormalClosure, "")
187+
188+
var interval = time.Minute
189+
if inTest {
190+
interval = 100 * time.Millisecond
191+
}
192+
193+
ctx := r.Context()
194+
timer := time.NewTimer(interval)
195+
for {
196+
err := wsjson.Write(ctx, conn, codersdk.AgentStatsReportRequest{})
197+
if err != nil {
198+
httpapi.Write(rw, http.StatusBadRequest, codersdk.Response{
199+
Message: "Failed to write report request.",
200+
Detail: err.Error(),
201+
})
202+
return
203+
}
204+
var rep codersdk.AgentStatsReportResponse
205+
206+
err = wsjson.Read(ctx, conn, &rep)
207+
if err != nil {
208+
httpapi.Write(rw, http.StatusBadRequest, codersdk.Response{
209+
Message: "Failed to read report response.",
210+
Detail: err.Error(),
211+
})
212+
return
213+
}
214+
215+
api.Logger.Debug(ctx, "read stats report",
216+
slog.F("agent", workspaceAgent.ID),
217+
slog.F("workspace", workspace.ID),
218+
slog.F("report", rep),
219+
)
220+
221+
select {
222+
case <-timer.C:
223+
continue
224+
case <-ctx.Done():
225+
conn.Close(websocket.StatusNormalClosure, "")
226+
return
227+
}
228+
}
229+
230+
}
231+
155232
func (api *API) workspaceAgentListen(rw http.ResponseWriter, r *http.Request) {
156233
api.websocketWaitMutex.Lock()
157234
api.websocketWaitGroup.Add(1)

codersdk/workspaceagents.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,3 +480,14 @@ func (c *Client) turnProxyDialer(ctx context.Context, httpClient *http.Client, p
480480
return websocket.NetConn(ctx, conn, websocket.MessageBinary), nil
481481
})
482482
}
483+
484+
// AgentStatsReportRequest is a WebSocket request by coderd
485+
// to the agent for stats.
486+
type AgentStatsReportRequest struct {
487+
}
488+
489+
// AgentStatsReportResponse is returned for each report
490+
// request by the agent.
491+
type AgentStatsReportResponse struct {
492+
Conns []agent.ConnStats `json:"conns,omitempty"`
493+
}

0 commit comments

Comments
 (0)