Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cdc95cd

Browse files
mafredrikylecarbs
authored andcommitted
feat: Add support for pprof in coder agent (#1985)
* feat: Allow USR1 signal to start pprof
1 parent 77ad755 commit cdc95cd

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

cli/agent.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cli
33
import (
44
"context"
55
"net/http"
6+
_ "net/http/pprof" //nolint: gosec
67
"net/url"
78
"os"
89
"path/filepath"
@@ -25,7 +26,9 @@ import (
2526

2627
func workspaceAgent() *cobra.Command {
2728
var (
28-
auth string
29+
auth string
30+
pprofEnabled bool
31+
pprofAddress string
2932
)
3033
cmd := &cobra.Command{
3134
Use: "agent",
@@ -49,6 +52,16 @@ func workspaceAgent() *cobra.Command {
4952
logger := slog.Make(sloghuman.Sink(cmd.ErrOrStderr()), sloghuman.Sink(logWriter)).Leveled(slog.LevelDebug)
5053
client := codersdk.New(coderURL)
5154

55+
if pprofEnabled {
56+
srvClose := serveHandler(cmd.Context(), logger, nil, pprofAddress, "pprof")
57+
defer srvClose()
58+
} else {
59+
// If pprof wasn't enabled at startup, allow a
60+
// `kill -USR1 $agent_pid` to start it (on Unix).
61+
srvClose := agentStartPPROFOnUSR1(cmd.Context(), logger, pprofAddress)
62+
defer srvClose()
63+
}
64+
5265
// exchangeToken returns a session token.
5366
// This is abstracted to allow for the same looping condition
5467
// regardless of instance identity auth type.
@@ -139,5 +152,7 @@ func workspaceAgent() *cobra.Command {
139152
}
140153

141154
cliflag.StringVarP(cmd.Flags(), &auth, "auth", "", "CODER_AGENT_AUTH", "token", "Specify the authentication type to use for the agent")
155+
cliflag.BoolVarP(cmd.Flags(), &pprofEnabled, "pprof-enable", "", "CODER_AGENT_PPROF_ENABLE", false, "Enable serving pprof metrics on the address defined by --pprof-address.")
156+
cliflag.StringVarP(cmd.Flags(), &pprofAddress, "pprof-address", "", "CODER_AGENT_PPROF_ADDRESS", "127.0.0.1:6060", "The address to serve pprof.")
142157
return cmd
143158
}

cli/agent_unix.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//go:build !windows
2+
3+
package cli
4+
5+
import (
6+
"context"
7+
"os"
8+
"os/signal"
9+
"syscall"
10+
11+
"cdr.dev/slog"
12+
)
13+
14+
func agentStartPPROFOnUSR1(ctx context.Context, logger slog.Logger, pprofAddress string) (srvClose func()) {
15+
ctx, cancel := context.WithCancel(ctx)
16+
17+
usr1 := make(chan os.Signal, 1)
18+
signal.Notify(usr1, syscall.SIGUSR1)
19+
go func() {
20+
defer close(usr1)
21+
defer signal.Stop(usr1)
22+
23+
select {
24+
case <-usr1:
25+
signal.Stop(usr1)
26+
srvClose := serveHandler(ctx, logger, nil, pprofAddress, "pprof")
27+
defer srvClose()
28+
case <-ctx.Done():
29+
return
30+
}
31+
<-ctx.Done() // Prevent defer close until done.
32+
}()
33+
34+
return func() {
35+
cancel()
36+
<-usr1 // Wait until usr1 is closed, ensures srvClose was run.
37+
}
38+
}

cli/agent_windows.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package cli
2+
3+
import (
4+
"context"
5+
6+
"cdr.dev/slog"
7+
)
8+
9+
// agentStartPPROFOnUSR1 is no-op on Windows (no SIGUSR1 signal).
10+
func agentStartPPROFOnUSR1(ctx context.Context, logger slog.Logger, pprofAddress string) (srvClose func()) {
11+
return func() {}
12+
}

0 commit comments

Comments
 (0)