Skip to content

Commit 6c44de9

Browse files
authored
feat: add Prometheus collector for DERP server expvar metrics (coder#22583)
This PR does three things: - Exports derp expvars to the pprof endpoint - Exports the expvar metrics as prometheus metrics in both coderd and wsproxy - Updates our tailscale to a fix I also had to make to avoid a data race condition I generated this with mux but I also manually tested that the metrics were getting properly emitted
1 parent d034903 commit 6c44de9

11 files changed

Lines changed: 617 additions & 16 deletions

File tree

coderd/coderd.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ import (
9999
"github.com/coder/coder/v2/provisionersdk"
100100
"github.com/coder/coder/v2/site"
101101
"github.com/coder/coder/v2/tailnet"
102+
"github.com/coder/coder/v2/tailnet/derpmetrics"
102103
"github.com/coder/quartz"
103104
"github.com/coder/serpent"
104105
)
@@ -899,17 +900,18 @@ func New(options *Options) *API {
899900
apiRateLimiter := httpmw.RateLimit(options.APIRateLimit, time.Minute)
900901

901902
// Register DERP on expvar HTTP handler, which we serve below in the router, c.f. expvar.Handler()
902-
// These are the metrics the DERP server exposes.
903-
// TODO: export via prometheus
904903
expDERPOnce.Do(func() {
905904
// We need to do this via a global Once because expvar registry is global and panics if we
906905
// register multiple times. In production there is only one Coderd and one DERP server per
907906
// process, but in testing, we create multiple of both, so the Once protects us from
908907
// panicking.
909-
if options.DERPServer != nil {
908+
if options.DERPServer != nil && expvar.Get("derp") == nil {
910909
expvar.Publish("derp", api.DERPServer.ExpVar())
911910
}
912911
})
912+
if options.PrometheusRegistry != nil && options.DERPServer != nil {
913+
options.PrometheusRegistry.MustRegister(derpmetrics.NewDERPExpvarCollector(options.DERPServer))
914+
}
913915
cors := httpmw.Cors(options.DeploymentValues.Dangerous.AllowAllCors.Value())
914916
prometheusMW := httpmw.Prometheus(options.PrometheusRegistry)
915917

coderd/coderd_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,3 +390,29 @@ func TestCSRFExempt(t *testing.T) {
390390
require.NotContains(t, string(data), "CSRF")
391391
})
392392
}
393+
394+
func TestDERPMetrics(t *testing.T) {
395+
t.Parallel()
396+
397+
_, _, api := coderdtest.NewWithAPI(t, nil)
398+
399+
require.NotNil(t, api.Options.DERPServer, "DERP server should be configured")
400+
require.NotNil(t, api.Options.PrometheusRegistry, "Prometheus registry should be configured")
401+
402+
// The registry is created internally by coderd. Gather from it
403+
// to verify DERP metrics were registered during startup.
404+
metrics, err := api.Options.PrometheusRegistry.Gather()
405+
require.NoError(t, err)
406+
407+
names := make(map[string]struct{})
408+
for _, m := range metrics {
409+
names[m.GetName()] = struct{}{}
410+
}
411+
412+
assert.Contains(t, names, "coder_derp_server_connections",
413+
"expected coder_derp_server_connections to be registered")
414+
assert.Contains(t, names, "coder_derp_server_bytes_received_total",
415+
"expected coder_derp_server_bytes_received_total to be registered")
416+
assert.Contains(t, names, "coder_derp_server_packets_dropped_reason_total",
417+
"expected coder_derp_server_packets_dropped_reason_total to be registered")
418+
}

docs/admin/integrations/prometheus.md

Lines changed: 25 additions & 0 deletions
Large diffs are not rendered by default.

enterprise/wsproxy/wsproxy.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"crypto/tls"
66
"errors"
7+
"expvar"
78
"fmt"
89
"net/http"
910
"net/url"
@@ -42,8 +43,14 @@ import (
4243
sharedhttpmw "github.com/coder/coder/v2/httpmw"
4344
"github.com/coder/coder/v2/site"
4445
"github.com/coder/coder/v2/tailnet"
46+
"github.com/coder/coder/v2/tailnet/derpmetrics"
4547
)
4648

49+
// expDERPOnce guards the global expvar.Publish call for the DERP server.
50+
// expvar panics on duplicate registration, and tests may create multiple
51+
// servers in the same process.
52+
var expDERPOnce sync.Once
53+
4754
type Options struct {
4855
Logger slog.Logger
4956
Experiments codersdk.Experiments
@@ -196,6 +203,17 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
196203
return nil, xerrors.Errorf("create DERP mesh tls config: %w", err)
197204
}
198205
derpServer := derp.NewServer(key.NewNode(), tailnet.Logger(opts.Logger.Named("net.derp")))
206+
// Publish DERP stats to expvar, available via the pprof
207+
// debug server (--pprof-enable) at /debug/vars. This avoids
208+
// exposing expvar on the public HTTP router.
209+
expDERPOnce.Do(func() {
210+
if expvar.Get("derp") == nil {
211+
expvar.Publish("derp", derpServer.ExpVar())
212+
}
213+
})
214+
if opts.PrometheusRegistry != nil {
215+
opts.PrometheusRegistry.MustRegister(derpmetrics.NewDERPExpvarCollector(derpServer))
216+
}
199217

200218
ctx, cancel := context.WithCancel(context.Background())
201219

enterprise/wsproxy/wsproxy_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,3 +1223,55 @@ func createProxyReplicas(ctx context.Context, t *testing.T, opts *createProxyRep
12231223

12241224
return proxies
12251225
}
1226+
1227+
func TestWorkspaceProxyDERPMetrics(t *testing.T) {
1228+
t.Parallel()
1229+
1230+
deploymentValues := coderdtest.DeploymentValues(t)
1231+
deploymentValues.Experiments = []string{"*"}
1232+
1233+
client, closer, api, _ := coderdenttest.NewWithAPI(t, &coderdenttest.Options{
1234+
Options: &coderdtest.Options{
1235+
DeploymentValues: deploymentValues,
1236+
AppHostname: "*.primary.test.coder.com",
1237+
IncludeProvisionerDaemon: true,
1238+
RealIPConfig: &httpmw.RealIPConfig{
1239+
TrustedOrigins: []*net.IPNet{{
1240+
IP: net.ParseIP("127.0.0.1"),
1241+
Mask: net.CIDRMask(8, 32),
1242+
}},
1243+
TrustedHeaders: []string{
1244+
"CF-Connecting-IP",
1245+
},
1246+
},
1247+
},
1248+
LicenseOptions: &coderdenttest.LicenseOptions{
1249+
Features: license.Features{
1250+
codersdk.FeatureWorkspaceProxy: 1,
1251+
},
1252+
},
1253+
})
1254+
t.Cleanup(func() {
1255+
_ = closer.Close()
1256+
})
1257+
1258+
proxy := coderdenttest.NewWorkspaceProxyReplica(t, api, client, &coderdenttest.ProxyOptions{
1259+
Name: "metrics-test-proxy",
1260+
})
1261+
1262+
// Gather metrics from the wsproxy's Prometheus registry.
1263+
metrics, err := proxy.PrometheusRegistry.Gather()
1264+
require.NoError(t, err)
1265+
1266+
names := make(map[string]struct{})
1267+
for _, m := range metrics {
1268+
names[m.GetName()] = struct{}{}
1269+
}
1270+
1271+
assert.Contains(t, names, "coder_derp_server_connections",
1272+
"expected coder_derp_server_connections to be registered")
1273+
assert.Contains(t, names, "coder_derp_server_bytes_received_total",
1274+
"expected coder_derp_server_bytes_received_total to be registered")
1275+
assert.Contains(t, names, "coder_derp_server_packets_dropped_reason_total",
1276+
"expected coder_derp_server_packets_dropped_reason_total to be registered")
1277+
}

go.mod

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ replace github.com/tcnksm/go-httpstat => github.com/coder/go-httpstat v0.0.0-202
3636

3737
// There are a few minor changes we make to Tailscale that we're slowly upstreaming. Compare here:
3838
// https://github.com/tailscale/tailscale/compare/main...coder:tailscale:main
39-
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20250829055706-6eafe0f9199e
39+
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20260306035934-af5c6fc52433
4040

4141
// This is replaced to include
4242
// 1. a fix for a data race: c.f. https://github.com/tailscale/wireguard-go/pull/25
@@ -115,7 +115,7 @@ require (
115115
github.com/coder/wgtunnel v0.2.0
116116
github.com/coreos/go-oidc/v3 v3.17.0
117117
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
118-
github.com/creack/pty v1.1.21
118+
github.com/creack/pty v1.1.24
119119
github.com/dave/dst v0.27.2
120120
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
121121
github.com/dblohm7/wingoes v0.0.0-20240820181039-f2b84150679e
@@ -289,9 +289,8 @@ require (
289289
github.com/containerd/continuity v0.4.5 // indirect
290290
github.com/coreos/go-iptables v0.6.0 // indirect
291291
github.com/dlclark/regexp2 v1.11.5 // indirect
292-
github.com/docker/cli v28.3.2+incompatible // indirect
293-
github.com/docker/docker v28.3.3+incompatible // indirect
294-
github.com/docker/go-connections v0.5.0 // indirect
292+
github.com/docker/cli v29.2.0+incompatible // indirect
293+
github.com/docker/go-connections v0.6.0 // indirect
295294
github.com/docker/go-units v0.5.0 // indirect
296295
github.com/dop251/goja v0.0.0-20241024094426-79f3a7efcdbd // indirect
297296
github.com/dustin/go-humanize v1.0.1
@@ -537,8 +536,11 @@ require (
537536
github.com/clipperhouse/uax29/v2 v2.5.0 // indirect
538537
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect
539538
github.com/coder/paralleltestctx v0.0.1 // indirect
539+
github.com/containerd/errdefs v1.0.0 // indirect
540+
github.com/containerd/errdefs/pkg v0.3.0 // indirect
540541
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
541542
github.com/daixiang0/gci v0.13.7 // indirect
543+
github.com/distribution/reference v0.6.0 // indirect
542544
github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect
543545
github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect
544546
github.com/esiqveland/notify v0.13.3 // indirect
@@ -562,6 +564,8 @@ require (
562564
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
563565
github.com/landlock-lsm/go-landlock v0.0.0-20251103212306-430f8e5cd97c // indirect
564566
github.com/mattn/go-shellwords v1.0.12 // indirect
567+
github.com/moby/moby/api v1.54.0 // indirect
568+
github.com/moby/moby/client v0.3.0 // indirect
565569
github.com/moby/sys/user v0.4.0 // indirect
566570
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
567571
github.com/openai/openai-go v1.12.0 // indirect
@@ -592,6 +596,7 @@ require (
592596
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 // indirect
593597
go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect
594598
go.yaml.in/yaml/v2 v2.4.3 // indirect
599+
go.yaml.in/yaml/v3 v3.0.4 // indirect
595600
go.yaml.in/yaml/v4 v4.0.0-rc.3 // indirect
596601
golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 // indirect
597602
google.golang.org/genai v1.47.0 // indirect

go.sum

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ github.com/coder/serpent v0.14.0 h1:g7vt2zBMp3nWyAvyhvQduaI53Ku65U3wITMi01+/8pU=
347347
github.com/coder/serpent v0.14.0/go.mod h1:7OIvFBYMd+OqarMy5einBl8AtRr8LliopVU7pyrwucY=
348348
github.com/coder/ssh v0.0.0-20231128192721-70855dedb788 h1:YoUSJ19E8AtuUFVYBpXuOD6a/zVP3rcxezNsoDseTUw=
349349
github.com/coder/ssh v0.0.0-20231128192721-70855dedb788/go.mod h1:aGQbuCLyhRLMzZF067xc84Lh7JDs1FKwCmF1Crl9dxQ=
350-
github.com/coder/tailscale v1.1.1-0.20250829055706-6eafe0f9199e h1:9RKGKzGLHtTvVBQublzDGtCtal3cXP13diCHoAIGPeI=
351-
github.com/coder/tailscale v1.1.1-0.20250829055706-6eafe0f9199e/go.mod h1:jU9T1vEs+DOs8NtGp1F2PT0/TOGVwtg/JCCKYRgvMOs=
350+
github.com/coder/tailscale v1.1.1-0.20260306035934-af5c6fc52433 h1:NxqWSEZFuCeIR/N7lZ9cx+434urbNvrrA7ZyNPTwnmc=
351+
github.com/coder/tailscale v1.1.1-0.20260306035934-af5c6fc52433/go.mod h1:q+R4UL4pPb0CpaSNVUTDsg0kZeL/OlqjRNO9XbJxU5g=
352352
github.com/coder/terraform-config-inspect v0.0.0-20250107175719-6d06d90c630e h1:JNLPDi2P73laR1oAclY6jWzAbucf70ASAvf5mh2cME0=
353353
github.com/coder/terraform-config-inspect v0.0.0-20250107175719-6d06d90c630e/go.mod h1:Gz/z9Hbn+4KSp8A2FBtNszfLSdT2Tn/uAKGuVqqWmDI=
354354
github.com/coder/terraform-provider-coder/v2 v2.13.1 h1:dtPaJUvueFm+XwBPUMWQCc5Z1QUQBW4B4RNyzX4h4y8=
@@ -382,8 +382,8 @@ github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHf
382382
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
383383
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
384384
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
385-
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
386-
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
385+
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
386+
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
387387
github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
388388
github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
389389
github.com/daixiang0/gci v0.13.7 h1:+0bG5eK9vlI08J+J/NWGbWPTNiXPG4WhNLJOkSxWITQ=
@@ -420,12 +420,12 @@ github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZ
420420
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
421421
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
422422
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
423-
github.com/docker/cli v28.3.2+incompatible h1:mOt9fcLE7zaACbxW1GeS65RI67wIJrTnqS3hP2huFsY=
424-
github.com/docker/cli v28.3.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
423+
github.com/docker/cli v29.2.0+incompatible h1:9oBd9+YM7rxjZLfyMGxjraKBKE4/nVyvVfN4qNl9XRM=
424+
github.com/docker/cli v29.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
425425
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
426426
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
427-
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
428-
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
427+
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
428+
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
429429
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
430430
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
431431
github.com/dop251/goja v0.0.0-20241024094426-79f3a7efcdbd h1:QMSNEh9uQkDjyPwu/J541GgSH+4hw+0skJDIj9HJ3mE=
@@ -872,6 +872,10 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N
872872
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
873873
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
874874
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
875+
github.com/moby/moby/api v1.54.0 h1:7kbUgyiKcoBhm0UrWbdrMs7RX8dnwzURKVbZGy2GnL0=
876+
github.com/moby/moby/api v1.54.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
877+
github.com/moby/moby/client v0.3.0 h1:UUGL5okry+Aomj3WhGt9Aigl3ZOxZGqR7XPo+RLPlKs=
878+
github.com/moby/moby/client v0.3.0/go.mod h1:HJgFbJRvogDQjbM8fqc1MCEm4mIAGMLjXbgwoZp6jCQ=
875879
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
876880
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
877881
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
@@ -1525,6 +1529,8 @@ kernel.org/pub/linux/libs/security/libcap/psx v1.2.77 h1:Z06sMOzc0GNCwp6efaVrIrz
15251529
kernel.org/pub/linux/libs/security/libcap/psx v1.2.77/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
15261530
mvdan.cc/gofumpt v0.8.0 h1:nZUCeC2ViFaerTcYKstMmfysj6uhQrA2vJe+2vwGU6k=
15271531
mvdan.cc/gofumpt v0.8.0/go.mod h1:vEYnSzyGPmjvFkqJWtXkh79UwPWP9/HMxQdGEXZHjpg=
1532+
pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=
1533+
pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
15281534
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
15291535
rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs=
15301536
sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=

scripts/metricsdocgen/generated_metrics

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,81 @@ agent_boundary_log_proxy_batches_forwarded_total 0
77
# HELP agent_boundary_log_proxy_logs_dropped_total Total number of individual boundary log entries dropped before reaching coderd. Reason: buffer_full = the agent's internal buffer is full; forward_failed = the agent failed to send the batch to coderd; boundary_channel_full = boundary's internal send channel overflowed, meaning boundary is generating logs faster than it can batch and send them; boundary_batch_full = boundary's outgoing batch buffer overflowed after a failed flush, meaning boundary could not write to the agent's socket.
88
# TYPE agent_boundary_log_proxy_logs_dropped_total counter
99
agent_boundary_log_proxy_logs_dropped_total{reason=""} 0
10+
# HELP coder_derp_server_accepts_total Total DERP connections accepted.
11+
# TYPE coder_derp_server_accepts_total counter
12+
coder_derp_server_accepts_total 0
13+
# HELP coder_derp_server_average_queue_duration_ms Average queue duration in milliseconds.
14+
# TYPE coder_derp_server_average_queue_duration_ms gauge
15+
coder_derp_server_average_queue_duration_ms 0
16+
# HELP coder_derp_server_bytes_received_total Total bytes received.
17+
# TYPE coder_derp_server_bytes_received_total counter
18+
coder_derp_server_bytes_received_total 0
19+
# HELP coder_derp_server_bytes_sent_total Total bytes sent.
20+
# TYPE coder_derp_server_bytes_sent_total counter
21+
coder_derp_server_bytes_sent_total 0
22+
# HELP coder_derp_server_clients Total clients (local + remote).
23+
# TYPE coder_derp_server_clients gauge
24+
coder_derp_server_clients 0
25+
# HELP coder_derp_server_clients_local Local clients.
26+
# TYPE coder_derp_server_clients_local gauge
27+
coder_derp_server_clients_local 0
28+
# HELP coder_derp_server_clients_remote Remote (mesh) clients.
29+
# TYPE coder_derp_server_clients_remote gauge
30+
coder_derp_server_clients_remote 0
31+
# HELP coder_derp_server_connections Current DERP connections.
32+
# TYPE coder_derp_server_connections gauge
33+
coder_derp_server_connections 0
34+
# HELP coder_derp_server_got_ping_total Total pings received.
35+
# TYPE coder_derp_server_got_ping_total counter
36+
coder_derp_server_got_ping_total 0
37+
# HELP coder_derp_server_home_connections Current home DERP connections.
38+
# TYPE coder_derp_server_home_connections gauge
39+
coder_derp_server_home_connections 0
40+
# HELP coder_derp_server_home_moves_in_total Total home moves in.
41+
# TYPE coder_derp_server_home_moves_in_total counter
42+
coder_derp_server_home_moves_in_total 0
43+
# HELP coder_derp_server_home_moves_out_total Total home moves out.
44+
# TYPE coder_derp_server_home_moves_out_total counter
45+
coder_derp_server_home_moves_out_total 0
46+
# HELP coder_derp_server_packets_dropped_reason_total Packets dropped by reason.
47+
# TYPE coder_derp_server_packets_dropped_reason_total counter
48+
coder_derp_server_packets_dropped_reason_total{reason=""} 0
49+
# HELP coder_derp_server_packets_dropped_total Total packets dropped.
50+
# TYPE coder_derp_server_packets_dropped_total counter
51+
coder_derp_server_packets_dropped_total 0
52+
# HELP coder_derp_server_packets_dropped_type_total Packets dropped by type.
53+
# TYPE coder_derp_server_packets_dropped_type_total counter
54+
coder_derp_server_packets_dropped_type_total{type=""} 0
55+
# HELP coder_derp_server_packets_forwarded_in_total Total packets forwarded in from mesh peers.
56+
# TYPE coder_derp_server_packets_forwarded_in_total counter
57+
coder_derp_server_packets_forwarded_in_total 0
58+
# HELP coder_derp_server_packets_forwarded_out_total Total packets forwarded out to mesh peers.
59+
# TYPE coder_derp_server_packets_forwarded_out_total counter
60+
coder_derp_server_packets_forwarded_out_total 0
61+
# HELP coder_derp_server_packets_received_kind_total Packets received by kind.
62+
# TYPE coder_derp_server_packets_received_kind_total counter
63+
coder_derp_server_packets_received_kind_total{kind=""} 0
64+
# HELP coder_derp_server_packets_received_total Total packets received.
65+
# TYPE coder_derp_server_packets_received_total counter
66+
coder_derp_server_packets_received_total 0
67+
# HELP coder_derp_server_packets_sent_total Total packets sent.
68+
# TYPE coder_derp_server_packets_sent_total counter
69+
coder_derp_server_packets_sent_total 0
70+
# HELP coder_derp_server_peer_gone_disconnected_total Total peer gone (disconnected) frames sent.
71+
# TYPE coder_derp_server_peer_gone_disconnected_total counter
72+
coder_derp_server_peer_gone_disconnected_total 0
73+
# HELP coder_derp_server_peer_gone_not_here_total Total peer gone (not here) frames sent.
74+
# TYPE coder_derp_server_peer_gone_not_here_total counter
75+
coder_derp_server_peer_gone_not_here_total 0
76+
# HELP coder_derp_server_sent_pong_total Total pongs sent.
77+
# TYPE coder_derp_server_sent_pong_total counter
78+
coder_derp_server_sent_pong_total 0
79+
# HELP coder_derp_server_unknown_frames_total Total unknown frames received.
80+
# TYPE coder_derp_server_unknown_frames_total counter
81+
coder_derp_server_unknown_frames_total 0
82+
# HELP coder_derp_server_watchers Current watchers.
83+
# TYPE coder_derp_server_watchers gauge
84+
coder_derp_server_watchers 0
1085
# HELP coder_pubsub_connected Whether we are connected (1) or not connected (0) to postgres
1186
# TYPE coder_pubsub_connected gauge
1287
coder_pubsub_connected 0

scripts/metricsdocgen/scanner/scanner.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ var scanDirs = []string{
3030
"coderd",
3131
"enterprise",
3232
"provisionerd",
33+
"tailnet",
3334
}
3435

3536
// skipPaths lists files that should be excluded from scanning. Their metrics

0 commit comments

Comments
 (0)