- Add POST /v1/traces endpoint for OTLP JSON trace ingestion - Convert OTLP spans to internal format and save to PostgreSQL - Manual JSON parsing (no Go 1.24 dependencies) - Add Node.js instrumentation example with Express - Add Python instrumentation example with Flask - Auto-instrumentation support for both languages
85 lines
2.7 KiB
Python
85 lines
2.7 KiB
Python
"""
|
|
═══════════════════════════════════════════════════════════
|
|
🔭 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()
|