Skip to content

Commit

Permalink
Do not use init functions to initialize metrics (#22)
Browse files Browse the repository at this point in the history
* Do not use init functions to initialize metrics

* Fix multiple metrics initialization on testing

* Change metric name
  • Loading branch information
miguelreiswildlife authored Jan 13, 2025
1 parent 869c980 commit dcd1070
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ vendor/
bin/
_build/
.idea
.vscode/launch.json
10 changes: 7 additions & 3 deletions api/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ package api

import (
"fmt"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
"os"
"strings"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"

raven "github.com/getsentry/raven-go"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
Expand Down Expand Up @@ -47,6 +48,7 @@ type App struct {
HttpClient *httpclient.HttpClient
NewRelic newrelic.Application
DDStatsD *DogStatsD
Metrics *Metrics
}

// GetApp returns a new arkadiko API Application
Expand Down Expand Up @@ -222,10 +224,12 @@ func (app *App) configureApplication() error {

}

app.Metrics = NewMetrics()

a.Pre(middleware.RemoveTrailingSlash())
a.Use(NewLoggerMiddleware(app.Logger).Serve)
a.Use(NewRecoveryMiddleware(app.OnErrorHandler).Serve)
a.Use(NewResponseTimeMetricsMiddleware(app.DDStatsD).Serve)
a.Use(NewResponseTimeMetricsMiddleware(app.DDStatsD, app.Metrics.APILatency).Serve)
a.Use(NewVersionMiddleware().Serve)
a.Use(NewSentryMiddleware(app).Serve)
a.Use(NewNewRelicMiddleware(app, app.Logger).Serve)
Expand Down
30 changes: 30 additions & 0 deletions api/metrics_reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package api
import (
"fmt"
"strconv"
"sync"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/spf13/viper"
"github.com/topfreegames/extensions/dogstatsd"
)
Expand Down Expand Up @@ -90,3 +93,30 @@ func (d *DogStatsD) Increment(metric string, tags ...string) error {
prefixTags(d.tagsPrefix, tags...)
return d.client.Incr(metric, tags, d.rate)
}

type Metrics struct {
APILatency *prometheus.HistogramVec
MQTTLatency *prometheus.HistogramVec
}

var metricsOnce sync.Once
var metricsSingleton *Metrics

func NewMetrics() *Metrics {
metricsOnce.Do(func() {
metricsSingleton = &Metrics{
APILatency: promauto.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "arkadiko",
Name: "response_time",
Help: "API response time",
}, []string{"route", "method", "status"}),
MQTTLatency: promauto.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "arkadiko",
Name: "mqtt_latency",
Help: "MQTT latency",
}, []string{"error", "retained"}),
}
})

return metricsSingleton
}
30 changes: 12 additions & 18 deletions api/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ package api
import (
"encoding/json"
"fmt"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"runtime/debug"
"time"

"github.com/prometheus/client_golang/prometheus"

raven "github.com/getsentry/raven-go"
"github.com/labstack/echo"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -80,25 +80,19 @@ func (s *SentryMiddleware) Serve(next echo.HandlerFunc) echo.HandlerFunc {

// ResponseTimeMetricsMiddleware struct encapsulating DDStatsD
type ResponseTimeMetricsMiddleware struct {
DDStatsD MetricsReporter
}

var latencyMetric *prometheus.HistogramVec

func init() {
latencyMetric = promauto.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "arkadiko",
Name: "response_time",
Help: "",
},
[]string{"route", "method", "status"},
)
DDStatsD MetricsReporter
latencyMetric *prometheus.HistogramVec
}

// ResponseTimeMetricsMiddleware returns a new ResponseTimeMetricsMiddleware
func NewResponseTimeMetricsMiddleware(ddStatsD MetricsReporter) *ResponseTimeMetricsMiddleware {
func NewResponseTimeMetricsMiddleware(
ddStatsD MetricsReporter,
latencyMetric *prometheus.HistogramVec,
) *ResponseTimeMetricsMiddleware {

return &ResponseTimeMetricsMiddleware{
DDStatsD: ddStatsD,
DDStatsD: ddStatsD,
latencyMetric: latencyMetric,
}
}

Expand All @@ -122,7 +116,7 @@ func (responseTimeMiddleware ResponseTimeMetricsMiddleware) Serve(next echo.Hand

// Keeping both for retro compatibility in the short term
responseTimeMiddleware.DDStatsD.Timing(responseTimeMillisecondsMetricName, timeUsed, tags...)
latencyMetric.WithLabelValues(route, method, fmt.Sprintf("%d", status)).Observe(timeUsed.Seconds())
responseTimeMiddleware.latencyMetric.WithLabelValues(route, method, fmt.Sprintf("%d", status)).Observe(timeUsed.Seconds())

return result
}
Expand Down
16 changes: 1 addition & 15 deletions api/sendmqtt.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ package api
import (
"encoding/json"
"fmt"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"io/ioutil"
"net/http"
"time"
Expand All @@ -20,18 +18,6 @@ import (
log "github.com/sirupsen/logrus"
)

var sendMqttLatencyMetric *prometheus.HistogramVec

func init() {
sendMqttLatencyMetric = promauto.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "arkadiko",
Name: "send_mqtt_latency",
Help: "The latency of sending a message to mqtt",
},
[]string{"error", "retained"},
)
}

// SendMqttHandler is the handler responsible for sending messages to mqtt
func SendMqttHandler(app *App) func(c echo.Context) error {
return func(c echo.Context) error {
Expand Down Expand Up @@ -108,7 +94,7 @@ func SendMqttHandler(app *App) func(c echo.Context) error {
}

app.DDStatsD.Timing("mqtt_latency", mqttLatency, tags...)
sendMqttLatencyMetric.WithLabelValues(fmt.Sprintf("%t", err != nil), fmt.Sprintf("%t", retained)).Observe(mqttLatency.Seconds())
app.Metrics.MQTTLatency.WithLabelValues(fmt.Sprintf("%t", err != nil), fmt.Sprintf("%t", retained)).Observe(mqttLatency.Seconds())
lg = lg.WithField("mqttLatency", mqttLatency.Nanoseconds())
lg.Debug("sent mqtt message")
c.Set("mqttLatency", mqttLatency)
Expand Down

0 comments on commit dcd1070

Please sign in to comment.