Push the rest

This commit is contained in:
2026-05-11 10:58:46 +02:00
parent adb5c1a439
commit 0031caf16c
94 changed files with 11777 additions and 3474 deletions

View File

@@ -7,24 +7,27 @@ from typing import Any
from fastapi import FastAPI
from opentelemetry import metrics, trace
from opentelemetry.baggage.propagation import W3CBaggagePropagator
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
from opentelemetry.instrumentation.logging import LoggingInstrumentor
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
from opentelemetry.propagate import set_global_textmap
from opentelemetry.propagators.composite import CompositePropagator
from opentelemetry.sdk._logs import LoggerProvider
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from opentelemetry._logs import set_logger_provider
try:
from opentelemetry.instrumentation.system_metrics import SystemMetricsInstrumentor
except ImportError: # pragma: no cover - defensive fallback for minimal envs
except ImportError:
SystemMetricsInstrumentor = None # type: ignore[assignment]
from app.core.config import Settings
@@ -36,12 +39,14 @@ LOGGER = logging.getLogger(__name__)
class TelemetryProviders:
tracer_provider: TracerProvider
meter_provider: MeterProvider
logger_provider: LoggerProvider
def configure_otel(settings: Settings) -> TelemetryProviders:
set_global_textmap(
CompositePropagator([TraceContextTextMapPropagator(), W3CBaggagePropagator()])
)
resource = Resource.create(
{
"service.name": settings.otel_service_name,
@@ -50,34 +55,54 @@ def configure_otel(settings: Settings) -> TelemetryProviders:
}
)
trace_exporter = OTLPSpanExporter(
endpoint=f"{settings.otel_collector_endpoint}/v1/traces",
timeout=settings.otel_export_timeout_ms / 1000,
)
tracer_provider = TracerProvider(resource=resource)
tracer_provider.add_span_processor(BatchSpanProcessor(trace_exporter))
tracer_provider.add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(
endpoint=f"{settings.otel_collector_endpoint}/v1/traces",
timeout=settings.otel_export_timeout_ms / 1000,
)
)
)
trace.set_tracer_provider(tracer_provider)
metric_reader = PeriodicExportingMetricReader(
exporter=OTLPMetricExporter(
endpoint=f"{settings.otel_collector_endpoint}/v1/metrics",
timeout=settings.otel_export_timeout_ms / 1000,
),
export_interval_millis=10000,
meter_provider = MeterProvider(
resource=resource,
metric_readers=[
PeriodicExportingMetricReader(
exporter=OTLPMetricExporter(
endpoint=f"{settings.otel_collector_endpoint}/v1/metrics",
timeout=settings.otel_export_timeout_ms / 1000,
),
export_interval_millis=10_000,
)
],
)
meter_provider = MeterProvider(resource=resource, metric_readers=[metric_reader])
metrics.set_meter_provider(meter_provider)
logger_provider = LoggerProvider(resource=resource)
logger_provider.add_log_record_processor(
BatchLogRecordProcessor(
OTLPLogExporter(
endpoint=f"{settings.otel_collector_endpoint}/v1/logs",
timeout=settings.otel_export_timeout_ms / 1000,
)
)
)
set_logger_provider(logger_provider)
LoggingInstrumentor().instrument(set_logging_format=True)
if SystemMetricsInstrumentor is not None:
SystemMetricsInstrumentor().instrument()
else:
LOGGER.warning(
"System metrics instrumentor not available, runtime host metrics disabled."
)
LOGGER.info("OpenTelemetry providers configured")
LOGGER.warning("SystemMetricsInstrumentor not available — skipping.")
LOGGER.info("OTel providers configured", extra={"service.name": settings.otel_service_name})
return TelemetryProviders(
tracer_provider=tracer_provider, meter_provider=meter_provider
tracer_provider=tracer_provider,
meter_provider=meter_provider,
logger_provider=logger_provider,
)
@@ -85,19 +110,15 @@ def instrument_fastapi(app: FastAPI) -> None:
FastAPIInstrumentor.instrument_app(app)
def instrument_sqlalchemy_engines(engines: dict[str, Any]) -> None:
def instrument_sqlalchemy(engines: dict[str, Any]) -> None:
for engine in engines.values():
SQLAlchemyInstrumentor().instrument(engine=engine)
def instrument_httpx_clients() -> None:
HTTPXClientInstrumentor().instrument()
def shutdown_otel(providers: TelemetryProviders) -> None:
HTTPXClientInstrumentor().uninstrument()
if SystemMetricsInstrumentor is not None:
SystemMetricsInstrumentor().uninstrument()
LoggingInstrumentor().uninstrument()
providers.meter_provider.shutdown()
providers.tracer_provider.shutdown()
providers.logger_provider.shutdown()