64 lines
2.8 KiB
Python
64 lines
2.8 KiB
Python
"""OTel initialization — called at app startup (U1: OTel now required)."""
|
||
|
||
import logging
|
||
|
||
from opentelemetry import trace, metrics
|
||
from opentelemetry.sdk.trace import TracerProvider
|
||
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
||
from opentelemetry.sdk.metrics import MeterProvider
|
||
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
|
||
from opentelemetry.sdk.resources import Resource
|
||
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
||
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
|
||
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
def setup_telemetry(app, config: dict | None = None):
|
||
"""Initialize OpenTelemetry if configured.
|
||
|
||
U1: opentelemetry-* deps now required (pyproject.toml). ImportError
|
||
fallbacks removed — a missing package is a hard install error. The
|
||
`enabled=False` config switch remains the supported way to disable.
|
||
|
||
Args:
|
||
app: FastAPI application instance
|
||
config: Telemetry configuration dict with keys:
|
||
- enabled (bool): Whether to enable telemetry
|
||
- service_name (str): Service name for OTel resource
|
||
- otlp_endpoint (str): OTLP gRPC endpoint URL
|
||
- export_traces (bool): Whether to export traces
|
||
- export_metrics (bool): Whether to export metrics
|
||
"""
|
||
if not config or not config.get("enabled", False):
|
||
logger.info("Telemetry disabled")
|
||
return
|
||
|
||
service_name = config.get("service_name", "fischer-agentkit")
|
||
resource = Resource.create({"service.name": service_name})
|
||
|
||
# Tracing setup
|
||
if config.get("export_traces", True):
|
||
endpoint = config.get("otlp_endpoint", "http://localhost:4317")
|
||
provider = TracerProvider(resource=resource)
|
||
provider.add_span_processor(
|
||
BatchSpanProcessor(OTLPSpanExporter(endpoint=endpoint, insecure=True))
|
||
)
|
||
trace.set_tracer_provider(provider)
|
||
logger.info(f"Tracing enabled, exporting to {endpoint}")
|
||
|
||
# Metrics setup
|
||
if config.get("export_metrics", True):
|
||
endpoint = config.get("otlp_endpoint", "http://localhost:4317")
|
||
reader = PeriodicExportingMetricReader(OTLPMetricExporter(endpoint=endpoint, insecure=True))
|
||
# ponytail: OTel SDK 1.16+ 将 readers kwarg 改名为 metric_readers;
|
||
# 旧代码用 readers=[...] 是已存在 bug,被 ImportError fallback 掩盖。
|
||
provider = MeterProvider(resource=resource, metric_readers=[reader])
|
||
metrics.set_meter_provider(provider)
|
||
logger.info(f"Metrics enabled, exporting to {endpoint}")
|
||
|
||
# FastAPI auto-instrumentation
|
||
FastAPIInstrumentor.instrument_app(app, excluded_urls="health,metrics")
|
||
logger.info("FastAPI auto-instrumentation enabled")
|