feat: Add OpenTelemetry OTLP HTTP receiver
- 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
This commit is contained in:
84
examples/otel-python/tracing.py
Normal file
84
examples/otel-python/tracing.py
Normal file
@@ -0,0 +1,84 @@
|
||||
"""
|
||||
═══════════════════════════════════════════════════════════
|
||||
🔭 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()
|
||||
Reference in New Issue
Block a user