diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e889bccc13..c08ec7f13a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added example for running Django with auto instrumentation. ([#1803](https://github.com/open-telemetry/opentelemetry-python/pull/1803)) +- Allow span limits (OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, OTEL_SPAN_EVENT_COUNT_LIMIT, OTEL_SPAN_LINK_COUNT_LIMIT) + to be set to "none". + ([#1830](https://github.com/open-telemetry/opentelemetry-python/pull/1830)) ### Changed - Fixed OTLP gRPC exporter silently failing if scheme is not specified in endpoint. diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 625b8519ef5..67b4396a2f7 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -58,12 +58,22 @@ logger = logging.getLogger(__name__) -SPAN_ATTRIBUTE_COUNT_LIMIT = int( - environ.get(OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, 128) + +def _get_limit_from_env(limit_name, default) -> Optional[int]: + value = environ.get(limit_name, default).strip().lower() + if value == "none": + return None + return int(value) + + +SPAN_ATTRIBUTE_COUNT_LIMIT = _get_limit_from_env( + OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, "128" ) -_SPAN_EVENT_COUNT_LIMIT = int(environ.get(OTEL_SPAN_EVENT_COUNT_LIMIT, 128)) -_SPAN_LINK_COUNT_LIMIT = int(environ.get(OTEL_SPAN_LINK_COUNT_LIMIT, 128)) +_SPAN_EVENT_COUNT_LIMIT = _get_limit_from_env( + OTEL_SPAN_EVENT_COUNT_LIMIT, "128" +) +_SPAN_LINK_COUNT_LIMIT = _get_limit_from_env(OTEL_SPAN_LINK_COUNT_LIMIT, "128") _VALID_ATTR_VALUE_TYPES = (bool, str, int, float) # pylint: disable=protected-access _TRACE_SAMPLER = sampling._get_from_env_or_default() diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/util/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/util/__init__.py index 1bb8ed264fc..694a0a5b1bd 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/util/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/util/__init__.py @@ -97,10 +97,11 @@ class BoundedDict(MutableMapping): """ def __init__(self, maxlen): - if not isinstance(maxlen, int): - raise ValueError - if maxlen < 0: - raise ValueError + if maxlen is not None: + if not isinstance(maxlen, int): + raise ValueError + if maxlen < 0: + raise ValueError self.maxlen = maxlen self.dropped = 0 self._dict = OrderedDict() # type: OrderedDict diff --git a/opentelemetry-sdk/tests/test_util.py b/opentelemetry-sdk/tests/test_util.py index cacc77dbd98..5c13bf2c7ed 100644 --- a/opentelemetry-sdk/tests/test_util.py +++ b/opentelemetry-sdk/tests/test_util.py @@ -134,6 +134,14 @@ def test_extend_drop(self): self.assertEqual(len(blist), list_len) self.assertEqual(blist.dropped, len(other_list)) + def test_no_limit(self): + blist = BoundedList(maxlen=None) + for num in range(100): + blist.append(num) + + for num in range(100): + self.assertEqual(blist[num], num) + class TestBoundedDict(unittest.TestCase): base = collections.OrderedDict( @@ -211,3 +219,11 @@ def test_bounded_dict(self): with self.assertRaises(KeyError): _ = bdict["new-name"] + + def test_no_limit(self): + bdict = BoundedDict(maxlen=None) + for num in range(100): + bdict[num] = num + + for num in range(100): + self.assertEqual(bdict[num], num)