Producción en Go: Logs, Métricas, Trazas y Señales
Ejecutar un servicio Go en producción significa que puedes responder qué sucedió, con qué frecuencia y cuánto tiempo tomó, sin necesidad de conectarte por SSH a un pod para leer stdout no estructurado.
Fundamentos de Observabilidad recopila fragmentos ejecutables; los artículos hermanos cubren slog, Prometheus, OpenTelemetry, sondas, apagado y configuración.
Observabilidad es la capacidad de inferir el estado interno del sistema a partir de salidas externas: logs (eventos discretos), métricas (contadores y histogramas agregados) y trazas (cadenas de latencia con ámbito de solicitud), además de señales operacionales como puntos finales de salud y comportamiento de apagado.
Perspectiva: Los binarios de Go son pequeños y rápidos, pero eso no hace visibles los fallos. Sin IDs de solicitud compartidos, dashboards RED y manejadores de sondas acotados, los ingenieros de guardia adivinan a partir de búsquedas en logs y gráficos de CPU.
Cuándo Usar: Cada API HTTP, servicio gRPC, worker y operador que se ejecuta fuera de un portátil de desarrollador necesita esta pila antes del primer despliegue en producción.
Limitaciones/Compromisos: Más señales implican costos de almacenamiento y riesgo de cardinalidad; el trazado añade sobrecarga; los logs verbosos pueden filtrar secretos; la configuración de recarga en caliente intercambia simplicidad por complejidad.
Temas Relacionados: middleware net/http, propagación de contexto, sondas de Kubernetes, scraping de Prometheus, exportadores de OpenTelemetry, Viper y análisis de flags.
La observabilidad descansa sobre tres pilares que se complementan entre sí.
Los Logs registran eventos individuales: un manejador comenzó, un pago falló, se agotó un reintento.
Los logs estructurados (campos clave-valor) te permiten filtrar user_id=… o trace_id=… en Loki o CloudWatch sin arqueología de expresiones regulares.
El paquete log/slog de Go (stdlib desde Go 1.21) es la opción predeterminada para nuevos servicios.
Las Métricas comprimen el comportamiento en números a lo largo del tiempo: tasa de solicitudes, ratio de errores, percentiles de duración.
Prometheus extrae contadores e histogramas de los puntos finales /metrics; Grafana grafica RED (Rate, Errors, Duration) por ruta o dependencia.
Las Trazas unen spans a través de servicios para que veas que una llamada API de 2 s pasó 1.8 s en PostgreSQL y 150 ms en una llamada HTTP descendente.
Los SDK de OpenTelemetry emiten spans a Jaeger, Tempo o backends de proveedores.
Más allá de los tres pilares, los servicios Go en producción exponen señales operacionales: /healthz y /readyz para orquestadores, manejo de SIGTERM para despliegues rodantes y configuración impulsada por el entorno para que el mismo binario se ejecute en staging y prod.
Solicitud
|
v
middleware -----> span de traza (OTel)
| |
v v
manejador -----> campos de slog (trace_id, route)
|
v
métricas <----- contador/histograma (estado, latencia)
La instrumentación se adjunta en límites estables.
El middleware HTTP envuelve http.Handler para iniciar spans, incrementar métricas y adjuntar un ID de solicitud al context.Context.
Ese contexto fluye hacia las llamadas a bases de datos y RPC para que los logs y los spans hijos compartan la misma clave de correlación.
Señal
Pregunta que responde
Herramientas Go típicas
Riesgo de cardinalidad
Logs
¿Qué sucedió en esta solicitud?
log/slog, zap (opcional)
Alto si registras IDs únicos por línea
Métricas
¿Cuántos? ¿Qué tan rápido? ¿Qué ratio de errores?
prometheus/client_golang
Alto si las etiquetas incluyen IDs de usuario ilimitados
Trazas
¿Dónde se fue el tiempo entre servicios?
SDK de OpenTelemetry para Go
Medio; el muestreo mitiga
Sondas
¿Está vivo el proceso? ¿Puede servir tráfico?
Manejadores de net/http
Bajo
Apagado
¿Pueden los despliegues drenarse de forma segura?
signal.Notify, server.Shutdown
N/A
Los logs y las trazas se enlazan a través de campos trace_id compartidos.
Las métricas permanecen agregadas: nunca pongas direcciones de correo electrónico crudas en las etiquetas de Prometheus.
La configuración se carga una vez al inicio (flags + env) o vigila archivos para recarga en caliente; los puntos finales de observabilidad deben reflejar errores de configuración en la preparación, no en la vitalidad.
La cardinalidad es el asesino silencioso de las pilas de métricas.
Prefiere etiquetas de plantilla http_route="/users/{id}" sobre etiquetas por usuario.
Los cubos del histograma deben coincidir con los umbrales de SLO (por ejemplo, 50 ms, 200 ms, 1 s).
El muestreo mantiene el volumen de trazas manejable: muestreo basado en cabeza en el borde o muestreo basado en cola solo para errores.
Siempre registra errores y spans de alta latencia, incluso cuando el tráfico base se muestrea hacia abajo.
El volumen de logs crece con QPS.
Establece niveles por entorno (INFO en prod, DEBUG en dev), oculta secretos en el manejador y evita registrar cuerpos de solicitud completos por defecto.
El slog de Go soporta LogValuer para campos costosos perezosos.
Kubernetes distingue liveness (reiniciar si está muerto) de readiness (eliminar del balanceador de carga si las dependencias fallan).
Una interrupción de la base de datos debería fallar la preparación, no la vitalidad, o reiniciarás pods que no pueden solucionar el problema.
El apagado ordenado empareja SIGTERM con un context.Context acotado pasado a http.Server.Shutdown y drenajes de workers en segundo plano.
El logging a stdout es suficiente para producción - Las líneas no estructuradas son difíciles de consultar; necesitas campos JSON o clave-valor y nombres de atributos consistentes.
Las métricas reemplazan a los logs - Las métricas muestran agregados; no pueden decirte qué usuario encontró el error. Usa ambos.
El trazado es solo para microservicios - Incluso los monolitos se benefician cuando un manejador llama a cinco dependencias; una sola traza explica las solicitudes lentas.
La verificación de salud es igual a la preparación - La vitalidad debe ser barata; la preparación debe verificar bases de datos y flags de características.
Más etiquetas crean mejores dashboards - La cardinalidad de etiquetas ilimitada bloquea Prometheus y aumenta el costo.
¿Cuál es la pila mínima de observabilidad para una nueva API Go?
Logs estructurados con ID de solicitud, un punto final /metrics con histograma de duración de solicitud, /healthz y /readyz, y apagado SIGTERM cubren lo básico.
Añade trazado cuando tengas más de una dependencia descendente o servicio.
¿Debo usar slog o zap?
Empieza con log/slog en la biblioteca estándar.
Busca zap cuando el profiling muestre asignaciones de logging en la ruta crítica o necesites características que slog aún no proporcione.
¿Cómo se conectan los logs y las trazas?
Inyecta trace_id y span_id del span activo de OpenTelemetry en los atributos de slog en cada solicitud.
Los backends de logs pueden enlazar a las UIs de trazas cuando los IDs coinciden.
¿Qué es RED para servicios HTTP?
Rate (solicitudes por segundo), Errors (solicitudes fallidas), Duration (distribución de latencia).
Instrumenta en la capa de middleware con etiquetas de plantilla de ruta, no rutas crudas con IDs.
¿Cuándo debería fallar la preparación?
Falla la preparación cuando las dependencias críticas (base de datos, caché, API ascendente requerida) son inalcanzables.
Mantén la vitalidad barata para que Kubernetes no reinicie procesos sanos durante interrupciones de dependencias.
¿La observabilidad ralentiza los servicios Go?
Métricas bien diseñadas y trazas muestreadas añaden una sobrecarga baja de un solo dígito porcentual.
El logging de depuración ilimitado y las etiquetas de alta cardinalidad perjudican más que las actualizaciones de histogramas.
¿Dónde expongo las métricas?
Monta /metrics en un oyente separado o ruta mux, restringe el acceso a la red y haz scraping con Prometheus o un agente compatible.
¿Es la configuración parte de la observabilidad?
La mala configuración causa interrupciones que parecen errores de código.
Logs de inicio estructurados, verificaciones de preparación para variables de entorno requeridas y valores predeterminados documentados reducen el tiempo medio de recuperación.
¿Cómo encajan frameworks como gin o chi?
Todavía usan manejadores de net/http.
Envuelve el router con el mismo middleware para logging, métricas y trazado, independientemente del framework.
¿Qué debo registrar en caso de errores?
Registra el tipo de error, la operación, los IDs de correlación y el contexto seguro.
Evita contraseñas, tokens y números completos de tarjetas de crédito, incluso en rutas de error.
¿Puedo omitir el trazado para los workers por lotes?
Los workers se benefician de spans alrededor del procesamiento de trabajos y llamadas externas.
Enlaza el ID del trabajo en los logs, incluso cuando los IDs de solicitud HTTP no existan.
¿Cómo pruebo los hooks de observabilidad?
Usa httptest para probar manejadores y afirmar incrementos de métricas o salida de logs con manejadores de prueba de slog.
Verifica que los puntos finales de sonda devuelvan los códigos de estado esperados bajo fallos de dependencias simulados.
Versiones de la Pila: Esta página fue escrita para Go 1.26.x (predeterminado Green Tea GC, go fix modernizers - verificar parche en la compilación), chi (última versión - verificar en la compilación), gin (última versión - verificar en la compilación), echo (última versión - verificar en la compilación), google.golang.org/grpc (última versión - verificar en la compilación), sigs.k8s.io/controller-runtime (última versión - verificar en la compilación), kubebuilder (última versión - verificar en la compilación), tinygo (última versión - verificar objetivos de placa en la compilación), wazero (última versión - verificar en la compilación) y golangci-lint (última versión - verificar conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026