Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/nemo/lens/logging_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,13 @@ def setup_logging_bridge(logger_name: str = "", level: int = logging.INFO) -> No
if not isinstance(logger_provider, LoggerProvider):
return

logger = logging.getLogger(logger_name)
if any(isinstance(h, LoggingHandler) for h in logger.handlers):
return

handler = LoggingHandler(logger_provider=logger_provider)
handler.setLevel(level)
logging.getLogger(logger_name).addHandler(handler)
logger.addHandler(handler)
except ImportError:
# OTel logs SDK not installed; silently skip
pass
Expand Down
30 changes: 30 additions & 0 deletions tests/test_logging_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,36 @@ def __init__(self, logger_provider):
logger.handlers.clear()


def test_setup_logging_bridge_is_idempotent(monkeypatch):
"""Verify repeated setup does not stack duplicate OTel handlers."""
logs_module = types.ModuleType("opentelemetry._logs")
sdk_logs_module = types.ModuleType("opentelemetry.sdk._logs")

class LoggerProvider:
pass

class LoggingHandler(logging.Handler):
def __init__(self, logger_provider):
super().__init__()
self.logger_provider = logger_provider

provider = LoggerProvider()
logs_module.get_logger_provider = lambda: provider
sdk_logs_module.LoggerProvider = LoggerProvider
sdk_logs_module.LoggingHandler = LoggingHandler
monkeypatch.setitem(sys.modules, logs_module.__name__, logs_module)
monkeypatch.setitem(sys.modules, sdk_logs_module.__name__, sdk_logs_module)

logger = logging.getLogger("nemo.lens.test.logging_bridge.idempotent")
logger.handlers.clear()

setup_logging_bridge(logger.name)
setup_logging_bridge(logger.name)

assert len(logger.handlers) == 1
logger.handlers.clear()


def test_setup_logging_bridge_skips_non_sdk_provider(monkeypatch):
"""Verify non-SDK logger providers are ignored without adding handlers."""
logs_module = types.ModuleType("opentelemetry._logs")
Expand Down
Loading