| 13 | ) |
| 14 | |
| 15 | func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler { |
| 16 | factory := promauto.With(register) |
| 17 | requestsProcessed := factory.NewCounterVec(prometheus.CounterOpts{ |
| 18 | Namespace: "coderd", |
| 19 | Subsystem: "api", |
| 20 | Name: "requests_processed_total", |
| 21 | Help: "The total number of processed API requests", |
| 22 | }, []string{"code", "method", "path"}) |
| 23 | requestsConcurrent := factory.NewGaugeVec(prometheus.GaugeOpts{ |
| 24 | Namespace: "coderd", |
| 25 | Subsystem: "api", |
| 26 | Name: "concurrent_requests", |
| 27 | Help: "The number of concurrent API requests.", |
| 28 | }, []string{"method", "path"}) |
| 29 | websocketsConcurrent := factory.NewGaugeVec(prometheus.GaugeOpts{ |
| 30 | Namespace: "coderd", |
| 31 | Subsystem: "api", |
| 32 | Name: "concurrent_websockets", |
| 33 | Help: "The total number of concurrent API websockets.", |
| 34 | }, []string{"path"}) |
| 35 | websocketsDist := factory.NewHistogramVec(prometheus.HistogramOpts{ |
| 36 | Namespace: "coderd", |
| 37 | Subsystem: "api", |
| 38 | Name: "websocket_durations_seconds", |
| 39 | Help: "Websocket duration distribution of requests in seconds.", |
| 40 | Buckets: []float64{ |
| 41 | 0.001, // 1ms |
| 42 | 1, |
| 43 | 60, // 1 minute |
| 44 | 60 * 60, // 1 hour |
| 45 | 60 * 60 * 15, // 15 hours |
| 46 | 60 * 60 * 30, // 30 hours |
| 47 | }, |
| 48 | }, []string{"path"}) |
| 49 | requestsDist := factory.NewHistogramVec(prometheus.HistogramOpts{ |
| 50 | Namespace: "coderd", |
| 51 | Subsystem: "api", |
| 52 | Name: "request_latencies_seconds", |
| 53 | Help: "Latency distribution of requests in seconds.", |
| 54 | Buckets: []float64{0.001, 0.005, 0.010, 0.025, 0.050, 0.100, 0.500, 1, 5, 10, 30}, |
| 55 | }, []string{"method", "path"}) |
| 56 | |
| 57 | return func(next http.Handler) http.Handler { |
| 58 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 59 | var ( |
| 60 | start = time.Now() |
| 61 | method = r.Method |
| 62 | ) |
| 63 | |
| 64 | sw, ok := w.(*tracing.StatusWriter) |
| 65 | if !ok { |
| 66 | panic("dev error: http.ResponseWriter is not *tracing.StatusWriter") |
| 67 | } |
| 68 | |
| 69 | var ( |
| 70 | dist *prometheus.HistogramVec |
| 71 | distOpts []string |
| 72 | path = ExtractHTTPRoute(r.Context()) |