""" ═══════════════════════════════════════════════════════════ 🔭 OpenTelemetry Tracing Setup for Ophion ═══════════════════════════════════════════════════════════ This module initializes OpenTelemetry tracing and sends spans to Ophion's OTLP HTTP endpoint. Usage: from tracing import init_tracing, get_tracer init_tracing() tracer = get_tracer() """ import os from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.resources import Resource, SERVICE_NAME, SERVICE_VERSION, DEPLOYMENT_ENVIRONMENT # Global tracer _tracer = None def init_tracing(service_name: str = None) -> None: """ Initialize OpenTelemetry tracing with OTLP HTTP exporter. Args: service_name: Name of the service (default: from env or 'python-example') """ global _tracer # Get configuration from environment otlp_endpoint = os.getenv('OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:8080') service = service_name or os.getenv('OTEL_SERVICE_NAME', 'python-example') environment = os.getenv('DEPLOYMENT_ENVIRONMENT', 'development') # Create resource with service info resource = Resource.create({ SERVICE_NAME: service, SERVICE_VERSION: '1.0.0', DEPLOYMENT_ENVIRONMENT: environment, }) # Create tracer provider provider = TracerProvider(resource=resource) # Configure OTLP HTTP exporter # Note: endpoint should be base URL, SDK adds /v1/traces exporter = OTLPSpanExporter( endpoint=f"{otlp_endpoint}/v1/traces", # headers={"Authorization": f"Bearer {os.getenv('OPHION_API_KEY', '')}"}, ) # Add batch processor for efficient sending processor = BatchSpanProcessor(exporter) provider.add_span_processor(processor) # Set as global tracer provider trace.set_tracer_provider(provider) # Create tracer _tracer = trace.get_tracer(__name__) print(f"🔭 OpenTelemetry tracing initialized") print(f" Service: {service}") print(f" Endpoint: {otlp_endpoint}/v1/traces") def get_tracer(): """Get the initialized tracer.""" global _tracer if _tracer is None: init_tracing() return _tracer def shutdown(): """Gracefully shutdown the tracer provider.""" provider = trace.get_tracer_provider() if hasattr(provider, 'shutdown'): provider.shutdown()