Bibliotecas cliente de Prometheus y OpenTelemetry
Los servicios Go en producción exponen métricas de Prometheus para paneles y trazas de OpenTelemetry para la depuración de latencia de solicitudes.
Busca en todas las páginas de la documentación
Los servicios Go en producción exponen métricas de Prometheus para paneles y trazas de OpenTelemetry para la depuración de latencia de solicitudes.
Las bibliotecas cliente se encuentran en el borde HTTP/gRPC y envuelven las llamadas salientes sin reemplazar tu pila de logging.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
import (
"net/http"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
http.Handle("/metrics", promhttp.Handler())import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
handler := otelhttp.NewHandler(mux, "api")Cuándo recurrir a esto:
/metrics o un colector de OTel recibe OTLPpackage main
import (
"context"
"log"
"net/http"
"time"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/trace"
)
var (
httpDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "HTTP request latency",
Buckets: prometheus.DefBuckets,
}, []string{"method", "route", "status"})
)
func initTracer() trace.TracerProvider {
tp := sdktrace.NewTracerProvider()
otel.SetTracerProvider(tp)
return tp
}
func metricsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
next.ServeHTTP(ww, r)
route := chi.RouteContext(r.Context()).RoutePattern()
httpDuration.WithLabelValues(r.Method, route, http.StatusText(ww.Status())).Observe(time.Since(start).Seconds())
})
}
func main() {
tp := initTracer()
defer func() { _ = tp.Shutdown(context.Background()) }()
r := chi.NewRouter()
r.Use(metricsMiddleware)
r.Get("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) })
r.Handle("/metrics", promhttp.Handler())
root := otelhttp.NewHandler(r, "api")
log.Fatal(http.ListenAndServe(":8080", root))
}Lo que esto demuestra:
method, route, status)chi para estabilidad de etiquetas (evita URLs crudas con IDs)promhttp.Handler en una ruta dedicada para scraperspromhttp expone el formato de exposición de texto.TracerProvider, exportadores (OTLP gRPC/HTTP) y atributos de recursos (service.name).traceparent.| Tipo | Uso | Ejemplo |
|---|---|---|
| Counter | Totales monotónicos | http_requests_total |
| Gauge | Valores puntuales | go_goroutines, profundidad de cola |
| Histogram | Distribuciones de latencia | http_request_duration_seconds |
| Summary | Cuantiles del lado del cliente | Usa histograma + consultas Prometheus en su lugar cuando sea posible |
exporter, _ := otlptracegrpc.New(ctx)
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceName("orders-api"),
)),
)
otel.SetTracerProvider(tp)service.name con las etiquetas de despliegue para la búsqueda de trazas.promauto solo cuando un único registro sea suficiente; las bibliotecas deben aceptar parámetros prometheus.Registerer.go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc de manera similar./users/123 por solicitud explota las series. Solución: usa chi.RoutePattern() o nombres de ruta con plantillas.prometheus.Registerer a los constructores.Shutdown en SIGTERM con tiempo de espera de vaciado gradual./metrics filtra detalles operativos. Solución: oyente separado o política de red en el puerto de administración.
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
expvar | Pequeños contadores de depuración internos | Necesitas histogramas y Grafana |
| Clientes StatsD/DogStatsD | La organización exige el agente Datadog | La plataforma está estandarizada en Prometheus |
| Agentes APM de proveedor | Trazas completamente gestionadas | Quieres portabilidad OTLP |
| Solo logs | Prototipo inicial | Los SLOs de producción requieren métricas |
Muchos equipos mantienen el cliente Prometheus para scraping mientras adoptan OTel para trazas; la madurez de las métricas de OTel varía: sigue la guía de la plataforma.
Usa paquetes de middleware contribuidos o envuelve el motor como http.Handler con otelhttp en el punto de montaje.
Añade interceptores unarios/de flujo de otelgrpc y grpc-prometheus junto con la instrumentación HTTP.
Esa sección cubre slog, paneles RED y sondeos de salud; esta página se centra en las bibliotecas cliente de Prometheus y OTel.
Comienza con DefBuckets para APIs; ajusta los buckets del histograma cuando los umbrales de SLO se agrupen lejos de los predeterminados.
Usa un registro personalizado en las pruebas, recopila métricas con Gather() y afirma los valores de contadores/histogramas con testify.
Sí: inyecta trace_id en los campos de slog/zap a través del equipaje OTel o el contexto del span en el middleware.
Como mínimo service.name y service.version; añade deployment.environment para filtrado multi-entorno.
controller-runtime expone métricas para operadores de Kubernetes; se aplican las mismas reglas de cardinalidad.
Mantén la configuración del SDK de OTel en main o internal/telemetry; los paquetes de negocio dependen de interfaces, no de exportadores.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado GC de Green Tea, go fix modernizers - verificar parche en la compilación), chi (última - verificar en la compilación), gin (última - verificar en la compilación), echo (última - verificar en la compilación), google.golang.org/grpc (última - verificar en la compilación), sigs.k8s.io/controller-runtime (última - verificar en la compilación), kubebuilder (última - verificar en la compilación), tinygo (última - verificar objetivos de placa en la compilación), wazero (última - verificar en la compilación) y golangci-lint (última - verificar conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 19 jul 2026