Skip to content

Commit 74cf7ae

Browse files
committed
chore: add profiling labels for pprof analysis
PProf labels segment the code into groups for determing the source of cpu/memory profiles. Since the web server and background jobs share a lot of the same code (eg wsbuilder), it helps to know if the load is user induced, or background job based.
1 parent ffbd583 commit 74cf7ae

File tree

7 files changed

+57
-8
lines changed

7 files changed

+57
-8
lines changed

cli/server.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import (
5555

5656
"cdr.dev/slog"
5757
"cdr.dev/slog/sloggers/sloghuman"
58+
"github.com/coder/coder/v2/coderd/pproflabel"
5859
"github.com/coder/pretty"
5960
"github.com/coder/quartz"
6061
"github.com/coder/retry"
@@ -1459,14 +1460,14 @@ func newProvisionerDaemon(
14591460
tracer := coderAPI.TracerProvider.Tracer(tracing.TracerName)
14601461
terraformClient, terraformServer := drpcsdk.MemTransportPipe()
14611462
wg.Add(1)
1462-
go func() {
1463+
pproflabel.Go(ctx, pproflabel.Service(pproflabel.ServiceTerraformProvisioner), func(ctx context.Context) {
14631464
defer wg.Done()
14641465
<-ctx.Done()
14651466
_ = terraformClient.Close()
14661467
_ = terraformServer.Close()
1467-
}()
1468+
})
14681469
wg.Add(1)
1469-
go func() {
1470+
pproflabel.Go(ctx, pproflabel.Service(pproflabel.ServiceTerraformProvisioner), func(ctx context.Context) {
14701471
defer wg.Done()
14711472
defer cancel()
14721473

@@ -1485,7 +1486,7 @@ func newProvisionerDaemon(
14851486
default:
14861487
}
14871488
}
1488-
}()
1489+
})
14891490

14901491
connector[string(database.ProvisionerTypeTerraform)] = sdkproto.NewDRPCProvisionerClient(terraformClient)
14911492
default:

coderd/autobuild/lifecycle_executor.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"cdr.dev/slog"
2222
"github.com/coder/coder/v2/coderd/files"
23+
"github.com/coder/coder/v2/coderd/pproflabel"
2324

2425
"github.com/coder/coder/v2/coderd/audit"
2526
"github.com/coder/coder/v2/coderd/database"
@@ -107,7 +108,7 @@ func (e *Executor) WithStatsChannel(ch chan<- Stats) *Executor {
107108
// tick from its channel. It will stop when its context is Done, or when
108109
// its channel is closed.
109110
func (e *Executor) Run() {
110-
go func() {
111+
pproflabel.Go(e.ctx, pproflabel.Service(pproflabel.ServiceLifecycles), func(ctx context.Context) {
111112
for {
112113
select {
113114
case <-e.ctx.Done():
@@ -128,7 +129,7 @@ func (e *Executor) Run() {
128129
e.log.Debug(e.ctx, "run stats", slog.F("elapsed", stats.Elapsed), slog.F("transitions", stats.Transitions))
129130
}
130131
}
131-
}()
132+
})
132133
}
133134

134135
func (e *Executor) runOnce(t time.Time) Stats {

coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,7 @@ func New(options *Options) *API {
852852

853853
r.Use(
854854
httpmw.Recover(api.Logger),
855+
httpmw.WithProfilingLabels,
855856
tracing.StatusWriterMiddleware,
856857
tracing.Middleware(api.TracerProvider),
857858
httpmw.AttachRequestID,

coderd/httpmw/pprof.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package httpmw
2+
3+
import (
4+
"context"
5+
"net/http"
6+
"runtime/pprof"
7+
8+
"github.com/coder/coder/v2/coderd/pproflabel"
9+
)
10+
11+
// WithProfilingLabels adds a pprof label to all http request handlers. This is
12+
// primarily used to determine if load is coming from background jobs, or from
13+
// http traffic.
14+
func WithProfilingLabels(next http.Handler) http.Handler {
15+
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
16+
ctx := r.Context()
17+
pprof.Do(ctx, pproflabel.Service(pproflabel.ServiceHTTPServer), func(ctx context.Context) {
18+
r = r.WithContext(ctx)
19+
next.ServeHTTP(rw, r)
20+
})
21+
})
22+
}

coderd/pproflabel/pproflabel.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package pproflabel
2+
3+
import (
4+
"context"
5+
"runtime/pprof"
6+
)
7+
8+
// Go is just a convince wrapper to set off a labeled goroutine.
9+
func Go(ctx context.Context, labels pprof.LabelSet, f func(context.Context)) {
10+
go pprof.Do(ctx, labels, f)
11+
}
12+
13+
const (
14+
ServiceTerraformProvisioner = "terraform-provisioner"
15+
ServiceMetricCollector = "metric-collector"
16+
ServiceLifecycles = "lifecycles"
17+
ServiceHTTPServer = "http-server"
18+
)
19+
20+
func Service(name string) pprof.LabelSet {
21+
return pprof.Labels("service", name)
22+
}

coderd/prometheusmetrics/insights/metricscollector.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"cdr.dev/slog"
1515

1616
"github.com/coder/coder/v2/coderd/database"
17+
"github.com/coder/coder/v2/coderd/pproflabel"
1718
"github.com/coder/coder/v2/coderd/util/slice"
1819
"github.com/coder/coder/v2/codersdk"
1920
)
@@ -158,7 +159,7 @@ func (mc *MetricsCollector) Run(ctx context.Context) (func(), error) {
158159
})
159160
}
160161

161-
go func() {
162+
pproflabel.Go(ctx, pproflabel.Service(pproflabel.ServiceMetricCollector), func(ctx context.Context) {
162163
defer close(done)
163164
defer ticker.Stop()
164165
for {
@@ -170,7 +171,7 @@ func (mc *MetricsCollector) Run(ctx context.Context) (func(), error) {
170171
doTick()
171172
}
172173
}
173-
}()
174+
})
174175
return func() {
175176
closeFunc()
176177
<-done

enterprise/wsproxy/wsproxy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
333333
r.Use(
334334
// TODO: @emyrk Should we standardize these in some other package?
335335
httpmw.Recover(s.Logger),
336+
httpmw.WithProfilingLabels,
336337
tracing.StatusWriterMiddleware,
337338
tracing.Middleware(s.TracerProvider),
338339
httpmw.AttachRequestID,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy