Skip to content

Commit a146d2a

Browse files
authored
Merge pull request moby#5337 from fiam/alberto/debug-flight-record
debug: add trace flight recorder
2 parents ad0c36c + 892e756 commit a146d2a

30 files changed

+7615
-19
lines changed

cmd/buildkitd/debug.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ func setupDebugHandlers(addr string) error {
3131

3232
m.Handle("/metrics", promhttp.Handler())
3333

34+
setupDebugFlight(m)
35+
3436
// setting debugaddr is opt-in. permission is defined by listener address
3537
trace.AuthRequest = func(_ *http.Request) (bool, bool) {
3638
return true, true

cmd/buildkitd/debug_flight.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"sync"
7+
"time"
8+
9+
"golang.org/x/exp/trace"
10+
)
11+
12+
type flightRecorder struct {
13+
mu sync.Mutex
14+
recorder *trace.FlightRecorder
15+
}
16+
17+
func newFlightRecorder() *flightRecorder {
18+
dbg := &flightRecorder{
19+
recorder: trace.NewFlightRecorder(),
20+
}
21+
return dbg
22+
}
23+
24+
func (r *flightRecorder) StartTrace(w http.ResponseWriter, req *http.Request) {
25+
r.mu.Lock()
26+
defer r.mu.Unlock()
27+
if r.recorder.Enabled() {
28+
http.Error(w, "flight recorder is already running", http.StatusConflict)
29+
return
30+
}
31+
if err := r.recorder.Start(); err != nil {
32+
http.Error(w, fmt.Sprintf("could not start flight recorder: %s", err), http.StatusInternalServerError)
33+
return
34+
}
35+
}
36+
37+
func (r *flightRecorder) StopTrace(w http.ResponseWriter, req *http.Request) {
38+
r.mu.Lock()
39+
defer r.mu.Unlock()
40+
if !r.recorder.Enabled() {
41+
http.Error(w, "flight recorder is not running", http.StatusConflict)
42+
return
43+
}
44+
if err := r.recorder.Stop(); err != nil {
45+
http.Error(w, err.Error(), http.StatusInternalServerError)
46+
return
47+
}
48+
}
49+
50+
func (r *flightRecorder) SetTracePeriod(w http.ResponseWriter, req *http.Request) {
51+
r.mu.Lock()
52+
defer r.mu.Unlock()
53+
if r.recorder.Enabled() {
54+
http.Error(w, "flight recorder is running, stop it to change its period", http.StatusPreconditionFailed)
55+
return
56+
}
57+
periodValue := req.FormValue("period")
58+
period, err := time.ParseDuration(periodValue)
59+
if err != nil {
60+
http.Error(w, fmt.Sprintf("invalid flight recorder period: %s", err), http.StatusBadRequest)
61+
}
62+
r.recorder.SetPeriod(period)
63+
}
64+
65+
func (r *flightRecorder) Trace(w http.ResponseWriter, req *http.Request) {
66+
r.mu.Lock()
67+
defer r.mu.Unlock()
68+
w.Header().Set("Content-Type", "application/octet-stream")
69+
w.Header().Set("Content-Disposition", `attachment; filename="trace"`)
70+
if _, err := r.recorder.WriteTo(w); err != nil {
71+
http.Error(w, fmt.Sprintf("could not write in-flight trace: %s", err), http.StatusInternalServerError)
72+
}
73+
}
74+
75+
func setupDebugFlight(m *http.ServeMux) {
76+
r := newFlightRecorder()
77+
78+
const (
79+
flightPattern = "/debug/flight"
80+
flightTracePattern = flightPattern + "/trace"
81+
)
82+
83+
m.HandleFunc("POST "+flightTracePattern+"/start", r.StartTrace)
84+
m.HandleFunc("POST "+flightTracePattern+"/stop", r.StopTrace)
85+
m.HandleFunc("POST "+flightTracePattern+"/set_period", r.SetTracePeriod)
86+
m.HandleFunc("GET "+flightTracePattern, r.Trace)
87+
}

control/control.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package control
33
import (
44
"context"
55
"fmt"
6+
"runtime/trace"
67
"strconv"
78
"sync"
89
"sync/atomic"
@@ -343,6 +344,8 @@ func translateLegacySolveRequest(req *controlapi.SolveRequest) {
343344
}
344345

345346
func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (*controlapi.SolveResponse, error) {
347+
defer trace.StartRegion(ctx, "Solve").End()
348+
trace.Logf(ctx, "Request", "solve request: %v", req.Ref)
346349
atomic.AddInt64(&c.buildCount, 1)
347350
defer atomic.AddInt64(&c.buildCount, -1)
348351

go.mod

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/moby/buildkit
22

3-
go 1.21.0
3+
go 1.22.0
44

55
require (
66
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0
@@ -95,9 +95,10 @@ require (
9595
go.opentelemetry.io/otel/trace v1.21.0
9696
go.opentelemetry.io/proto/otlp v1.0.0
9797
golang.org/x/crypto v0.23.0
98-
golang.org/x/mod v0.17.0
98+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
99+
golang.org/x/mod v0.21.0
99100
golang.org/x/net v0.25.0
100-
golang.org/x/sync v0.7.0
101+
golang.org/x/sync v0.8.0
101102
golang.org/x/sys v0.22.0
102103
golang.org/x/time v0.3.0
103104
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80

go.sum

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -450,15 +450,15 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
450450
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
451451
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
452452
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
453-
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
454-
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
453+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
454+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
455455
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
456456
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
457457
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
458458
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
459459
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
460-
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
461-
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
460+
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
461+
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
462462
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
463463
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
464464
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -482,8 +482,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
482482
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
483483
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
484484
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
485-
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
486-
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
485+
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
486+
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
487487
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
488488
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
489489
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -515,8 +515,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
515515
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
516516
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
517517
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
518-
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
519-
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
518+
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
519+
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
520520
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
521521
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
522522
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

hack/dockerfiles/docs-dockerfile.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# syntax=docker/dockerfile:1
22

3-
ARG GO_VERSION=1.21
3+
ARG GO_VERSION=1.22
44
ARG ALPINE_VERSION=3.20
55

66
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS golatest

vendor/golang.org/x/exp/LICENSE

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/golang.org/x/exp/PATENTS

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)