@@ -16,6 +16,7 @@ import (
16
16
"time"
17
17
18
18
"cloud.google.com/go/compute/metadata"
19
+ "github.com/go-chi/chi/v5"
19
20
"golang.org/x/xerrors"
20
21
"gopkg.in/natefinch/lumberjack.v2"
21
22
"tailscale.com/util/clientmetric"
@@ -37,7 +38,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
37
38
noReap bool
38
39
sshMaxTimeout time.Duration
39
40
tailnetListenPort int64
40
- prometheusAddress string
41
+ metricsAddress string
41
42
)
42
43
cmd := & clibase.Cmd {
43
44
Use : "agent" ,
@@ -48,7 +49,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
48
49
ctx , cancel := context .WithCancel (inv .Context ())
49
50
defer cancel ()
50
51
51
- agentPorts := map [int ]string {}
52
+ ignorePorts := map [int ]string {}
52
53
53
54
isLinux := runtime .GOOS == "linux"
54
55
@@ -125,14 +126,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
125
126
defer pprofSrvClose ()
126
127
// Do a best effort here. If this fails, it's not a big deal.
127
128
if port , err := urlPort (pprofAddress ); err == nil {
128
- agentPorts [port ] = "pprof"
129
- }
130
-
131
- prometheusSrvClose := ServeHandler (ctx , logger , prometheusMetricsHandler (), prometheusAddress , "prometheus" )
132
- defer prometheusSrvClose ()
133
- // Do a best effort here. If this fails, it's not a big deal.
134
- if port , err := urlPort (prometheusAddress ); err == nil {
135
- agentPorts [port ] = "prometheus"
129
+ ignorePorts [port ] = "pprof"
136
130
}
137
131
138
132
// exchangeToken returns a session token.
@@ -196,7 +190,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
196
190
return xerrors .Errorf ("add executable to $PATH: %w" , err )
197
191
}
198
192
199
- closer := agent .New (agent.Options {
193
+ agnt := agent .New (agent.Options {
200
194
Client : client ,
201
195
Logger : logger ,
202
196
LogDir : logDir ,
@@ -215,11 +209,19 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
215
209
EnvironmentVariables : map [string ]string {
216
210
"GIT_ASKPASS" : executablePath ,
217
211
},
218
- AgentPorts : agentPorts ,
212
+ IgnorePorts : ignorePorts ,
219
213
SSHMaxTimeout : sshMaxTimeout ,
220
214
})
215
+
216
+ metricsSrvClose := ServeHandler (ctx , logger , metricsHandler (agnt ), metricsAddress , "metrics" )
217
+ defer metricsSrvClose ()
218
+ // Do a best effort here. If this fails, it's not a big deal.
219
+ if port , err := urlPort (metricsAddress ); err == nil {
220
+ ignorePorts [port ] = "metrics"
221
+ }
222
+
221
223
<- ctx .Done ()
222
- return closer .Close ()
224
+ return agnt .Close ()
223
225
},
224
226
}
225
227
@@ -270,7 +272,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
270
272
Flag : "prometheus-address" ,
271
273
Default : "127.0.0.1:2112" ,
272
274
Env : "CODER_AGENT_PROMETHEUS_ADDRESS" ,
273
- Value : clibase .StringOf (& prometheusAddress ),
275
+ Value : clibase .StringOf (& metricsAddress ),
274
276
Description : "The bind address to serve Prometheus metrics." ,
275
277
},
276
278
}
@@ -360,11 +362,17 @@ func urlPort(u string) (int, error) {
360
362
return - 1 , xerrors .Errorf ("invalid port: %s" , u )
361
363
}
362
364
363
- func prometheusMetricsHandler ( ) http.Handler {
364
- // We don't have any other internal metrics so far, so it's safe to expose metrics this way.
365
- // Based on: https://github.com/tailscale/tailscale/blob/280255acae604796a1113861f5a84e6fa2dc6121/ipn/localapi/localapi.go#L489
366
- return http . HandlerFunc ( func (w http.ResponseWriter , r * http.Request ) {
365
+ func metricsHandler ( a agent. Agent ) http.Handler {
366
+ r := chi . NewRouter ()
367
+
368
+ r . Get ( "/" , func (w http.ResponseWriter , r * http.Request ) {
367
369
w .Header ().Set ("Content-Type" , "text/plain" )
368
370
clientmetric .WritePrometheusExpositionFormat (w )
369
371
})
372
+
373
+ r .Route ("/debug" , func (r chi.Router ) {
374
+ r .Get ("/magicsock" , a .MagicsockServeHTTPDebug )
375
+ })
376
+
377
+ return r
370
378
}
0 commit comments