La corrección está integrada en el TP (Ver los recuadros verdes)
Lo que vas a aprender en este TP
- Conectar un logger existente a OpenTelemetry
- Correlacionar logs y trazas
- Recoger archivos con filelog
Introducción #
Lo que vas a aprender en esta sección
- Conectar un logger existente a OpenTelemetry
- Correlacionar logs y trazas
- Recoger archivos con filelog
Contexto. Los logs de facturación son archivos de texto que nadie vincula con las trazas. Conectas el servicio moderno a OpenTelemetry y recoges los logs de la aplicación heredada sin modificarla.
Requisitos previos: Docker y Python 3.10 o superior; la pila grafana/otel-lgtm (Collector, Tempo, Loki, Prometheus, Pyroscope y Grafana en un solo contenedor) · Duración estimada: 45 min
Puesta en práctica #
Pasos guiados, con su corrección.
1. Arrancar la pila de observabilidad
¿Por qué? Una sola imagen proporciona un Collector OTLP y todos los backends: nos centramos en la señal.
Lanzagrafana/otel-lgtm, crea un entorno Python y apunta los exportadores al puerto OTLP/HTTP 4318.Ver la corrección
docker run -d --name lgtm -p 3000:3000 -p 4317:4317 -p 4318:4318 -p 4040:4040 grafana/otel-lgtm python3 -m venv .venv && . .venv/bin/activate export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf # Grafana : http://localhost:3000 (admin / admin)2. Conectar el módulo logging
¿Por qué? El LoggingHandler convierte cada llamada a logging en un LogRecord de OpenTelemetry, con el contexto de traza activo.
Escribefacturation.py: un LoggerProvider con exportador OTLP, un handler añadido al logger raíz, un TracerProvider y logs INFO y ERROR emitidos dentro de spans.Ver la corrección
pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http cat > facturation.py <<'EOF' import logging, random, time from opentelemetry import trace from opentelemetry._logs import set_logger_provider from opentelemetry.sdk.resources import Resource from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler from opentelemetry.sdk._logs.export import BatchLogRecordProcessor from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter resource = Resource.create({"service.name": "facturation", "service.version": "2.1.0"}) logs = LoggerProvider(resource=resource) logs.add_log_record_processor(BatchLogRecordProcessor(OTLPLogExporter())) set_logger_provider(logs) logging.basicConfig(level=logging.INFO) logging.getLogger().addHandler(LoggingHandler(level=logging.INFO, logger_provider=logs)) traces = TracerProvider(resource=resource) traces.add_span_processor(BatchSpanProcessor(OTLPSpanExporter())) trace.set_tracer_provider(traces) log = logging.getLogger("facturation") tracer = trace.get_tracer("tp.facturation") for n in range(20): with tracer.start_as_current_span("emettre facture"): log.info("facture émise", extra={"shop.invoice.id": f"F-{n}", "shop.invoice.amount": random.randint(10, 900)}) if n % 5 == 0: log.error("échec d'envoi au client", extra={"shop.invoice.id": f"F-{n}"}) time.sleep(0.2) logs.shutdown() ; traces.shutdown() EOF python facturation.py3. Consultar y correlacionar en Grafana
¿Por qué? El trace_id que lleva cada log permite pasar del log a la traza y viceversa.
En Explore > Loki, muestra los errores del servicio, despliega una línea y localizatrace_id,span_id, la severidad y tus atributos. Abre la traza vinculada y, desde un span de Tempo, muestra sus logs.Ver la corrección
{service_name="facturation"} | severity_text="ERROR" {service_name="facturation"} | shop_invoice_id="F-10" sum by (severity_text) (count_over_time({service_name="facturation"}[5m]))4. Recoger los logs de una aplicación heredada
¿Por qué? Sin tocar el código, el receiver filelog lee los archivos y analiza el JSON, la severidad y el contexto de traza.
Genera un archivo de logs JSON y lanza un Collector contrib en la misma red que la pila, confilelog,json_parser,trace_parsery un procesadorresourceque fijeservice.name.Ver la corrección
mkdir -p logs for i in $(seq 1 30); do lvl=$([ $((i % 6)) -eq 0 ] && echo ERROR || echo INFO) printf '{"time":"%s","level":"%s","message":"traitement lot %d","trace_id":"%s","span_id":"%s"}\n' \ "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$lvl" "$i" "$(openssl rand -hex 16)" "$(openssl rand -hex 8)" >> logs/app.log done cat > collector.yaml <<'EOF' receivers: filelog: include: [/logs/app.log] start_at: beginning operators: - type: json_parser severity: { parse_from: attributes.level } - type: trace_parser trace_id: { parse_from: attributes.trace_id } span_id: { parse_from: attributes.span_id } - type: move from: attributes.message to: body processors: resource: attributes: [{ key: service.name, value: facturation-historique, action: upsert }] batch: {} exporters: otlphttp: { endpoint: http://lgtm:4318 } service: pipelines: logs: { receivers: [filelog], processors: [resource, batch], exporters: [otlphttp] } EOF docker network create otel 2>/dev/null ; docker network connect otel lgtm docker run -d --name col-logs --network otel -v "$PWD/collector.yaml:/etc/otelcol-contrib/config.yaml" -v "$PWD/logs:/logs" otel/opentelemetry-collector-contrib:latest # Loki : {service_name="facturation-historique"} | severity_text="ERROR"5. Reducir y enmascarar
¿Por qué? El Collector elimina el ruido y los datos personales antes del almacenamiento.
Añade un procesadorfilterque elimine los logs INFO y untransformque enmascare las direcciones de correo en el cuerpo y compruébalo en Loki.Ver la corrección
processors: filter/info: logs: log_record: ['severity_number < SEVERITY_NUMBER_WARN'] transform/pii: log_statements: - context: log statements: - replace_pattern(body, "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+", "***@***") # pipeline : processors: [resource, filter/info, transform/pii, batch] # docker restart col-logs, puis nettoyage : docker rm -f col-logs
Nivel de dificultad : ●●●○○ (3/5)
Mi seguimiento
Inicia sesión para seguir tu progreso y tomar notas. Iniciar sesión
Artículos recomendados
Les logs avec OpenTelemetry : modèle de données, appenders, corrélation et collecte
Maîtriser le signal log : modèle de données LogRecord, Logs Bridge API et appenders (Logback, Log...
Grafana Alloy: Perfilado Continuo con Pyroscope
Descubra cómo configurar el perfilado continuo (Continuous Profiling) en sus entornos utilizando ...