Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0c1fc96

Browse files
authored
Introduce SpanLimits class to tracing SDK (open-telemetry#1877)
1 parent 56495ed commit 0c1fc96

File tree

3 files changed

+136
-63
lines changed

3 files changed

+136
-63
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v1.2.0-0.21b0...HEAD)
88

9+
### Added
10+
- Allow span limits to be set programatically via TracerProvider.
11+
([#1877](https://github.com/open-telemetry/opentelemetry-python/pull/1877))
12+
913
### Changed
1014
- Updated get_tracer to return an empty string when passed an invalid name
1115
([#1854](https://github.com/open-telemetry/opentelemetry-python/pull/1854))

opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@
6262

6363
logger = logging.getLogger(__name__)
6464

65-
_DEFAULT_SPAN_EVENTS_LIMIT = 128
66-
_DEFAULT_SPAN_LINKS_LIMIT = 128
67-
_DEFAULT_SPAN_ATTRIBUTES_LIMIT = 128
65+
_DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = 128
66+
_DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT = 128
67+
_DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT = 128
68+
69+
70+
_ENV_VALUE_UNSET = "unset"
6871

6972
# pylint: disable=protected-access
7073
_TRACE_SAMPLER = sampling._get_from_env_or_default()
@@ -499,19 +502,29 @@ def _format_links(links):
499502
return f_links
500503

501504

502-
class _Limits:
505+
class SpanLimits:
503506
"""The limits that should be enforce on recorded data such as events, links, attributes etc.
504507
505508
This class does not enforce any limits itself. It only provides an a way read limits from env,
506-
default values and in future from user provided arguments.
509+
default values and from user provided arguments.
510+
511+
All limit arguments must be either a non-negative integer, ``None`` or ``SpanLimits.UNSET``.
507512
508-
All limit must be either a non-negative integer or ``None``.
509-
Setting a limit to ``None`` will not set any limits for that field/type.
513+
- All limit arguments are optional.
514+
- If a limit argument is not set, the class will try to read it's value from the corresponding
515+
environment variable.
516+
- If the environment variable is not set, the default value for the limit is used.
510517
511518
Args:
519+
max_attributes: Maximum number of attributes that can be added to a Span.
520+
Environment variable: OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT
521+
Default: {_DEFAULT_SPAN_ATTRIBUTE_COUNT_LIMIT}
512522
max_events: Maximum number of events that can be added to a Span.
523+
Environment variable: OTEL_SPAN_EVENT_COUNT_LIMIT
524+
Default: {_DEFAULT_SPAN_EVENT_COUNT_LIMIT}
513525
max_links: Maximum number of links that can be added to a Span.
514-
max_attributes: Maximum number of attributes that can be added to a Span.
526+
Environment variable: OTEL_SPAN_LINK_COUNT_LIMIT
527+
Default: {_DEFAULT_SPAN_LINK_COUNT_LIMIT}
515528
"""
516529

517530
UNSET = -1
@@ -529,13 +542,17 @@ def __init__(
529542
self.max_attributes = self._from_env_if_absent(
530543
max_attributes,
531544
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT,
532-
_DEFAULT_SPAN_ATTRIBUTES_LIMIT,
545+
_DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT,
533546
)
534547
self.max_events = self._from_env_if_absent(
535-
max_events, OTEL_SPAN_EVENT_COUNT_LIMIT, _DEFAULT_SPAN_EVENTS_LIMIT
548+
max_events,
549+
OTEL_SPAN_EVENT_COUNT_LIMIT,
550+
_DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT,
536551
)
537552
self.max_links = self._from_env_if_absent(
538-
max_links, OTEL_SPAN_LINK_COUNT_LIMIT, _DEFAULT_SPAN_LINKS_LIMIT
553+
max_links,
554+
OTEL_SPAN_LINK_COUNT_LIMIT,
555+
_DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT,
539556
)
540557

541558
def __repr__(self):
@@ -556,7 +573,7 @@ def _from_env_if_absent(
556573
str_value = environ.get(env_var, "").strip().lower()
557574
if not str_value:
558575
return default
559-
if str_value == "unset":
576+
if str_value == _ENV_VALUE_UNSET:
560577
return None
561578

562579
try:
@@ -569,14 +586,16 @@ def _from_env_if_absent(
569586
return value
570587

571588

572-
_UnsetLimits = _Limits(
573-
max_attributes=_Limits.UNSET,
574-
max_events=_Limits.UNSET,
575-
max_links=_Limits.UNSET,
589+
_UnsetLimits = SpanLimits(
590+
max_attributes=SpanLimits.UNSET,
591+
max_events=SpanLimits.UNSET,
592+
max_links=SpanLimits.UNSET,
576593
)
577594

578-
SPAN_ATTRIBUTE_COUNT_LIMIT = _Limits._from_env_if_absent(
579-
None, OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, _DEFAULT_SPAN_ATTRIBUTES_LIMIT
595+
SPAN_ATTRIBUTE_COUNT_LIMIT = SpanLimits._from_env_if_absent(
596+
None,
597+
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT,
598+
_DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT,
580599
)
581600

582601

@@ -599,6 +618,7 @@ class Span(trace_api.Span, ReadableSpan):
599618
links: Links to other spans to be exported
600619
span_processor: `SpanProcessor` to invoke when starting and ending
601620
this `Span`.
621+
limits: `SpanLimits` instance that was passed to the `TracerProvider`
602622
"""
603623

604624
def __new__(cls, *args, **kwargs):
@@ -623,6 +643,7 @@ def __init__(
623643
instrumentation_info: InstrumentationInfo = None,
624644
record_exception: bool = True,
625645
set_status_on_exception: bool = True,
646+
limits=_UnsetLimits,
626647
) -> None:
627648
super().__init__(
628649
name=name,
@@ -637,6 +658,7 @@ def __init__(
637658
self._record_exception = record_exception
638659
self._set_status_on_exception = set_status_on_exception
639660
self._span_processor = span_processor
661+
self._limits = limits
640662
self._lock = threading.Lock()
641663

642664
_filter_attributes(attributes)
@@ -847,10 +869,6 @@ class _Span(Span):
847869
by other mechanisms than through the `Tracer`.
848870
"""
849871

850-
def __init__(self, *args, limits=_UnsetLimits, **kwargs):
851-
self._limits = limits
852-
super().__init__(*args, **kwargs)
853-
854872

855873
class Tracer(trace_api.Tracer):
856874
"""See `opentelemetry.trace.Tracer`."""
@@ -864,13 +882,14 @@ def __init__(
864882
],
865883
id_generator: IdGenerator,
866884
instrumentation_info: InstrumentationInfo,
885+
span_limits: SpanLimits,
867886
) -> None:
868887
self.sampler = sampler
869888
self.resource = resource
870889
self.span_processor = span_processor
871890
self.id_generator = id_generator
872891
self.instrumentation_info = instrumentation_info
873-
self._limits = None
892+
self._span_limits = span_limits
874893

875894
@contextmanager
876895
def start_as_current_span(
@@ -972,7 +991,7 @@ def start_span( # pylint: disable=too-many-locals
972991
instrumentation_info=self.instrumentation_info,
973992
record_exception=record_exception,
974993
set_status_on_exception=set_status_on_exception,
975-
limits=self._limits,
994+
limits=self._span_limits,
976995
)
977996
span.start(start_time=start_time, parent_context=context)
978997
else:
@@ -992,6 +1011,7 @@ def __init__(
9921011
SynchronousMultiSpanProcessor, ConcurrentMultiSpanProcessor
9931012
] = None,
9941013
id_generator: IdGenerator = None,
1014+
span_limits: SpanLimits = None,
9951015
):
9961016
self._active_span_processor = (
9971017
active_span_processor or SynchronousMultiSpanProcessor()
@@ -1002,7 +1022,7 @@ def __init__(
10021022
self.id_generator = id_generator
10031023
self._resource = resource
10041024
self.sampler = sampler
1005-
self._limits = _Limits()
1025+
self._span_limits = span_limits or SpanLimits()
10061026
self._atexit_handler = None
10071027
if shutdown_on_exit:
10081028
self._atexit_handler = atexit.register(self.shutdown)
@@ -1019,17 +1039,16 @@ def get_tracer(
10191039
if not instrumenting_module_name: # Reject empty strings too.
10201040
instrumenting_module_name = ""
10211041
logger.error("get_tracer called with missing module name.")
1022-
tracer = Tracer(
1042+
return Tracer(
10231043
self.sampler,
10241044
self.resource,
10251045
self._active_span_processor,
10261046
self.id_generator,
10271047
InstrumentationInfo(
10281048
instrumenting_module_name, instrumenting_library_version
10291049
),
1050+
self._span_limits,
10301051
)
1031-
tracer._limits = self._limits
1032-
return tracer
10331052

10341053
def add_span_processor(self, span_processor: SpanProcessor) -> None:
10351054
"""Registers a new :class:`SpanProcessor` for this `TracerProvider`.

0 commit comments

Comments
 (0)