Skip to content

Commit b329d55

Browse files
authored
Only set OTLP providers when exporter endpoints are set (#497)
This PR makes sure DBOS only sets the global OTLP tracer/logger providers if OTLP exporter endpoints are provided. The change is necessary if users are using other providers like Logfire, which already set up the exporters. Otherwise, setting providers again would generate warnings.
1 parent a367039 commit b329d55

File tree

4 files changed

+49
-41
lines changed

4 files changed

+49
-41
lines changed

dbos/_logger.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,30 +68,37 @@ def config_logger(config: "ConfigFile") -> None:
6868
)
6969
disable_otlp = config.get("telemetry", {}).get("disable_otlp", False) # type: ignore
7070

71-
if not disable_otlp and otlp_logs_endpoints:
71+
if not disable_otlp:
7272

73-
from opentelemetry._logs import set_logger_provider
73+
from opentelemetry._logs import get_logger_provider, set_logger_provider
7474
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
7575
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
7676
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
7777
from opentelemetry.sdk.resources import Resource
7878
from opentelemetry.semconv.attributes.service_attributes import SERVICE_NAME
7979

80-
log_provider = LoggerProvider(
81-
Resource.create(
82-
attributes={
83-
SERVICE_NAME: config["name"],
84-
}
85-
)
86-
)
87-
set_logger_provider(log_provider)
88-
for e in otlp_logs_endpoints:
89-
log_provider.add_log_record_processor(
90-
BatchLogRecordProcessor(
91-
OTLPLogExporter(endpoint=e),
92-
export_timeout_millis=5000,
80+
# Only set up OTLP provider and exporter if endpoints are provided
81+
log_provider = get_logger_provider()
82+
if otlp_logs_endpoints is not None:
83+
if not isinstance(log_provider, LoggerProvider):
84+
log_provider = LoggerProvider(
85+
Resource.create(
86+
attributes={
87+
SERVICE_NAME: config["name"],
88+
}
89+
)
90+
)
91+
set_logger_provider(log_provider)
92+
93+
for e in otlp_logs_endpoints:
94+
log_provider.add_log_record_processor(
95+
BatchLogRecordProcessor(
96+
OTLPLogExporter(endpoint=e),
97+
export_timeout_millis=5000,
98+
)
9399
)
94-
)
100+
101+
# Even if no endpoints are provided, we still need a LoggerProvider to create the LoggingHandler
95102
global _otlp_handler
96103
_otlp_handler = LoggingHandler(logger_provider=log_provider)
97104

dbos/_tracer.py

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def __init__(self) -> None:
2525
def config(self, config: ConfigFile) -> None:
2626
self.otlp_attributes = config.get("telemetry", {}).get("otlp_attributes", {}) # type: ignore
2727
self.disable_otlp = config.get("telemetry", {}).get("disable_otlp", False) # type: ignore
28+
otlp_traces_endpoints = (
29+
config.get("telemetry", {}).get("OTLPExporter", {}).get("tracesEndpoint") # type: ignore
30+
)
31+
2832
if not self.disable_otlp:
2933
from opentelemetry import trace
3034
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
@@ -38,25 +42,26 @@ def config(self, config: ConfigFile) -> None:
3842
)
3943
from opentelemetry.semconv.attributes.service_attributes import SERVICE_NAME
4044

41-
if not isinstance(trace.get_tracer_provider(), TracerProvider):
42-
resource = Resource(
43-
attributes={
44-
SERVICE_NAME: config["name"],
45-
}
46-
)
47-
48-
provider = TracerProvider(resource=resource)
49-
if os.environ.get("DBOS__CONSOLE_TRACES", None) is not None:
50-
processor = BatchSpanProcessor(ConsoleSpanExporter())
51-
provider.add_span_processor(processor)
52-
otlp_traces_endpoints = (
53-
config.get("telemetry", {}).get("OTLPExporter", {}).get("tracesEndpoint") # type: ignore
54-
)
55-
if otlp_traces_endpoints:
56-
for e in otlp_traces_endpoints:
57-
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint=e))
58-
provider.add_span_processor(processor)
59-
trace.set_tracer_provider(provider)
45+
tracer_provider = trace.get_tracer_provider()
46+
47+
# Only set up OTLP provider and exporter if endpoints are provided
48+
if otlp_traces_endpoints is not None:
49+
if not isinstance(tracer_provider, TracerProvider):
50+
resource = Resource(
51+
attributes={
52+
SERVICE_NAME: config["name"],
53+
}
54+
)
55+
56+
tracer_provider = TracerProvider(resource=resource)
57+
if os.environ.get("DBOS__CONSOLE_TRACES", None) is not None:
58+
processor = BatchSpanProcessor(ConsoleSpanExporter())
59+
tracer_provider.add_span_processor(processor)
60+
trace.set_tracer_provider(tracer_provider)
61+
62+
for e in otlp_traces_endpoints:
63+
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint=e))
64+
tracer_provider.add_span_processor(processor)
6065

6166
def set_provider(self, provider: "Optional[TracerProvider]") -> None:
6267
self.provider = provider

tests/test_queue.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ def parent(child_one: str, child_two: str) -> None:
14761476
queue.enqueue(child)
14771477

14781478
child_one, child_two = str(uuid.uuid4()), str(uuid.uuid4())
1479-
with SetWorkflowTimeout(1.0):
1479+
with SetWorkflowTimeout(2.0):
14801480
queue.enqueue(parent, child_one, child_two).get_result()
14811481

14821482
# Verify child one, which has a propagated timeout, is cancelled

tests/test_spans.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from fastapi import FastAPI
66
from fastapi.testclient import TestClient
77
from inline_snapshot import snapshot
8-
from opentelemetry._logs import set_logger_provider
98
from opentelemetry.sdk import trace as tracesdk
109
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
1110
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, InMemoryLogExporter
@@ -17,6 +16,7 @@
1716
from dbos._logger import dbos_logger
1817
from dbos._tracer import dbos_tracer
1918
from dbos._utils import GlobalParams
19+
from tests.conftest import default_config
2020

2121

2222
@dataclass
@@ -65,7 +65,6 @@ def test_step() -> None:
6565
log_processor = BatchLogRecordProcessor(log_exporter)
6666
log_provider = LoggerProvider()
6767
log_provider.add_log_record_processor(log_processor)
68-
set_logger_provider(log_provider)
6968
dbos_logger.addHandler(LoggingHandler(logger_provider=log_provider))
7069

7170
test_workflow()
@@ -192,7 +191,6 @@ async def test_step() -> None:
192191
log_processor = BatchLogRecordProcessor(log_exporter)
193192
log_provider = LoggerProvider()
194193
log_provider.add_log_record_processor(log_processor)
195-
set_logger_provider(log_provider)
196194
dbos_logger.addHandler(LoggingHandler(logger_provider=log_provider))
197195

198196
await test_workflow()
@@ -303,7 +301,6 @@ def test_workflow_endpoint() -> str:
303301
log_processor = BatchLogRecordProcessor(log_exporter)
304302
log_provider = LoggerProvider()
305303
log_provider.add_log_record_processor(log_processor)
306-
set_logger_provider(log_provider)
307304
dbos_logger.addHandler(LoggingHandler(logger_provider=log_provider))
308305

309306
client = TestClient(app)
@@ -378,7 +375,6 @@ def test_step() -> None:
378375
log_processor = BatchLogRecordProcessor(log_exporter)
379376
log_provider = LoggerProvider()
380377
log_provider.add_log_record_processor(log_processor)
381-
set_logger_provider(log_provider)
382378
dbos_logger.addHandler(LoggingHandler(logger_provider=log_provider))
383379

384380
test_workflow()

0 commit comments

Comments
 (0)