Golang application metrics


We will see how to expose metrics in Prometheus original format as Open Source monitoring tool, scalable and Cloud Native.

Prometheus give us specific libraries for each programming language.

As an essential point, we should avoid coupling our applications with intrusive libraries, as in the future our monitoring stack could change.

Libraries

Firstly, we will add the three Prometheus libraries to our project:

go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promauto
go get github.com/prometheus/client_golang/prometheus/promhttp

Monitoring code

As I’m using Gin-gonic as a development Framework, I have to create a specific handle to expose the metrics:

package interfaces

import (
    "github.com/gin-gonic/gin"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

func MetricsHandlerGetHandler() func(c *gin.Context) {
    return func(c *gin.Context) {
        prometheusHandler := promhttp.Handler()
        prometheusHandler.ServeHTTP(c.Writer, c.Request)
    }
}

Add the handler to the router:

func main() {
    router := gin.Default()
    router.GET("/metrics", interfaces.MetricsHandlerGetHandler())
    router.Run(":8080")
}

Testing the metrics

Run the application:

 go run app.go
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /api/v1/health            --> golang-k8s-helm-helloworld/interfaces.HealthcheckGetHandler.func1 (3 handlers)
[GIN-debug] GET    /api/v1/grettings         --> golang-k8s-helm-helloworld/interfaces.MessageGetHandler.func1 (3 handlers)
[GIN-debug] GET    /metrics                  --> golang-k8s-helm-helloworld/interfaces.MetricsHandlerGetHandler.func1 (3 handlers)
[GIN-debug] Listening and serving HTTP on :8080

The application expose the ```/metrics```` endpoint, as you can see at logs.

If we call this endpoint:

❯ curl localhost:8080/metrics
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0
go_gc_duration_seconds{quantile="0.25"} 0
go_gc_duration_seconds{quantile="0.5"} 0
go_gc_duration_seconds{quantile="0.75"} 0
go_gc_duration_seconds{quantile="1"} 0
go_gc_duration_seconds_sum 0
go_gc_duration_seconds_count 0
...

We can see a lot of parameters. In the following articles, we will see how Prometheus reads these metrics and store them.

References