@@ -17,11 +17,13 @@ import (
1717 "fmt"
1818 "io"
1919 "net/http"
20+ "time"
2021
2122 "github.com/google/uuid"
2223 "github.com/pkg/errors"
2324 "github.com/prometheus-community/promql-langserver/internal/vendored/go-tools/lsp/protocol"
2425 "github.com/prometheus-community/promql-langserver/langserver"
26+ "github.com/prometheus/client_golang/prometheus"
2527)
2628
2729type key int
@@ -129,3 +131,60 @@ func manageDocumentMiddleware(langServer langserver.HeadlessServer) middlewareFu
129131 }
130132 }
131133}
134+
135+ const (
136+ defaultMetricNamespace = "langserver"
137+ labelHandler = "handler"
138+ )
139+
140+ type apiMetrics struct {
141+ totalHTTPRequest * prometheus.CounterVec
142+ durationHTTPRequest * prometheus.SummaryVec
143+ }
144+
145+ func newAPIMetrics () * apiMetrics {
146+ return & apiMetrics {
147+ totalHTTPRequest : prometheus .NewCounterVec (prometheus.CounterOpts {
148+ Namespace : defaultMetricNamespace ,
149+ Name : "http_request_total" ,
150+ Help : "Total of HTTP requests received by the API" ,
151+ }, []string {labelHandler }),
152+ durationHTTPRequest : prometheus .NewSummaryVec (prometheus.SummaryOpts {
153+ Namespace : defaultMetricNamespace ,
154+ Name : "http_request_duration_second" ,
155+ Help : "HTTP request latencies in second" ,
156+ }, []string {labelHandler }),
157+ }
158+ }
159+
160+ func (m * apiMetrics ) Collect (ch chan <- prometheus.Metric ) {
161+ m .totalHTTPRequest .Collect (ch )
162+ m .durationHTTPRequest .Collect (ch )
163+ }
164+
165+ func (m * apiMetrics ) Describe (ch chan <- * prometheus.Desc ) {
166+ m .totalHTTPRequest .Describe (ch )
167+ m .durationHTTPRequest .Describe (ch )
168+ }
169+
170+ func (m * apiMetrics ) instrumentHTTPRequest (next http.HandlerFunc ) http.HandlerFunc {
171+ return func (w http.ResponseWriter , r * http.Request ) {
172+ start := time .Now ()
173+ // Call the next middleware.
174+ // This middleware should be executed in the first in the chain of the middleware in order to have an accurate execution time.
175+ next (w , r )
176+
177+ elaspsed := time .Since (start ).Seconds ()
178+
179+ counter , err := m .totalHTTPRequest .GetMetricWith (prometheus.Labels {labelHandler : r .URL .Path })
180+ if err != nil {
181+ return
182+ }
183+ counter .Inc ()
184+ sum , err := m .durationHTTPRequest .GetMetricWith (prometheus.Labels {labelHandler : r .URL .Path })
185+ if err != nil {
186+ return
187+ }
188+ sum .Observe (elaspsed )
189+ }
190+ }
0 commit comments