summaryrefslogtreecommitdiff
path: root/cmd/rr/http/metrics.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/rr/http/metrics.go')
-rw-r--r--cmd/rr/http/metrics.go86
1 files changed, 86 insertions, 0 deletions
diff --git a/cmd/rr/http/metrics.go b/cmd/rr/http/metrics.go
new file mode 100644
index 00000000..f9d3c079
--- /dev/null
+++ b/cmd/rr/http/metrics.go
@@ -0,0 +1,86 @@
+package http
+
+import (
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/spf13/cobra"
+ rr "github.com/spiral/roadrunner/cmd/rr/cmd"
+ rrhttp "github.com/spiral/roadrunner/service/http"
+ "github.com/spiral/roadrunner/service/metrics"
+ "strconv"
+)
+
+func init() {
+ cobra.OnInitialize(func() {
+ svc, _ := rr.Container.Get(metrics.ID)
+ mtr, ok := svc.(*metrics.Service)
+ if !ok || !mtr.Enabled() {
+ return
+ }
+
+ ht, _ := rr.Container.Get(rrhttp.ID)
+ if ht, ok := ht.(*rrhttp.Service); ok {
+ collector := newCollector()
+
+ // register metrics
+ mtr.MustRegister(collector.requestCounter)
+ mtr.MustRegister(collector.requestDuration)
+
+ // collect events
+ ht.AddListener(collector.listener)
+ }
+ })
+}
+
+// listener provide debug callback for system events. With colors!
+type metricCollector struct {
+ requestCounter *prometheus.CounterVec
+ requestDuration *prometheus.HistogramVec
+}
+
+func newCollector() *metricCollector {
+ return &metricCollector{
+ requestCounter: prometheus.NewCounterVec(
+ prometheus.CounterOpts{
+ Name: "rr_http_total",
+ Help: "Total number of handled http requests after server restart.",
+ },
+ []string{"status"},
+ ),
+ requestDuration: prometheus.NewHistogramVec(
+ prometheus.HistogramOpts{
+ Name: "rr_http_request_duration",
+ Help: "HTTP request duration.",
+ Buckets: []float64{0.25, 0.5, 1, 10, 20, 60},
+ },
+ []string{"status"},
+ ),
+ }
+}
+
+// listener listens to http events and generates nice looking output.
+func (c *metricCollector) listener(event int, ctx interface{}) {
+ // http events
+ switch event {
+ case rrhttp.EventResponse:
+ e := ctx.(*rrhttp.ResponseEvent)
+
+ c.requestCounter.With(prometheus.Labels{
+ "status": strconv.Itoa(e.Response.Status),
+ }).Inc()
+
+ c.requestDuration.With(prometheus.Labels{
+ "status": strconv.Itoa(e.Response.Status),
+ }).Observe(e.Elapsed().Seconds())
+
+ case rrhttp.EventError:
+ e := ctx.(*rrhttp.ErrorEvent)
+
+ c.requestCounter.With(prometheus.Labels{
+ "status": "500",
+ }).Inc()
+
+ c.requestDuration.With(prometheus.Labels{
+ "status": "500",
+ }).Observe(e.Elapsed().Seconds())
+ }
+}