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