-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrack_handler.go
54 lines (39 loc) · 1.34 KB
/
track_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package prom
import (
"fmt"
"log"
"net/http"
"runtime/debug"
"time"
)
// TrackHandler monitor an event handler or business go method like an HTTP Request Handler, and protect it
// from panicking the whole application.
func (o *Registerer) TrackHandler(err *error, methodName string) (onCompleted func()) {
timeStart := time.Now()
o.requestsReceived.WithLabelValues(methodName).Inc()
// onCompleted happen as a deferred func at handler ends
onCompleted = func() {
statusCode := 0
// handle panic & map error to std http status code
if p := recover(); p != nil {
statusCode = CustomHTTPCodePanic
log.Printf("TrackHandler: Panic in %s: %#v: stack:\n%s\n", methodName, p, string(debug.Stack()))
} else if *err == nil {
statusCode = http.StatusOK
} else if invalidParam, ok := (*err).(*ErrorInvalidParam); ok {
statusCode = http.StatusBadRequest
log.Printf("TrackHandler: %s: InvalidArgument err: %v", methodName, invalidParam)
} else {
statusCode = http.StatusInternalServerError
log.Printf("TrackHandler: %s: internal err: %v", methodName, *err)
}
status := fmt.Sprintf("%d", statusCode)
o.responsesSent.WithLabelValues(methodName, status).Inc()
duration := time.Since(timeStart).Seconds()
o.rpcDurations.WithLabelValues(methodName, status).Observe(duration)
}
return
}
const (
CustomHTTPCodePanic = 999
)