lib/app/prometheus.go

68 lines
1.9 KiB
Go

package app
import (
"fmt"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/rs/cors"
)
var (
namespace = "collage"
counter = prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Name: "endpoint_request_count",
Help: "collage request count.",
}, []string{"app", "name", "method", "state"})
histogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{
Namespace: namespace,
Name: "endpoint_duration_seconds",
Help: "Time taken to execute endpoint.",
}, []string{"app", "name", "method", "status"})
)
type metricResponseWriter struct {
http.ResponseWriter
statusCode int
}
func newMetricResponseWriter(w http.ResponseWriter) *metricResponseWriter {
return &metricResponseWriter{w, http.StatusOK}
}
func (lrw *metricResponseWriter) WriteHeader(code int) {
lrw.statusCode = code
lrw.ResponseWriter.WriteHeader(code)
}
// SetupPrometheusHandler enable CORS, handler metrics
func SetupPrometheusHandler(handler http.Handler, app string) http.Handler {
sugar.Debug("app.SetupPrometheusHandler: 📥")
handleCORS := cors.AllowAll().Handler
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
lrw := newMetricResponseWriter(w)
handler.ServeHTTP(lrw, r)
statusCode := lrw.statusCode
duration := time.Since(start)
histogram.WithLabelValues(app, r.URL.String(), r.Method, fmt.Sprintf("%d", statusCode)).Observe(duration.Seconds())
counter.WithLabelValues(app, r.URL.String(), r.Method, fmt.Sprintf("%d", statusCode)).Inc()
})
err := prometheus.Register(histogram)
if err != nil {
sugar.Errorf("app.SetupPrometheusHandler: 💣 ⛔ %s", err.Error())
return nil
}
err = prometheus.Register(counter)
if err != nil {
sugar.Errorf("app.SetupPrometheusHandler: 💣 ⛔ %s", err.Error())
return nil
}
sugar.Info("app.SetupPrometheusHandler: 👍 📤")
return handleCORS(h)
}