Skip to content

Commit db532be

Browse files
committed
fix(telemetry): fix CI failures after rebase onto main
- Restore set_logging_format=True in LoggingInstrumentorWrapper - Update test_exception_returns_none to force the else path so the exception in _create_log_exporter is actually reached - Update clashing-provider test to assert against external_exporter — we no longer add a second processor to the platform LP - Update subaccount_id attribute key after rename on main - Clean up what-comments, keep only the non-obvious why
1 parent 9853613 commit db532be

4 files changed

Lines changed: 11 additions & 27 deletions

File tree

src/sap_cloud_sdk/core/telemetry/_provider.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,7 @@
5050
def _merge_sdk_resource_into_log_provider(
5151
provider: LoggerProvider, sdk_resource: Resource
5252
) -> None:
53-
"""Mutate provider._resource and update all active Logger instances.
54-
55-
Mirrors the TracerProvider resource merge in auto_instrument.py —
56-
OTel SDK exposes no public API to swap a LoggerProvider's Resource
57-
post-construction.
58-
"""
53+
"""OTel SDK has no public API to swap a LoggerProvider's Resource after construction."""
5954
provider._resource = provider.resource.merge(sdk_resource)
6055
with provider._active_loggers_lock:
6156
for logger_instance in provider._active_loggers:
@@ -66,9 +61,7 @@ def _merge_sdk_resource_into_log_provider(
6661

6762

6863
def _root_logger_has_otel_handler() -> bool:
69-
# The platform's sitecustomize.py (OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED)
70-
# installs opentelemetry.sdk._logs.LoggingHandler, which is a different class from
71-
# opentelemetry.instrumentation.logging.handler.LoggingHandler. Check both.
64+
# sitecustomize.py installs sdk._logs.LoggingHandler, not the instrumentation-layer one — check both.
7265
try:
7366
from opentelemetry.sdk._logs import LoggingHandler as _SDKLoggingHandler
7467

@@ -142,18 +135,14 @@ def setup_log_provider() -> Optional[LoggerProvider]:
142135
existing = cast(LoggerProvider, get_logger_provider())
143136

144137
if isinstance(existing, LoggerProvider):
145-
# Platform's auto-instrumentation pre-installed a provider.
146-
# Merge SDK resource attrs into it so all records carry sap.cloud_sdk.*.
147-
# Never add a second BatchLogRecordProcessor here — the platform's provider
138+
# Never add a second BatchLogRecordProcessor — the platform's provider
148139
# already has one, and a second processor doubles every exported log record.
149140
logger.warning(
150141
"Global LoggerProvider was already set by another library. "
151142
"Merging sap.cloud_sdk.* resource attributes into the existing provider."
152143
)
153144
_merge_sdk_resource_into_log_provider(existing, resource)
154145
if not _root_logger_has_otel_handler():
155-
# No stdlib bridge handler yet — add one so log records reach the
156-
# platform's existing processor. No extra processor needed.
157146
logging.getLogger().addHandler(LoggingHandler(logger_provider=existing))
158147
_log_provider = existing
159148
else:

src/sap_cloud_sdk/core/telemetry/instrumentation/instrumentors/logging.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
def _has_otel_handler_on_root() -> bool:
15-
"""Return True if any OTel log bridge handler is already on the root logger."""
15+
# sitecustomize.py installs sdk._logs.LoggingHandler, not the instrumentation-layer one — check both.
1616
try:
1717
from opentelemetry.sdk._logs import LoggingHandler as _SDKHandler
1818

@@ -33,12 +33,9 @@ def is_instrumented(self) -> bool:
3333
return _instrumentor.is_instrumented_by_opentelemetry
3434

3535
def _instrument(self, **kwargs) -> None:
36+
kwargs.setdefault("set_logging_format", True)
3637
if _has_otel_handler_on_root():
37-
# An OTel log bridge handler is already on root (from platform
38-
# auto-instrumentation or setup_log_provider). Pass
39-
# enable_log_auto_instrumentation=False so LoggingInstrumentor
40-
# only injects trace context into stdlib log records — it must
41-
# not add a second handler that would duplicate every log record.
38+
# Already have a handler — adding another duplicates every log record.
4239
kwargs = {**kwargs, "enable_log_auto_instrumentation": False}
4340
_instrumentor.instrument(**kwargs)
4441

tests/core/unit/telemetry/test_log_provider_e2e.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def test_resource_attributes_on_record(self, log_exporter):
118118
assert attrs.get("service.name") == "test-svc"
119119
assert attrs.get("sap.cloud_sdk.language") == "python"
120120
assert attrs.get("cloud.region") == "eu10"
121-
assert attrs.get("sap.cld.subaccount_id") == "sub-123"
121+
assert attrs.get("sap.cloud.provider.subaccount_id") == "sub-123"
122122

123123
def test_extra_fields_become_log_attributes(self, log_exporter):
124124
logging.getLogger("test.extra").warning(
@@ -196,7 +196,7 @@ def test_logs_reach_our_exporter_when_provider_already_set(self, monkeypatch):
196196
root.setLevel(logging.DEBUG)
197197
logging.getLogger("test.clash").warning("hello from sdk")
198198

199-
our_records = our_exporter.get_finished_logs()
199+
our_records = external_exporter.get_finished_logs()
200200
assert len(our_records) == 1
201201
assert our_records[0].log_record.body == "hello from sdk"
202202

tests/core/unit/telemetry/test_provider.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,9 @@ def test_normal_path_installs_handler_on_root_logger(self):
293293
def test_exception_returns_none(self):
294294
with patch("sap_cloud_sdk.core.telemetry._provider.get_config", return_value=_ENABLED_CONFIG):
295295
with patch("sap_cloud_sdk.core.telemetry._provider.Resource"):
296-
with patch("sap_cloud_sdk.core.telemetry._provider._create_log_exporter", side_effect=Exception("boom")):
297-
assert setup_log_provider() is None
296+
with patch("sap_cloud_sdk.core.telemetry._provider.get_logger_provider", return_value=MagicMock()):
297+
with patch("sap_cloud_sdk.core.telemetry._provider._create_log_exporter", side_effect=Exception("boom")):
298+
assert setup_log_provider() is None
298299

299300
def test_platform_path_merges_resource_no_extra_handler(self):
300301
"""Platform pre-installed provider with a handler — merge resource, add nothing."""
@@ -323,7 +324,6 @@ def test_platform_path_adds_handler_when_none_present(self):
323324
with patch(_LOGGING_HANDLER) as mock_handler_cls:
324325
with patch("logging.getLogger"):
325326
setup_log_provider()
326-
# No second processor — platform LP already has one
327327
external.add_log_record_processor.assert_not_called()
328328
mock_handler_cls.assert_called_once_with(logger_provider=external)
329329

@@ -389,8 +389,6 @@ def test_returns_true_when_handler_present(self):
389389
root.handlers = original
390390

391391
def test_returns_true_when_sdk_level_handler_present(self):
392-
"""Platform sitecustomize.py uses opentelemetry.sdk._logs.LoggingHandler, not the
393-
instrumentation-layer one. _root_logger_has_otel_handler must detect both."""
394392
from opentelemetry.sdk._logs import LoggingHandler as SDKHandler
395393
root = logging.getLogger()
396394
original = root.handlers[:]

0 commit comments

Comments
 (0)