OpenTelemetry Go: Guía completa de trazado distribuido
1. ¿Qué es y para qué sirve?
OpenTelemetry es un conjunto de APIs, SDKs y herramientas diseñadas para crear y gestionar datos de telemetría, como trazas (traces), métricas (metrics) y registros (logs). La biblioteca opentelemetry-go es la implementación oficial del estándar OpenTelemetry para el lenguaje Go. Proporciona a los desarrolladores una forma única e independiente del proveedor de instrumentar sus aplicaciones para recopilar telemetría, que luego puede enviarse a diversos backends como Jaeger, Zipkin, Prometheus, Grafana Tempo, Datadog y muchos otros.
¿Para qué sirve? En las arquitecturas modernas de microservicios, una solicitud de usuario a menudo pasa por decenas de servicios diferentes. Cuando surge un problema (por ejemplo, una solicitud es demasiado lenta o termina en error), sin el trazado distribuido (distributed tracing) es extremadamente difícil identificar qué servicio se convirtió en el cuello de botella o en la fuente de la falla. OpenTelemetry permite rastrear la ruta de una solicitud a través de todo el sistema, ver el tiempo de ejecución de cada paso y vincularlos en una sola traza (trace) compuesta por spans. Esto brinda a los desarrolladores e ingenieros de confiabilidad (SRE) una herramienta poderosa para la depuración, el monitoreo y la optimización del rendimiento.
La principal ventaja de OpenTelemetry sobre otras soluciones (como las antiguas bibliotecas OpenTracing u OpenCensus) es su universalidad y estandarización. Escribes el código una sola vez, utilizando una API unificada, y puedes cambiar el backend para almacenar y visualizar los datos sin modificar el código de la aplicación. Esto convierte a opentelemetry-go no solo en una biblioteca, sino en la base para construir un sistema observable (observable) en Go.
2. Instalación
Para instalar la biblioteca opentelemetry-go y sus componentes principales, utiliza el gestor de paquetes estándar de Go. Necesitarás instalar el paquete principal de la API, el SDK para trazado y un exportador (por ejemplo, para consola o Jaeger).
# Instalar la API principal
go get go.opentelemetry.io/otel
# Instalar el SDK para trazado
go get go.opentelemetry.io/otel/sdk
# Instalar el exportador para salida en consola (para depuración)
go get go.opentelemetry.io/otel/exporters/stdout/stdouttrace
# Instalar el propagador HTTP de contexto (para integración con HTTP)
go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
# Instalar el exportador para Jaeger (para producción)
go get go.opentelemetry.io/otel/exporters/jaeger
Después de ejecutar estos comandos, todas las dependencias necesarias se agregarán a tu archivo go.mod.
3. Inicio rápido — ejemplo mínimo funcional
Este ejemplo muestra cómo crear una traza simple con un solo span y mostrarla en la consola. Es un excelente punto de partida para comprender los conceptos básicos.
package main
import (
"context"
"fmt"
"log"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
"go.opentelemetry.io/otel/trace"
)
func main() {
// 1. Crear el exportador para salida en consola
exporter, err := stdouttrace.New(
stdouttrace.WithPrettyPrint(),
)
if err != nil {
log.Fatal(err)
}
// 2. Crear un TracerProvider con el exportador y el recurso
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("mi-servicio"),
)),
)
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
log.Fatal(err)
}
}()
// 3. Establecer el TracerProvider global
otel.SetTracerProvider(tp)
// 4. Obtener un Tracer
tracer := otel.Tracer("mi-trazador")
// 5. Crear un span
ctx, span :=