prometheus

prometheus implements github.com/tecnickcom/nurago/pkg/metrics.Client using the Prometheus client ecosystem.

Part of nurago, a collection of independent Go packages for backend services.

import "github.com/tecnickcom/nurago/pkg/metrics/prometheus"

Package prometheus implements github.com/tecnickcom/nurago/pkg/metrics.Client using the Prometheus client ecosystem.

It registers a set of default collectors and exposes wrappers for common instrumentation points:

  • inbound HTTP handlers
  • outbound HTTP round trippers
  • SQL database stats
  • application counters (log level and error code dimensions)

The implementation is based on:

  • github.com/prometheus/client_golang/prometheus
  • github.com/prometheus/client_golang/prometheus/promhttp
  • github.com/dlmiddlecote/sqlstats

Default Metrics Scope

Default collectors include:

  • Go runtime and process metrics
  • HTTP server request count, in-flight gauge, duration histogram, request size histogram, and response size histogram
  • HTTP client request count, in-flight gauge, and duration histogram
  • error counters by level and by task/operation/code

When To Use

  • Your platform scrapes metrics rather than receiving pushes.
  • You want standard HTTP, SQL, and error metrics without defining collectors by hand.

Example

// The returned Client satisfies metrics.Client, so application code
// depends on the contract rather than on Prometheus.
var client metrics.Client

client, err := prometheus.New()
if err != nil {
	fmt.Println(err)

	return
}

defer func() { _ = client.Close() }()

// The path label must be a low-cardinality route template, never a raw
// request URI containing identifiers.
handler := client.InstrumentHandler("/users/{id}", func(w http.ResponseWriter, _ *http.Request) {
	w.WriteHeader(http.StatusOK)
})

rec := httptest.NewRecorder()
handler.ServeHTTP(rec, httptest.NewRequestWithContext(
	context.TODO(), http.MethodGet, "/users/42", nil,
))

client.IncErrorCounter("user", "read", "404")

// The metrics endpoint returns the scrape payload, since Prometheus is
// a pull-based backend.
scrape := httptest.NewRecorder()
client.MetricsHandlerFunc()(scrape, httptest.NewRequestWithContext(
	context.TODO(), http.MethodGet, "/metrics", nil,
))

body, _ := io.ReadAll(scrape.Body)

fmt.Println(rec.Code, scrape.Code)
fmt.Println(strings.Contains(string(body), prometheus.NameAPIRequests))

// Output:
// 200 200
// true

Full source is in example_prometheus_test.go. More runnable examples are on pkg.go.dev.

Dependencies

Importing this package pulls 10 external modules:

  • github.com/beorn7/perks
  • github.com/cespare/xxhash/v2
  • github.com/dlmiddlecote/sqlstats
  • github.com/munnerz/goautoneg
  • github.com/prometheus/client_golang
  • github.com/prometheus/client_model
  • github.com/prometheus/common
  • github.com/prometheus/procfs
  • golang.org/x/sys
  • google.golang.org/protobuf