learn-grafana/main.py
Waylon S. Walker 0a4b32dffe init
2025-05-07 08:09:39 -05:00

100 lines
2.9 KiB
Python

import time
import random
from flask import Flask
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.instrumentation.flask import FlaskInstrumentor
from opentelemetry.sdk.resources import Resource
import logging
from opentelemetry.trace import get_current_span
# Configure tracing
trace.set_tracer_provider(
TracerProvider(resource=Resource.create({"service.name": "my-flask-app"}))
)
tracer = trace.get_tracer(__name__)
span_processor = BatchSpanProcessor(OTLPSpanExporter())
trace.get_tracer_provider().add_span_processor(span_processor)
# Setup logging with trace_id
class TraceIdFilter(logging.Filter):
def filter(self, record):
span = trace.get_current_span()
ctx = span.get_span_context()
if ctx.trace_id != 0:
record.trace_id = format(ctx.trace_id, "032x")
record.span_id = format(ctx.span_id, "016x")
else:
record.trace_id = None
record.span_id = None
return True
formatter = logging.Formatter(
'{"message": "%(message)s", "trace_id": "%(trace_id)s", "span_id": "%(span_id)s"}'
)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
handler.addFilter(TraceIdFilter())
logger = logging.getLogger("myapp")
logger.setLevel(logging.INFO)
logger.addHandler(handler)
# Setup Tracer
resource = Resource(
attributes={
"service.name": "python-otel-demo-app", # 👈 choose any name you like
}
)
trace.set_tracer_provider(TracerProvider(resource=resource))
tracer = trace.get_tracer(__name__)
# Configure OTLP HTTP exporter
otlp_exporter = OTLPSpanExporter(
endpoint="http://otel-collector.meta.svc:4318/v1/traces",
# insecure=True,
)
span_processor = BatchSpanProcessor(otlp_exporter)
trace.get_tracer_provider().add_span_processor(span_processor)
# Flask App
app = Flask(__name__)
FlaskInstrumentor().instrument_app(app)
def get_trace_id():
span = get_current_span()
if span:
return span.get_span_context().trace_id
return None
@app.route("/")
def root():
with tracer.start_as_current_span("handle_homepage"):
logger.info("handling request", extra={"trace_id": get_trace_id()})
time.sleep(random.random() * 0.05) # simulate request parsing
fetch_user()
calculate_recommendations()
return "Hello from / with traces!"
def fetch_user():
with tracer.start_as_current_span("fetch_user"):
time.sleep(random.random() * 0.1) # simulate DB query
def calculate_recommendations():
with tracer.start_as_current_span("calculate_recommendations"):
for i in range(2):
with tracer.start_as_current_span(f"score_item_{i}"):
time.sleep(random.random())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)