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 {
2526var _promRequests promRequests
2627
2728type 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
3437func 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
82103func (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