Commit a2b3c382 authored by ale's avatar ale

Add a per-request counter to the Prometheus metrics

parent a357ed38
......@@ -13,10 +13,23 @@ import (
"git.autistici.org/ai3/go-common/clientutil"
"git.autistici.org/ai3/go-common/serverutil"
"github.com/prometheus/client_golang/prometheus"
as "git.autistici.org/ai3/accountserver"
)
var (
requestCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "accountserver_requests_total",
Help: "Total number of requests, by type",
},
[]string{"method", "status"})
)
func init() {
prometheus.MustRegister(requestCounter)
}
type actionRegistry struct {
service *as.AccountService
handlers map[string]reflect.Type
......@@ -33,18 +46,22 @@ func (r *actionRegistry) Register(path string, rtype as.Request) {
r.handlers[path] = reflect.ValueOf(rtype).Elem().Type()
}
func (r *actionRegistry) newRequest(path string) (as.Request, bool) {
// Create a new instance of a Request type, along with the type name
// (used for monitoring).
func (r *actionRegistry) newRequest(path string) (as.Request, string, bool) {
h, ok := r.handlers[path]
if !ok {
return nil, false
return nil, "", false
}
return reflect.New(h).Interface().(as.Request), true
return reflect.New(h).Interface().(as.Request),
strings.TrimSuffix(h.Name(), "Request"),
true
}
func (r *actionRegistry) ServeHTTP(w http.ResponseWriter, httpReq *http.Request) {
// Create a new empty request object based on the request
// path, then decode the HTTP request JSON body onto it.
req, ok := r.newRequest(httpReq.URL.Path)
req, reqTypeName, ok := r.newRequest(httpReq.URL.Path)
if !ok {
http.NotFound(w, httpReq)
return
......@@ -76,12 +93,17 @@ func (r *actionRegistry) ServeHTTP(w http.ResponseWriter, httpReq *http.Request)
// Now that all is done, we can log the request/response
// (sanitization might modify the objects in place).
reqData := marshalJSONSanitized(req)
reqStatus := "error"
if err != nil {
log.Printf("request: %s %s -> ERROR: %v", httpReq.URL.Path, reqData, err)
} else {
respData := marshalJSONSanitized(resp)
log.Printf("request: %s %s -> %s", httpReq.URL.Path, reqData, respData)
reqStatus = "ok"
}
// Increment the request metric.
requestCounter.WithLabelValues(reqTypeName, reqStatus).Inc()
}
// APIServer is the HTTP API interface to AccountService. It
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment