Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit55ad97b

Browse files
authored
feat: add pprof and prometheus metrics tocoder server (#1266)
1 parent5dcaf94 commit55ad97b

File tree

5 files changed

+168
-6
lines changed

5 files changed

+168
-6
lines changed

‎cli/server.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"log"
1313
"net"
1414
"net/http"
15+
"net/http/pprof"
1516
"net/url"
1617
"os"
1718
"os/signal"
@@ -23,6 +24,7 @@ import (
2324
"github.com/google/go-github/v43/github"
2425
"github.com/pion/turn/v2"
2526
"github.com/pion/webrtc/v3"
27+
"github.com/prometheus/client_golang/prometheus/promhttp"
2628
"github.com/spf13/cobra"
2729
"golang.org/x/oauth2"
2830
xgithub"golang.org/x/oauth2/github"
@@ -55,6 +57,10 @@ func server() *cobra.Command {
5557
var (
5658
accessURLstring
5759
addressstring
60+
promEnabledbool
61+
promAddressstring
62+
pprofEnabledbool
63+
pprofAddressstring
5864
cacheDirstring
5965
devbool
6066
devUserEmailstring
@@ -245,6 +251,17 @@ func server() *cobra.Command {
245251
}
246252
}
247253

254+
// This prevents the pprof import from being accidentally deleted.
255+
var_=pprof.Handler
256+
ifpprofEnabled {
257+
//nolint:revive
258+
deferserveHandler(cmd.Context(),logger,nil,pprofAddress,"pprof")()
259+
}
260+
ifpromEnabled {
261+
//nolint:revive
262+
deferserveHandler(cmd.Context(),logger,promhttp.Handler(),promAddress,"prometheus")()
263+
}
264+
248265
errCh:=make(chanerror,1)
249266
provisionerDaemons:=make([]*provisionerd.Server,0)
250267
fori:=0;uint8(i)<provisionerDaemonCount;i++ {
@@ -400,8 +417,12 @@ func server() *cobra.Command {
400417
},
401418
}
402419

403-
cliflag.StringVarP(root.Flags(),&accessURL,"access-url","","CODER_ACCESS_URL","","Specifies the external URL to access Coder")
404-
cliflag.StringVarP(root.Flags(),&address,"address","a","CODER_ADDRESS","127.0.0.1:3000","The address to serve the API and dashboard")
420+
cliflag.StringVarP(root.Flags(),&accessURL,"access-url","","CODER_ACCESS_URL","","Specifies the external URL to access Coder.")
421+
cliflag.StringVarP(root.Flags(),&address,"address","a","CODER_ADDRESS","127.0.0.1:3000","The address to serve the API and dashboard.")
422+
cliflag.BoolVarP(root.Flags(),&promEnabled,"prometheus-enable","","CODER_PROMETHEUS_ENABLE",false,"Enable serving prometheus metrics on the addressdefined by --prometheus-address.")
423+
cliflag.StringVarP(root.Flags(),&promAddress,"prometheus-address","","CODER_PROMETHEUS_ADDRESS","127.0.0.1:2112","The address to serve prometheus metrics.")
424+
cliflag.BoolVarP(root.Flags(),&promEnabled,"pprof-enable","","CODER_PPROF_ENABLE",false,"Enable serving pprof metrics on the address defined by --pprof-address.")
425+
cliflag.StringVarP(root.Flags(),&pprofAddress,"pprof-address","","CODER_PPROF_ADDRESS","127.0.0.1:6060","The address to serve pprof.")
405426
// systemd uses the CACHE_DIRECTORY environment variable!
406427
cliflag.StringVarP(root.Flags(),&cacheDir,"cache-dir","","CACHE_DIRECTORY",filepath.Join(os.TempDir(),"coder-cache"),"Specifies a directory to cache binaries for provision operations.")
407428
cliflag.BoolVarP(root.Flags(),&dev,"dev","","CODER_DEV_MODE",false,"Serve Coder in dev mode for tinkering")
@@ -661,6 +682,20 @@ func configureGithubOAuth2(accessURL *url.URL, clientID, clientSecret string, al
661682
},nil
662683
}
663684

685+
funcserveHandler(ctx context.Context,logger slog.Logger,handler http.Handler,addr,namestring) (closeFuncfunc()) {
686+
logger.Debug(ctx,"http server listening",slog.F("addr",addr),slog.F("name",name))
687+
688+
srv:=&http.Server{Addr:addr,Handler:handler}
689+
gofunc() {
690+
err:=srv.ListenAndServe()
691+
iferr!=nil&&!xerrors.Is(err,http.ErrServerClosed) {
692+
logger.Error(ctx,"http server listen",slog.F("name",name),slog.Error(err))
693+
}
694+
}()
695+
696+
returnfunc() {_=srv.Close() }
697+
}
698+
664699
typedatadogLoggerstruct {
665700
logger slog.Logger
666701
}

‎coderd/coderd.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/go-chi/chi/v5"
13+
"github.com/go-chi/chi/v5/middleware"
1314
"github.com/pion/webrtc/v3"
1415
"google.golang.org/api/idtoken"
1516

@@ -68,9 +69,18 @@ func New(options *Options) (http.Handler, func()) {
6869
})
6970

7071
r:=chi.NewRouter()
72+
r.Use(
73+
func(next http.Handler) http.Handler {
74+
returnhttp.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {
75+
next.ServeHTTP(middleware.NewWrapResponseWriter(w,r.ProtoMajor),r)
76+
})
77+
},
78+
httpmw.Prometheus,
79+
chitrace.Middleware(),
80+
)
81+
7182
r.Route("/api/v2",func(r chi.Router) {
7283
r.Use(
73-
chitrace.Middleware(),
7484
// Specific routes can specify smaller limits.
7585
httpmw.RateLimitPerMinute(options.APIRateLimit),
7686
debugLogRequest(api.Logger),

‎coderd/httpmw/prometheus.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package httpmw
2+
3+
import (
4+
"net/http"
5+
"strconv"
6+
"time"
7+
8+
"github.com/go-chi/chi/v5"
9+
chimw"github.com/go-chi/chi/v5/middleware"
10+
11+
"github.com/prometheus/client_golang/prometheus"
12+
"github.com/prometheus/client_golang/prometheus/promauto"
13+
)
14+
15+
var (
16+
requestsProcessed=promauto.NewCounterVec(prometheus.CounterOpts{
17+
Namespace:"coderd",
18+
Subsystem:"api",
19+
Name:"requests_processed_total",
20+
Help:"The total number of processed API requests",
21+
}, []string{"code","method","path"})
22+
requestsConcurrent=promauto.NewGauge(prometheus.GaugeOpts{
23+
Namespace:"coderd",
24+
Subsystem:"api",
25+
Name:"concurrent_requests",
26+
Help:"The number of concurrent API requests",
27+
})
28+
websocketsConcurrent=promauto.NewGauge(prometheus.GaugeOpts{
29+
Namespace:"coderd",
30+
Subsystem:"api",
31+
Name:"concurrent_websockets",
32+
Help:"The total number of concurrent API websockets",
33+
})
34+
websocketsDist=promauto.NewHistogramVec(prometheus.HistogramOpts{
35+
Namespace:"coderd",
36+
Subsystem:"api",
37+
Name:"websocket_durations_ms",
38+
Help:"Websocket duration distribution of requests in milliseconds",
39+
Buckets: []float64{
40+
durationToFloatMs(01*time.Millisecond),
41+
durationToFloatMs(01*time.Second),
42+
durationToFloatMs(01*time.Minute),
43+
durationToFloatMs(01*time.Hour),
44+
durationToFloatMs(15*time.Hour),
45+
durationToFloatMs(30*time.Hour),
46+
},
47+
}, []string{"path"})
48+
requestsDist=promauto.NewHistogramVec(prometheus.HistogramOpts{
49+
Namespace:"coderd",
50+
Subsystem:"api",
51+
Name:"request_latencies_ms",
52+
Help:"Latency distribution of requests in milliseconds",
53+
Buckets: []float64{1,5,10,25,50,100,500,1000,5000,10000,30000},
54+
}, []string{"method","path"})
55+
)
56+
57+
funcdurationToFloatMs(d time.Duration)float64 {
58+
returnfloat64(d.Milliseconds())
59+
}
60+
61+
funcPrometheus(next http.Handler) http.Handler {
62+
returnhttp.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {
63+
var (
64+
start=time.Now()
65+
method=r.Method
66+
rctx=chi.RouteContext(r.Context())
67+
)
68+
sw,ok:=w.(chimw.WrapResponseWriter)
69+
if!ok {
70+
panic("dev error: http.ResponseWriter is not chimw.WrapResponseWriter")
71+
}
72+
73+
var (
74+
dist*prometheus.HistogramVec
75+
distOpts []string
76+
)
77+
// We want to count websockets separately.
78+
ifisWebsocketUpgrade(r) {
79+
websocketsConcurrent.Inc()
80+
deferwebsocketsConcurrent.Dec()
81+
82+
dist=websocketsDist
83+
}else {
84+
requestsConcurrent.Inc()
85+
deferrequestsConcurrent.Dec()
86+
87+
dist=requestsDist
88+
distOpts= []string{method}
89+
}
90+
91+
next.ServeHTTP(w,r)
92+
93+
path:=rctx.RoutePattern()
94+
distOpts=append(distOpts,path)
95+
statusStr:=strconv.Itoa(sw.Status())
96+
97+
requestsProcessed.WithLabelValues(statusStr,method,path).Inc()
98+
dist.WithLabelValues(distOpts...).Observe(float64(time.Since(start))/1e6)
99+
})
100+
}
101+
102+
funcisWebsocketUpgrade(r*http.Request)bool {
103+
vs:=r.Header.Values("Upgrade")
104+
for_,v:=rangevs {
105+
ifv=="websocket" {
106+
returntrue
107+
}
108+
}
109+
returnfalse
110+
}

‎go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ require (
9090
github.com/pion/webrtc/v3v3.1.34
9191
github.com/pkg/browserv0.0.0-20210911075715-681adbf594b8
9292
github.com/pkg/sftpv1.13.4
93+
github.com/prometheus/client_golangv1.12.1
9394
github.com/quasilyte/go-ruleguard/dslv0.3.19
9495
github.com/robfig/cron/v3v3.0.1
9596
github.com/spf13/cobrav1.4.0
@@ -135,6 +136,7 @@ require (
135136
github.com/anmitsu/go-shlexv0.0.0-20200514113438-38f4b401e2be// indirect
136137
github.com/apparentlymart/go-textseg/v13v13.0.0// indirect
137138
github.com/armon/go-socks5v0.0.0-20160902184237-e75332964ef5// indirect
139+
github.com/beorn7/perksv1.0.1// indirect
138140
github.com/cenkalti/backoff/v4v4.1.2// indirect
139141
github.com/cespare/xxhash/v2v2.1.2// indirect
140142
github.com/charmbracelet/bubblesv0.10.3// indirect
@@ -184,6 +186,7 @@ require (
184186
github.com/mailru/easyjsonv0.7.7// indirect
185187
github.com/mattn/go-colorablev0.1.12// indirect
186188
github.com/mattn/go-runewidthv0.0.13// indirect
189+
github.com/matttproud/golang_protobuf_extensionsv1.0.2-0.20181231171920-c182affec369// indirect
187190
github.com/mgutz/ansiv0.0.0-20170206155736-9520e82c474b// indirect
188191
github.com/miekg/dnsv1.1.45// indirect
189192
github.com/mitchellh/go-wordwrapv1.0.1// indirect
@@ -213,6 +216,9 @@ require (
213216
github.com/pkg/errorsv0.9.1// indirect
214217
github.com/pmezard/go-difflibv1.0.0// indirect
215218
github.com/pquerna/cachecontrolv0.1.0// indirect
219+
github.com/prometheus/client_modelv0.2.0// indirect
220+
github.com/prometheus/commonv0.32.1// indirect
221+
github.com/prometheus/procfsv0.7.3// indirect
216222
github.com/rcrowley/go-metricsv0.0.0-20200313005456-10cdbea86bc0// indirect
217223
github.com/rivo/unisegv0.2.0// indirect
218224
github.com/sirupsen/logrusv1.8.1// indirect

‎site/src/api/typesGenerated.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export interface CreateWorkspaceBuildRequest {
9191
// This is likely an enum in an external package ("github.com/coder/coder/coderd/database.WorkspaceTransition")
9292
readonlytransition:string
9393
readonlydry_run:boolean
94+
readonlystate:string
9495
}
9596

9697
// From codersdk/organizations.go:52:6
@@ -265,12 +266,12 @@ export interface UpdateUserProfileRequest {
265266
readonlyusername:string
266267
}
267268

268-
// From codersdk/workspaces.go:94:6
269+
// From codersdk/workspaces.go:95:6
269270
exportinterfaceUpdateWorkspaceAutostartRequest{
270271
readonlyschedule:string
271272
}
272273

273-
// From codersdk/workspaces.go:114:6
274+
// From codersdk/workspaces.go:115:6
274275
exportinterfaceUpdateWorkspaceAutostopRequest{
275276
readonlyschedule:string
276277
}
@@ -366,7 +367,7 @@ export interface WorkspaceAgentResourceMetadata {
366367
readonlycpu_mhz:number
367368
}
368369

369-
// From codersdk/workspacebuilds.go:17:6
370+
// From codersdk/workspacebuilds.go:18:6
370371
exportinterfaceWorkspaceBuild{
371372
readonlyid:string
372373
readonlycreated_at:string

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp