-
Notifications
You must be signed in to change notification settings - Fork 651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT
env var
#2056
Changes from 11 commits
061e72c
a60f030
6dd996a
4bbfb01
50daa9e
305ce60
6c200aa
545e36c
0cfd038
8eb4188
319fd4b
10bae11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ | |
from opentelemetry.context import Context | ||
from opentelemetry.sdk import resources, trace | ||
from opentelemetry.sdk.environment_variables import ( | ||
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, | ||
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, | ||
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, | ||
OTEL_SPAN_EVENT_COUNT_LIMIT, | ||
|
@@ -1335,6 +1336,25 @@ def test_limits_defaults(self): | |
limits.max_links, trace._DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT | ||
) | ||
self.assertIsNone(limits.max_attribute_length) | ||
self.assertIsNone(limits.max_span_attribute_length) | ||
|
||
def test_limits_attribute_length_limits_code(self): | ||
# global limit unset while span limit is set | ||
limits = trace.SpanLimits(max_span_attribute_length=22) | ||
self.assertIsNone(limits.max_attribute_length) | ||
self.assertEqual(limits.max_span_attribute_length, 22) | ||
|
||
# span limit falls back to global limit when no value is provided | ||
limits = trace.SpanLimits(max_attribute_length=22) | ||
self.assertEqual(limits.max_attribute_length, 22) | ||
self.assertEqual(limits.max_span_attribute_length, 22) | ||
|
||
# global and span limits set to different values | ||
limits = trace.SpanLimits( | ||
max_attribute_length=22, max_span_attribute_length=33 | ||
) | ||
self.assertEqual(limits.max_attribute_length, 22) | ||
self.assertEqual(limits.max_span_attribute_length, 33) | ||
|
||
def test_limits_values_code(self): | ||
max_attributes, max_events, max_links, max_attr_length = ( | ||
|
@@ -1477,7 +1497,8 @@ def _test_span_no_limits(self, tracer): | |
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT: "13", | ||
OTEL_SPAN_EVENT_COUNT_LIMIT: "7", | ||
OTEL_SPAN_LINK_COUNT_LIMIT: "4", | ||
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT: "11", | ||
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT: "11", | ||
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT: "15", | ||
srikanthccv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
) | ||
def test_span_limits_env(self): | ||
|
@@ -1487,6 +1508,7 @@ def test_span_limits_env(self): | |
max_events=7, | ||
max_links=4, | ||
max_attr_len=11, | ||
max_span_attr_len=15, | ||
) | ||
|
||
@mock.patch.dict( | ||
|
@@ -1495,7 +1517,8 @@ def test_span_limits_env(self): | |
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT: "10", | ||
OTEL_SPAN_EVENT_COUNT_LIMIT: "20", | ||
OTEL_SPAN_LINK_COUNT_LIMIT: "30", | ||
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT: "40", | ||
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT: "40", | ||
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT: "50", | ||
}, | ||
) | ||
def test_span_limits_default_to_env(self): | ||
|
@@ -1506,12 +1529,14 @@ def test_span_limits_default_to_env(self): | |
max_events=None, | ||
max_links=None, | ||
max_attribute_length=None, | ||
max_span_attribute_length=None, | ||
) | ||
), | ||
max_attrs=10, | ||
max_events=20, | ||
max_links=30, | ||
max_attr_len=40, | ||
max_span_attr_len=50, | ||
) | ||
|
||
def test_span_limits_code(self): | ||
|
@@ -1522,12 +1547,14 @@ def test_span_limits_code(self): | |
max_events=15, | ||
max_links=13, | ||
max_attribute_length=9, | ||
max_span_attribute_length=25, | ||
) | ||
), | ||
max_attrs=11, | ||
max_events=15, | ||
max_links=13, | ||
max_attr_len=9, | ||
max_span_attr_len=25, | ||
) | ||
|
||
@mock.patch.dict( | ||
|
@@ -1562,3 +1589,105 @@ def test_dropped_attributes(self): | |
self.assertEqual(2, span.events[0].attributes.dropped) | ||
self.assertEqual(2, span.links[0].attributes.dropped) | ||
self.assertEqual(2, span.resource.attributes.dropped) | ||
|
||
def _test_span_limits( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this because of bad rebase? Why is it showing as new addition if not used anywhere in this diff? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. I had moved them to the bottom but looks like rebase added them back to the original place? Fixed now. |
||
self, | ||
tracer, | ||
max_attrs, | ||
max_events, | ||
max_links, | ||
max_attr_len, | ||
max_span_attr_len, | ||
): | ||
id_generator = RandomIdGenerator() | ||
some_links = [ | ||
trace_api.Link( | ||
trace_api.SpanContext( | ||
trace_id=id_generator.generate_trace_id(), | ||
span_id=id_generator.generate_span_id(), | ||
is_remote=False, | ||
), | ||
attributes={"k": self.long_val}, | ||
) | ||
for _ in range(100) | ||
] | ||
|
||
some_attrs = { | ||
"init_attribute_{}".format(idx): self.long_val | ||
for idx in range(100) | ||
} | ||
with tracer.start_as_current_span( | ||
"root", links=some_links, attributes=some_attrs | ||
) as root: | ||
self.assertEqual(len(root.links), max_links) | ||
self.assertEqual(len(root.attributes), max_attrs) | ||
for idx in range(100): | ||
root.set_attribute( | ||
"my_str_attribute_{}".format(idx), self.long_val | ||
) | ||
root.set_attribute( | ||
"my_byte_attribute_{}".format(idx), self.long_val.encode() | ||
) | ||
root.set_attribute( | ||
"my_int_attribute_{}".format(idx), self.long_val.encode() | ||
) | ||
root.add_event( | ||
"my_event_{}".format(idx), attributes={"k": self.long_val} | ||
) | ||
|
||
self.assertEqual(len(root.attributes), max_attrs) | ||
self.assertEqual(len(root.events), max_events) | ||
|
||
for link in root.links: | ||
for attr_val in link.attributes.values(): | ||
self._assert_attr_length(attr_val, max_attr_len) | ||
|
||
for event in root.events: | ||
for attr_val in event.attributes.values(): | ||
self._assert_attr_length(attr_val, max_attr_len) | ||
|
||
for attr_val in root.attributes.values(): | ||
self._assert_attr_length(attr_val, max_span_attr_len) | ||
|
||
def _test_span_no_limits(self, tracer): | ||
num_links = int(trace._DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT) + randint( | ||
1, 100 | ||
) | ||
|
||
id_generator = RandomIdGenerator() | ||
some_links = [ | ||
trace_api.Link( | ||
trace_api.SpanContext( | ||
trace_id=id_generator.generate_trace_id(), | ||
span_id=id_generator.generate_span_id(), | ||
is_remote=False, | ||
) | ||
) | ||
for _ in range(num_links) | ||
] | ||
with tracer.start_as_current_span("root", links=some_links) as root: | ||
self.assertEqual(len(root.links), num_links) | ||
|
||
num_events = int(trace._DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT) + randint( | ||
1, 100 | ||
) | ||
with tracer.start_as_current_span("root") as root: | ||
for idx in range(num_events): | ||
root.add_event( | ||
"my_event_{}".format(idx), attributes={"k": self.long_val} | ||
) | ||
|
||
self.assertEqual(len(root.events), num_events) | ||
|
||
num_attributes = int( | ||
trace._DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | ||
) + randint(1, 100) | ||
with tracer.start_as_current_span("root") as root: | ||
for idx in range(num_attributes): | ||
root.set_attribute( | ||
"my_attribute_{}".format(idx), self.long_val | ||
) | ||
|
||
self.assertEqual(len(root.attributes), num_attributes) | ||
for attr_val in root.attributes.values(): | ||
self.assertEqual(attr_val, self.long_val) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you modify the docstring for
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT
to say that it is specific for attributes on span? AS well, it takes precedence overOTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT
specifically for span attributes.