From d6e8dc263ea6c70d16e366f0951295354cb16f38 Mon Sep 17 00:00:00 2001 From: Leonidas Spyropoulos <artafinde@archlinux.org> Date: Mon, 17 Mar 2025 09:38:59 +0000 Subject: [PATCH] feat: optionally enable opentelemetry based on config Local spawning of the service fails with OpenTelemetry enabled, only enable if config is set Relates: b730f6447d78d4d1b3b70a8524c60fa8884be05f Signed-off-by: Leonidas Spyropoulos <artafinde@archlinux.org> --- aurweb/asgi.py | 31 ++++++++++++++++--------------- aurweb/aur_redis.py | 6 ++++-- aurweb/db.py | 12 ++++++++---- test/setup.sh | 3 +++ 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/aurweb/asgi.py b/aurweb/asgi.py index 4a0c11132..6702ca43e 100644 --- a/aurweb/asgi.py +++ b/aurweb/asgi.py @@ -14,12 +14,6 @@ from fastapi import FastAPI, HTTPException, Request, Response from fastapi.responses import RedirectResponse from fastapi.staticfiles import StaticFiles from jinja2 import TemplateNotFound -from opentelemetry import trace -from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter -from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor -from opentelemetry.sdk.resources import Resource -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.sdk.trace.export import BatchSpanProcessor from sqlalchemy import and_ from starlette.exceptions import HTTPException as StarletteHTTPException from starlette.middleware.authentication import AuthenticationMiddleware @@ -51,7 +45,6 @@ async def lifespan(app: FastAPI): # Setup the FastAPI app. app = FastAPI(lifespan=lifespan) - # Instrument routes with the prometheus-fastapi-instrumentator # library with custom collectors and expose /metrics. instrumentator().add(prometheus.http_api_requests_total()) @@ -59,15 +52,23 @@ instrumentator().add(prometheus.http_requests_total()) instrumentator().instrument(app) -# Instrument FastAPI for tracing -FastAPIInstrumentor.instrument_app(app) +if aurweb.config.get("tracing", "otlp_endpoint"): + from opentelemetry import trace + from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter + from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor + from opentelemetry.sdk.resources import Resource + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import BatchSpanProcessor + + # Instrument FastAPI for tracing + FastAPIInstrumentor.instrument_app(app) -resource = Resource(attributes={"service.name": "aurweb"}) -otlp_endpoint = aurweb.config.get("tracing", "otlp_endpoint") -otlp_exporter = OTLPSpanExporter(endpoint=otlp_endpoint) -span_processor = BatchSpanProcessor(otlp_exporter) -trace.set_tracer_provider(TracerProvider(resource=resource)) -trace.get_tracer_provider().add_span_processor(span_processor) + resource = Resource(attributes={"service.name": "aurweb"}) + otlp_endpoint = aurweb.config.get("tracing", "otlp_endpoint") + otlp_exporter = OTLPSpanExporter(endpoint=otlp_endpoint) + span_processor = BatchSpanProcessor(otlp_exporter) + trace.set_tracer_provider(TracerProvider(resource=resource)) + trace.get_tracer_provider().add_span_processor(span_processor) async def app_startup(): diff --git a/aurweb/aur_redis.py b/aurweb/aur_redis.py index b735bb84d..55a059437 100644 --- a/aurweb/aur_redis.py +++ b/aurweb/aur_redis.py @@ -1,5 +1,4 @@ import fakeredis -from opentelemetry.instrumentation.redis import RedisInstrumentor from redis import ConnectionPool, Redis import aurweb.config @@ -8,7 +7,10 @@ from aurweb import aur_logging logger = aur_logging.get_logger(__name__) pool = None -RedisInstrumentor().instrument() +if aurweb.config.get("tracing", "otlp_endpoint"): + from opentelemetry.instrumentation.redis import RedisInstrumentor + + RedisInstrumentor().instrument() class FakeConnectionPool: diff --git a/aurweb/db.py b/aurweb/db.py index f1b8210f0..030d940a9 100644 --- a/aurweb/db.py +++ b/aurweb/db.py @@ -298,12 +298,16 @@ def get_engine(dbname: str = None, echo: bool = False): connect_args["check_same_thread"] = False kwargs = {"echo": echo, "connect_args": connect_args} - from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor from sqlalchemy import create_engine - engine = create_engine(get_sqlalchemy_url(), **kwargs) - SQLAlchemyInstrumentor().instrument(engine=engine) - _engines[dbname] = engine + if aurweb.config.get("tracing", "otlp_endpoint"): + from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor + + engine = create_engine(get_sqlalchemy_url(), **kwargs) + SQLAlchemyInstrumentor().instrument(engine=engine) + _engines[dbname] = engine + else: + _engines[dbname] = create_engine(get_sqlalchemy_url(), **kwargs) if is_sqlite: # pragma: no cover setup_sqlite(_engines.get(dbname)) diff --git a/test/setup.sh b/test/setup.sh index 33238533f..728fc453d 100644 --- a/test/setup.sh +++ b/test/setup.sh @@ -74,6 +74,9 @@ packagesmetafile = packages-meta-v1.json.gz packagesmetaextfile = packages-meta-ext-v1.json.gz pkgbasefile = pkgbase.gz userfile = users.gz + +[tracing] +otlp_endpoint = EOF cat >sendmail.sh <<-\EOF -- GitLab