Instrumenting a Go application for Prometheus

Prometheus has an official Go client library that you can use to instrument Go applications. In this guide, we'll create a simple Go application that exposes Prometheus metrics via HTTP.

NOTE: For comprehensive API documentation, see the GoDoc for Prometheus' various Go libraries.

Installation

You can install the prometheus, promauto, and promhttp libraries necessary for the guide using go get:

  1. go get github.com/prometheus/client_golang/prometheus
  2. go get github.com/prometheus/client_golang/prometheus/promauto
  3. go get github.com/prometheus/client_golang/prometheus/promhttp

How Go exposition works

To expose Prometheus metrics in a Go application, you need to provide a /metrics HTTP endpoint. You can use the prometheus/promhttp library's HTTP Handler as the handler function.

This minimal application, for example, would expose the default metrics for Go applications via http://localhost:2112/metrics:

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/prometheus/client_golang/prometheus/promhttp"
  5. )
  6. func main() {
  7. http.Handle("/metrics", promhttp.Handler())
  8. http.ListenAndServe(":2112", nil)
  9. }

To start the application:

  1. go run main.go

To access the metrics:

  1. curl http://localhost:2112/metrics

Adding your own metrics

The application above exposes only the default Go metrics. You can also register your own custom application-specific metrics. This example application exposes a myapp_processed_ops_total counter that counts the number of operations that have been processed thus far. Every 2 seconds, the counter is incremented by one.

  1. package main
  2. import (
  3. "net/http"
  4. "time"
  5. "github.com/prometheus/client_golang/prometheus"
  6. "github.com/prometheus/client_golang/prometheus/promauto"
  7. "github.com/prometheus/client_golang/prometheus/promhttp"
  8. )
  9. func recordMetrics() {
  10. go func() {
  11. for {
  12. opsProcessed.Inc()
  13. time.Sleep(2 * time.Second)
  14. }
  15. }()
  16. }
  17. var (
  18. opsProcessed = promauto.NewCounter(prometheus.CounterOpts{
  19. Name: "myapp_processed_ops_total",
  20. Help: "The total number of processed events",
  21. })
  22. )
  23. func main() {
  24. recordMetrics()
  25. http.Handle("/metrics", promhttp.Handler())
  26. http.ListenAndServe(":2112", nil)
  27. }

To run the application:

  1. go run main.go

To access the metrics:

  1. curl http://localhost:2112/metrics

In the metrics output, you'll see the help text, type information, and current value of the myapp_processed_ops_total counter:

  1. # HELP myapp_processed_ops_total The total number of processed events
  2. # TYPE myapp_processed_ops_total counter
  3. myapp_processed_ops_total 5

You can configure a locally running Prometheus instance to scrape metrics from the application. Here's an example prometheus.yml configuration:

  1. scrape_configs:
  2. - job_name: myapp
  3. scrape_interval: 10s
  4. static_configs:
  5. - targets:
  6. - localhost:2112

Other Go client features

In this guide we covered just a small handful of features available in the Prometheus Go client libraries. You can also expose other metrics types, such as gauges and histograms, non-global registries, functions for pushing metrics to Prometheus PushGateways, bridging Prometheus and Graphite, and more.

Summary

In this guide, you created two sample Go applications that expose metrics to Prometheus—-one that exposes only the default Go metrics and one that also exposes a custom Prometheus counter—-and configured a Prometheus instance to scrape metrics from those applications.