Skip to content

Commit dde755b

Browse files
committed
Update optional OTEL
Signed-off-by: Mihai Criveti <[email protected]>
1 parent 94611d4 commit dde755b

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

mcpgateway/observability.py

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,27 @@
99
import logging
1010
import os
1111

12-
# Third-Party
13-
from opentelemetry import trace
14-
from opentelemetry.sdk.resources import Resource
15-
from opentelemetry.sdk.trace import TracerProvider
16-
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter, SimpleSpanProcessor
17-
from opentelemetry.trace import Status, StatusCode
12+
# Try to import OpenTelemetry core components - make them truly optional
13+
OTEL_AVAILABLE = False
14+
try:
15+
# Third-Party
16+
from opentelemetry import trace
17+
from opentelemetry.sdk.resources import Resource
18+
from opentelemetry.sdk.trace import TracerProvider
19+
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter, SimpleSpanProcessor
20+
from opentelemetry.trace import Status, StatusCode
21+
22+
OTEL_AVAILABLE = True
23+
except ImportError:
24+
# OpenTelemetry not installed - set to None for graceful degradation
25+
trace = None
26+
Resource = None
27+
TracerProvider = None
28+
BatchSpanProcessor = None
29+
ConsoleSpanExporter = None
30+
SimpleSpanProcessor = None
31+
Status = None
32+
StatusCode = None
1833

1934
# Try to import optional exporters
2035
try:
@@ -73,6 +88,12 @@ def init_telemetry():
7388
logger.info("Observability disabled via OTEL_ENABLE_OBSERVABILITY=false")
7489
return None
7590

91+
# Check if OpenTelemetry is available
92+
if not OTEL_AVAILABLE:
93+
logger.warning("OpenTelemetry not installed. Telemetry features will be disabled.")
94+
logger.info("To enable telemetry, install with: pip install mcp-contextforge-gateway[observability]")
95+
return None
96+
7697
# Get exporter type from environment
7798
exporter_type = os.getenv("OTEL_TRACES_EXPORTER", "otlp").lower()
7899

@@ -223,6 +244,10 @@ def decorator(func):
223244
The wrapped function with tracing capabilities.
224245
"""
225246

247+
# If OpenTelemetry is not available, return the function unchanged
248+
if not OTEL_AVAILABLE:
249+
return func
250+
226251
async def wrapper(*args, **kwargs):
227252
"""Async wrapper that adds tracing to the decorated function.
228253
@@ -280,8 +305,8 @@ def create_span(name: str, attributes: dict = None):
280305
# Your code here
281306
pass
282307
"""
283-
if not _TRACER:
284-
# Return a no-op context manager if tracing is not configured
308+
if not _TRACER or not OTEL_AVAILABLE:
309+
# Return a no-op context manager if tracing is not configured or available
285310
return nullcontext()
286311

287312
# Start span and return the context manager
@@ -337,12 +362,14 @@ def __exit__(self, exc_type, exc_val, exc_tb):
337362
# Record exception if one occurred
338363
if exc_type is not None and self.span:
339364
self.span.record_exception(exc_val)
340-
self.span.set_status(Status(StatusCode.ERROR, str(exc_val)))
365+
if OTEL_AVAILABLE and Status and StatusCode:
366+
self.span.set_status(Status(StatusCode.ERROR, str(exc_val)))
341367
self.span.set_attribute("error", True)
342368
self.span.set_attribute("error.type", exc_type.__name__)
343369
self.span.set_attribute("error.message", str(exc_val))
344370
elif self.span:
345-
self.span.set_status(Status(StatusCode.OK))
371+
if OTEL_AVAILABLE and Status and StatusCode:
372+
self.span.set_status(Status(StatusCode.OK))
346373
return self.span_context.__exit__(exc_type, exc_val, exc_tb)
347374

348375
return SpanWithAttributes(span_context, attributes)

0 commit comments

Comments
 (0)