Skip to content

Commit b3962a8

Browse files
authored
metrics: track service duration (#23)
* metrics: track service duration * fix prom * fix test * update golang docker
1 parent a782d11 commit b3962a8

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
runs-on: ubuntu-latest
88
strategy:
99
matrix:
10-
go: ['1.24.4']
10+
go: ['1.25.1']
1111
name: Go ${{ matrix.go }}
1212
steps:
1313
- uses: actions/checkout@v3

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.24.4-bookworm
1+
FROM golang:1.25.1-bookworm
22

33
ARG VERSION
44
ARG GOAMD64

metric/requests.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strconv"
88
"strings"
99
"sync"
10+
"time"
1011

1112
"github.com/moonrhythm/parapet"
1213
"github.com/moonrhythm/parapet/pkg/prom"
@@ -25,23 +26,32 @@ func Requests() parapet.Middleware {
2526
var _promRequests promRequests
2627

2728
type promRequests struct {
28-
vec *prometheus.CounterVec
29+
vec *prometheus.CounterVec
30+
durations *prometheus.HistogramVec
2931

3032
mu sync.RWMutex
3133
m map[string]prometheus.Counter // host/namespace/ingress/service/type/method/status
34+
d map[string]prometheus.Observer
3235
}
3336

3437
func init() {
3538
_promRequests.vec = prometheus.NewCounterVec(prometheus.CounterOpts{
3639
Namespace: prom.Namespace,
3740
Name: "requests",
3841
}, []string{"host", "status", "method", "ingress_name", "ingress_namespace", "service_type", "service_name"})
42+
_promRequests.durations = prometheus.NewHistogramVec(prometheus.HistogramOpts{
43+
Namespace: prom.Namespace,
44+
Name: "service_durations",
45+
}, []string{"service_type", "service_name"})
3946
_promRequests.m = make(map[string]prometheus.Counter, requestSizeHint)
47+
_promRequests.d = make(map[string]prometheus.Observer, requestSizeHint)
4048

41-
prom.Registry().MustRegister(_promRequests.vec)
49+
prom.Registry().MustRegister(_promRequests.vec, _promRequests.durations)
4250
}
4351

44-
func (p *promRequests) Inc(r *http.Request, status int) {
52+
func (p *promRequests) Inc(r *http.Request, status int, start time.Time) {
53+
duration := time.Since(start)
54+
4555
ctx := r.Context()
4656
s := state.Get(ctx)
4757

@@ -57,6 +67,7 @@ func (p *promRequests) Inc(r *http.Request, status int) {
5767

5868
p.mu.RLock()
5969
m := p.m[key]
70+
d := p.d[key]
6071
p.mu.RUnlock()
6172

6273
if m == nil {
@@ -73,18 +84,29 @@ func (p *promRequests) Inc(r *http.Request, status int) {
7384
})
7485
}
7586
m = p.m[key]
87+
88+
if p.d[key] == nil {
89+
p.d[key] = p.durations.With(prometheus.Labels{
90+
"service_type": s["serviceType"],
91+
"service_name": s["serviceName"],
92+
})
93+
}
94+
d = p.d[key]
95+
7696
p.mu.Unlock()
7797
}
7898

7999
m.Inc()
100+
d.Observe(float64(duration.Milliseconds()))
80101
}
81102

82103
func (p *promRequests) ServeHandler(h http.Handler) http.Handler {
83104
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
105+
start := time.Now()
84106
nw := requestTrackRW{
85107
ResponseWriter: w,
86108
}
87-
defer func() { p.Inc(r, nw.status) }()
109+
defer func() { p.Inc(r, nw.status, start) }()
88110

89111
h.ServeHTTP(&nw, r)
90112
})

0 commit comments

Comments
 (0)