Skip to content

Commit c072fe3

Browse files
committed
Attributes make logger unique
1 parent 95a162b commit c072fe3

File tree

3 files changed

+69
-45
lines changed

3 files changed

+69
-45
lines changed

opentelemetry-sdk/benchmarks/logs/test_benchmark_logs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_simple_get_logger_different_names(benchmark, num_loggers):
3232
]
3333

3434
def benchmark_get_logger():
35-
for i in range(1000):
36-
loggers[i % num_loggers].warning("test message")
35+
for index in range(1000):
36+
loggers[index % num_loggers].warning("test message")
3737

3838
benchmark(benchmark_get_logger)

opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import threading
2121
import traceback
2222
import warnings
23+
from functools import lru_cache
2324
from os import environ
24-
from threading import Lock
2525
from time import time_ns
2626
from typing import Any, Callable, Optional, Tuple, Union # noqa
2727

@@ -644,13 +644,47 @@ def __init__(
644644
self._at_exit_handler = None
645645
if shutdown_on_exit:
646646
self._at_exit_handler = atexit.register(self.shutdown)
647-
self._logger_cache = {}
648-
self._logger_cache_lock = Lock()
649647

650648
@property
651649
def resource(self):
652650
return self._resource
653651

652+
def _get_logger_no_cache(
653+
self,
654+
name: str,
655+
version: Optional[str] = None,
656+
schema_url: Optional[str] = None,
657+
attributes: Optional[Attributes] = None,
658+
) -> Logger:
659+
return Logger(
660+
self._resource,
661+
self._multi_log_record_processor,
662+
InstrumentationScope(
663+
name,
664+
version,
665+
schema_url,
666+
attributes,
667+
),
668+
)
669+
670+
@lru_cache(maxsize=None)
671+
def _get_logger_cached(
672+
self,
673+
name: str,
674+
version: Optional[str] = None,
675+
schema_url: Optional[str] = None,
676+
) -> Logger:
677+
return Logger(
678+
self._resource,
679+
self._multi_log_record_processor,
680+
InstrumentationScope(
681+
name,
682+
version,
683+
schema_url,
684+
None,
685+
),
686+
)
687+
654688
def get_logger(
655689
self,
656690
name: str,
@@ -666,28 +700,12 @@ def get_logger(
666700
schema_url=schema_url,
667701
attributes=attributes,
668702
)
669-
key = (name, version, schema_url)
670-
# Fast path if the logger is already in the cache, return it
671-
if key in self._logger_cache:
672-
return self._logger_cache[key]
673-
674-
# Lock to prevent race conditions when registering loggers with the same key
675-
with self._logger_cache_lock:
676-
# Check again in case another thread added the logger while waiting
677-
if key in self._logger_cache:
678-
return self._logger_cache[key]
679-
680-
self._logger_cache[key] = Logger(
681-
self._resource,
682-
self._multi_log_record_processor,
683-
InstrumentationScope(
684-
name,
685-
version,
686-
schema_url,
687-
attributes,
688-
),
703+
if attributes is None:
704+
return self._get_logger_cached(name, version, schema_url)
705+
else:
706+
return self._get_logger_no_cache(
707+
name, version, schema_url, attributes
689708
)
690-
return self._logger_cache[key]
691709

692710
def add_log_record_processor(
693711
self, log_record_processor: LogRecordProcessor

opentelemetry-sdk/tests/logs/test_log_provider_cache.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,47 +28,53 @@ class TestLogProviderCache(unittest.TestCase):
2828
def test_get_logger_single_handler(self):
2929
handler, logger_provider = set_up_logging_handler(level=logging.DEBUG)
3030

31+
cache_info = logger_provider._get_logger_cached.cache_clear()
32+
3133
logger = create_logger(handler, "test_logger")
3234

35+
# Ensure logger is lazily cached
36+
cache_info = logger_provider._get_logger_cached.cache_info()
37+
self.assertEqual(0, cache_info.currsize)
38+
3339
logger.warning("test message")
3440

35-
self.assertEqual(1, len(logger_provider._logger_cache))
36-
self.assertTrue(
37-
("test_logger", "", None) in logger_provider._logger_cache
38-
)
41+
cache_info = logger_provider._get_logger_cached.cache_info()
42+
self.assertEqual(1, cache_info.currsize)
43+
self.assertEqual(1, cache_info.misses)
3944

45+
# Ensure only one logger is cached
4046
rounds = 100
4147
for _ in range(rounds):
4248
logger.warning("test message")
4349

44-
self.assertEqual(1, len(logger_provider._logger_cache))
45-
self.assertTrue(
46-
("test_logger", "", None) in logger_provider._logger_cache
47-
)
50+
cache_info = logger_provider._get_logger_cached.cache_info()
51+
self.assertEqual(1, cache_info.currsize)
52+
self.assertEqual(1, cache_info.misses)
4853

4954
def test_get_logger_multiple_loggers(self):
5055
handler, logger_provider = set_up_logging_handler(level=logging.DEBUG)
5156

57+
cache_info = logger_provider._get_logger_cached.cache_clear()
58+
5259
num_loggers = 10
5360
loggers = [create_logger(handler, str(i)) for i in range(num_loggers)]
5461

62+
# Ensure loggers are lazily cached
63+
cache_info = logger_provider._get_logger_cached.cache_info()
64+
self.assertEqual(0, cache_info.currsize)
65+
5566
for logger in loggers:
5667
logger.warning("test message")
5768

58-
self.assertEqual(num_loggers, len(logger_provider._logger_cache))
59-
print(logger_provider._logger_cache)
60-
for logger in loggers:
61-
self.assertTrue(
62-
(logger.name, "", None) in logger_provider._logger_cache
63-
)
69+
cache_info = logger_provider._get_logger_cached.cache_info()
70+
self.assertEqual(num_loggers, cache_info.currsize)
71+
self.assertEqual(num_loggers, cache_info.misses)
6472

6573
rounds = 100
6674
for _ in range(rounds):
6775
for logger in loggers:
6876
logger.warning("test message")
6977

70-
self.assertEqual(num_loggers, len(logger_provider._logger_cache))
71-
for logger in loggers:
72-
self.assertTrue(
73-
(logger.name, "", None) in logger_provider._logger_cache
74-
)
78+
cache_info = logger_provider._get_logger_cached.cache_info()
79+
self.assertEqual(num_loggers, cache_info.currsize)
80+
self.assertEqual(num_loggers, cache_info.misses)

0 commit comments

Comments
 (0)