MCPcopy Index your code
hub / github.com/docker/docker-agent / StartPprofServer

Function StartPprofServer

pkg/profiling/pprof_server.go:22–69  ·  view source on GitHub ↗

StartPprofServer starts an HTTP server exposing Go runtime profiling endpoints at /debug/pprof/ on the given addr. It binds the listener synchronously and returns an error if the address is unavailable. The server runs in a background goroutine and shuts down when ctx is cancelled. addr must be a TC

(ctx context.Context, addr string)

Source from the content-addressed store, hash-verified

20// (":6060") — the latter binds all interfaces, exposing process memory and arguments
21// to the network.
22func StartPprofServer(ctx context.Context, addr string) error {
23 mux := http.NewServeMux()
24 mux.HandleFunc("/debug/pprof/", pprof.Index)
25 mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
26 mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
27 mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
28 mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
29
30 ln, err := (&net.ListenConfig{}).Listen(ctx, "tcp", addr)
31 if err != nil {
32 return fmt.Errorf("pprof: listen on %s: %w", addr, err)
33 }
34
35 // ReadHeaderTimeout guards against slow-loris connections on the debug port.
36 // WriteTimeout is intentionally omitted: profile/trace captures legitimately
37 // run for tens of seconds and would be truncated by a short write deadline.
38 srv := &http.Server{Handler: mux, ReadHeaderTimeout: 10 * time.Second}
39
40 slog.InfoContext(ctx, "pprof server listening", "addr", ln.Addr().String())
41 if tcpAddr, ok := ln.Addr().(*net.TCPAddr); ok && !tcpAddr.IP.IsLoopback() {
42 slog.WarnContext(ctx, "pprof server is listening on a non-loopback address — "+
43 "/debug/pprof/cmdline and heap profiles are network-reachable without authentication",
44 "addr", tcpAddr.String())
45 }
46
47 go func() {
48 if err := srv.Serve(ln); err != nil && !errors.Is(err, http.ErrServerClosed) {
49 slog.WarnContext(ctx, "pprof server error", "error", err)
50 }
51 }()
52
53 go func() {
54 <-ctx.Done()
55 // 5s grace: favors prompt process exit over draining in-flight profile
56 // captures. CPU/trace profiles run up to 30s by default; callers should
57 // cancel their requests before the process exits rather than relying on
58 // this timeout to drain them.
59 // context.WithoutCancel preserves ctx values (e.g. trace IDs) without
60 // inheriting the cancellation, so the shutdown timeout is not pre-expired.
61 shutdownCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 5*time.Second)
62 defer cancel()
63 if err := srv.Shutdown(shutdownCtx); err != nil {
64 slog.WarnContext(shutdownCtx, "pprof server shutdown error", "error", err)
65 }
66 }()
67
68 return nil
69}

Callers 1

runAPICommandMethod · 0.92

Calls 4

ServeMethod · 0.95
ListenMethod · 0.80
StringMethod · 0.45
ShutdownMethod · 0.45

Tested by

no test coverage detected