Files
Aleksei Sokol 53f14a8624
All checks were successful
Run linters on applied template / Python 3.13 lint and build (push) Successful in 1m40s
Version 0.4.0
Changes:
- put ObservabilityMiddleware before ExceptionHandlerMiddleware to avoid repetative code
- add application startup and last metrics update metrics along with CPU usage metric and threads count
- move host and port to new uvicorn section at config along with new reload and forwarded_allow_ips
- add request_id and remove trace_id/span_id generation if tracing is disabled
- move logging logic from utils to observability
- pass trace_id/span_id in HEX form
2026-01-03 16:29:58 +03:00

52 lines
2.1 KiB
Django/Jinja

"""Open Telemetry agent initialization is defined here"""
import platform
from functools import cache
from opentelemetry import metrics, trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.prometheus import PrometheusMetricReader
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.resources import SERVICE_INSTANCE_ID, SERVICE_NAME, SERVICE_VERSION, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from {{project_slug}}.config import JaegerConfig, PrometheusConfig
from {{project_slug}}.version import VERSION as APP_VERSION
from .metrics_server import PrometheusServer
@cache
def get_resource() -> Resource:
return Resource.create(
attributes={SERVICE_NAME: "{{project_slug}}", SERVICE_VERSION: APP_VERSION, SERVICE_INSTANCE_ID: platform.node()}
)
class OpenTelemetryAgent: # pylint: disable=too-few-public-methods
def __init__(self, prometheus_config: PrometheusConfig | None, jaeger_config: JaegerConfig | None):
self._resource = get_resource()
self._prometheus: PrometheusServer | None = None
self._span_exporter: OTLPSpanExporter | None = None
if prometheus_config is not None:
self._prometheus = PrometheusServer(port=prometheus_config.port, host=prometheus_config.host)
reader = PrometheusMetricReader()
provider = MeterProvider(resource=self._resource, metric_readers=[reader])
metrics.set_meter_provider(provider)
if jaeger_config is not None:
self._span_exporter = OTLPSpanExporter(endpoint=jaeger_config.endpoint)
tracer_provider = TracerProvider(resource=self._resource)
processor = BatchSpanProcessor(span_exporter=self._span_exporter)
tracer_provider.add_span_processor(processor)
trace.set_tracer_provider(tracer_provider)
def shutdown(self) -> None:
"""Stop metrics and tracing services if they were started."""
if self._prometheus is not None:
self._prometheus.shutdown()