learn-grafana/main.py
Waylon S. Walker 774ea44af1 wip
2025-05-23 10:24:41 -05:00

85 lines
2.8 KiB
Python

import time
import random
from flask import Flask
from opentelemetry import trace, metrics
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
import logging
from opentelemetry.trace import get_current_span
# === Resource ===
resource = Resource(attributes={"service.name": "my-flask-app"})
# === Tracing ===
trace.set_tracer_provider(TracerProvider(resource=resource))
tracer = trace.get_tracer(__name__)
# trace_exporter = OTLPSpanExporter(
# endpoint="http://otel-collector.meta.svc:4318/v1/traces"
# )
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(trace_exporter))
# === Metrics ===
reader = PeriodicExportingMetricReader(
OTLPMetricExporter(endpoint="http://otel-collector.meta.svc:4318/v1/metrics")
)
provider = MeterProvider(resource=resource, metric_readers=[reader])
metrics.set_meter_provider(provider)
# === Logging with trace ID ===
class TraceIdFilter(logging.Filter):
def filter(self, record):
span = trace.get_current_span()
ctx = span.get_span_context()
record.trace_id = format(ctx.trace_id, "032x") if ctx.trace_id != 0 else None
record.span_id = format(ctx.span_id, "016x") if ctx.span_id != 0 else 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)
# === Flask App ===
app = Flask(__name__)
# FlaskInstrumentor().instrument_app(app) # auto-instruments metrics + traces
@app.route("/")
def root():
with tracer.start_as_current_span("handle_homepage"):
logger.info(
"handling request",
extra={"trace_id": get_current_span().get_span_context().trace_id},
)
time.sleep(random.random() * 0.05) # simulate request parsing
fetch_user()
calculate_recommendations()
return "Hello from / with traces and metrics!"
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)