Skip to content

Commit

Permalink
Added max_attr_value_length option to OTLP exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
owais committed May 7, 2021
1 parent 81d80aa commit af21980
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ 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))
- Added `max_attr_value_length` option to OTLP exporter.
([#1824](https://github.com/open-telemetry/opentelemetry-python/pull/1824))

### Changed
- Fixed OTLP gRPC exporter silently failing if scheme is not specified in endpoint.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,16 @@ def environ_to_compression(environ_key: str) -> Optional[Compression]:
return _ENVIRON_TO_COMPRESSION[environ_value]


def _translate_key_values(key: Text, value: Any) -> KeyValue:
def _translate_key_values(
key: Text, value: Any, max_attr_value_length: Optional[int]
) -> KeyValue:

if isinstance(value, bool):
any_value = AnyValue(bool_value=value)

elif isinstance(value, str):
if max_attr_value_length is not None:
value = value[:max_attr_value_length]
any_value = AnyValue(string_value=value)

elif isinstance(value, int):
Expand Down Expand Up @@ -115,6 +119,7 @@ def get_resource_data(
],
resource_class: Callable[..., TypingResourceT],
name: str,
max_attr_value_length=None,
) -> List[TypingResourceT]:

resource_data = []
Expand All @@ -131,7 +136,7 @@ def get_resource_data(
try:
# pylint: disable=no-member
collector_resource.attributes.append(
_translate_key_values(key, value)
_translate_key_values(key, value, max_attr_value_length)
)
except Exception as error: # pylint: disable=broad-except
logger.exception(error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""OTLP Span Exporter"""

import logging
from functools import partial
from os import environ
from typing import Optional, Sequence

Expand Down Expand Up @@ -70,6 +71,7 @@ class OTLPSpanExporter(
headers: Headers to send when exporting
timeout: Backend request timeout in seconds
compression: gRPC compression method to use
max_attr_value_length: Max length string attribute values can have. Set to None to disable.
"""

_result = SpanExportResult
Expand All @@ -83,7 +85,10 @@ def __init__(
headers: Optional[Sequence] = None,
timeout: Optional[int] = None,
compression: Optional[Compression] = None,
max_attr_value_length: Optional[int] = None,
):
self._max_attr_value_length = max_attr_value_length

if (
not insecure
and environ.get(OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE) is not None
Expand Down Expand Up @@ -161,7 +166,9 @@ def _translate_attributes(self, sdk_span: ReadableSpan) -> None:

try:
self._collector_span_kwargs["attributes"].append(
_translate_key_values(key, value)
_translate_key_values(
key, value, self._max_attr_value_length
)
)
except Exception as error: # pylint: disable=broad-except
logger.exception(error)
Expand All @@ -180,7 +187,9 @@ def _translate_events(self, sdk_span: ReadableSpan) -> None:
for key, value in sdk_span_event.attributes.items():
try:
collector_span_event.attributes.append(
_translate_key_values(key, value)
_translate_key_values(
key, value, self._max_attr_value_length
)
)
# pylint: disable=broad-except
except Exception as error:
Expand All @@ -206,7 +215,9 @@ def _translate_links(self, sdk_span: ReadableSpan) -> None:
for key, value in sdk_span_link.attributes.items():
try:
collector_span_link.attributes.append(
_translate_key_values(key, value)
_translate_key_values(
key, value, self._max_attr_value_length
)
)
# pylint: disable=broad-except
except Exception as error:
Expand Down Expand Up @@ -287,6 +298,7 @@ def _translate_data(
sdk_resource_instrumentation_library_spans,
ResourceSpans,
"spans",
max_attr_value_length=self._max_attr_value_length,
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import os
from collections import OrderedDict
from concurrent.futures import ThreadPoolExecutor
from random import randint
from unittest import TestCase
from unittest.mock import Mock, PropertyMock, patch

Expand Down Expand Up @@ -130,7 +131,9 @@ def setUp(self):
event_mock = Mock(
**{
"timestamp": 1591240820506462784,
"attributes": OrderedDict([("a", 1), ("b", False)]),
"attributes": OrderedDict(
[("a", 1), ("b", False), ("c", "ve" * 1200)]
),
}
)

Expand All @@ -145,16 +148,22 @@ def setUp(self):
"trace_id": 67545097771067222548457157018666467027,
}
),
resource=SDKResource(OrderedDict([("a", 1), ("b", False)])),
resource=SDKResource(
OrderedDict([("a", 1), ("b", False), ("c", "vr" * 500)])
),
parent=Mock(**{"span_id": 12345}),
attributes=OrderedDict([("a", 1), ("b", True)]),
attributes=OrderedDict(
[("a", 1), ("b", True), ("c", "vs" * 1000)]
),
events=[event_mock],
links=[
Mock(
**{
"context.trace_id": 1,
"context.span_id": 2,
"attributes": OrderedDict([("a", 1), ("b", False)]),
"attributes": OrderedDict(
[("a", 1), ("b", False), ("c", "vl" * 700)]
),
"kind": OTLPSpan.SpanKind.SPAN_KIND_INTERNAL, # pylint: disable=no-member
}
)
Expand Down Expand Up @@ -401,6 +410,12 @@ def test_translate_spans(self):
KeyValue(
key="b", value=AnyValue(bool_value=False)
),
KeyValue(
key="c",
value=AnyValue(
string_value="vr" * 500,
),
),
]
),
instrumentation_library_spans=[
Expand Down Expand Up @@ -438,6 +453,12 @@ def test_translate_spans(self):
key="b",
value=AnyValue(bool_value=True),
),
KeyValue(
key="c",
value=AnyValue(
string_value="vs" * 1000,
),
),
],
events=[
OTLPSpan.Event(
Expand All @@ -456,6 +477,13 @@ def test_translate_spans(self):
bool_value=False
),
),
KeyValue(
key="c",
value=AnyValue(
string_value="ve"
* 1200,
),
),
],
)
],
Expand All @@ -479,6 +507,13 @@ def test_translate_spans(self):
bool_value=False
),
),
KeyValue(
key="c",
value=AnyValue(
string_value="vl"
* 700,
),
),
],
)
],
Expand All @@ -493,6 +528,40 @@ def test_translate_spans(self):
# pylint: disable=protected-access
self.assertEqual(expected, self.exporter._translate_data([self.span]))

def test_max_attr_value_length(self):
max_length = randint(0, 100)
exporter = OTLPSpanExporter(
insecure=True, max_attr_value_length=max_length
)
resource_spans = exporter._translate_data( # pylint: disable=protected-access,no-member
[self.span]
).resource_spans
self.assertEqual(len(resource_spans), 1)
self.assertEqual(len(resource_spans[0].resource.attributes), 3)
self.assertEqual(
len(resource_spans[0].resource.attributes[2].value.string_value),
max_length,
)

self.assertEqual(
len(resource_spans[0].instrumentation_library_spans), 1
)
span = resource_spans[0].instrumentation_library_spans[0].spans[0]
self.assertEqual(len(span.attributes), 3)
self.assertEqual(
len(span.attributes[2].value.string_value), max_length
)

self.assertEqual(len(span.links), 1)
self.assertEqual(
len(span.links[0].attributes[2].value.string_value), max_length
)

self.assertEqual(len(span.events), 1)
self.assertEqual(
len(span.events[0].attributes[2].value.string_value), max_length
)

def _check_translated_status(
self,
translated: ExportTraceServiceRequest,
Expand Down

0 comments on commit af21980

Please sign in to comment.