Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions opentelemetry-exporter-gcp-trace/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- Update span and attribute limits to match Cloud Trace backend

## Version 1.14.0

Released 2026-08-03
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@


MAX_NUM_LINKS = 128
MAX_NUM_EVENTS = 32
MAX_EVENT_ATTRS = 4
MAX_LINK_ATTRS = 32
MAX_SPAN_ATTRS = 32
MAX_ATTR_KEY_BYTES = 128
MAX_ATTR_VAL_BYTES = 16 * 1024 # 16 kilobytes
MAX_NUM_EVENTS = 256
MAX_EVENT_ATTRS = 1024
MAX_LINK_ATTRS = 1024
MAX_SPAN_ATTRS = 1024
MAX_ATTR_KEY_BYTES = 512
MAX_ATTR_VAL_BYTES = 64 * 1024 # 64 kilobytes


def _create_default_client() -> TraceServiceClient:
Expand Down Expand Up @@ -260,7 +260,7 @@ def _translate_to_cloud_trace(
trace_types.Span(
name=span_name,
span_id=span_id,
display_name=_get_truncatable_str_object(span.name, 128),
display_name=_get_truncatable_str_object(span.name, 1024),
start_time=start_time,
end_time=end_time,
parent_span_id=parent_id,
Expand Down Expand Up @@ -400,7 +400,7 @@ def _extract_events(
trace_types.Span.TimeEvent(
time=_get_time_from_ns(event.timestamp),
annotation=trace_types.Span.TimeEvent.Annotation(
description=_get_truncatable_str_object(event.name, 256),
description=_get_truncatable_str_object(event.name, 1024),
attributes=_extract_attributes(
event.attributes, MAX_EVENT_ATTRS
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,12 @@ def setUpClass(cls):
cls.example_span_id = "95bb5edabd45950f"
cls.example_time_in_ns = 1589919268850900051
cls.example_time_stamp = _get_time_from_ns(cls.example_time_in_ns)
cls.str_20kb = "a" * 20 * 1024
cls.str_16kb = "a" * 16 * 1024
cls.str_70kb = "a" * 70 * 1024
cls.str_64kb = "a" * 64 * 1024
cls.str_1100 = "a" * 1100
cls.str_1024 = "a" * 1024
cls.str_600 = "a" * 600
cls.str_512 = "a" * 512
cls.str_300 = "a" * 300
cls.str_256 = "a" * 256
cls.str_128 = "a" * 128
Expand Down Expand Up @@ -338,22 +342,22 @@ def test_agent_attribute_priority(self):
def test_attribute_value_truncation(self):
# shouldn't truncate
self.assertEqual(
_format_attribute_value(self.str_300),
_format_attribute_value(self.str_600),
AttributeValue(
string_value=TruncatableString(
value=self.str_300,
value=self.str_600,
truncated_byte_count=0,
)
),
)

# huge string should truncate
self.assertEqual(
_format_attribute_value(self.str_20kb),
_format_attribute_value(self.str_70kb),
AttributeValue(
string_value=TruncatableString(
value=self.str_16kb,
truncated_byte_count=(20 - 16) * 1024,
value=self.str_64kb,
truncated_byte_count=(70 - 64) * 1024,
)
),
)
Expand Down Expand Up @@ -395,11 +399,11 @@ def test_list_attribute_value(self):
def test_attribute_key_truncation(self):
self.assertEqual(
_extract_attributes(
{self.str_300: "attr_value"}, num_attrs_limit=4
{self.str_600: "attr_value"}, num_attrs_limit=4
),
ProtoSpan.Attributes(
attribute_map={
self.str_128: AttributeValue(
self.str_512: AttributeValue(
string_value=TruncatableString(
value="attr_value", truncated_byte_count=0
)
Expand Down Expand Up @@ -504,7 +508,9 @@ def test_extract_multiple_events(self):

def test_event_name_truncation(self):
event1 = Event(
name=self.str_300, attributes={}, timestamp=self.example_time_in_ns
name=self.str_1100,
attributes={},
timestamp=self.example_time_in_ns,
)
self.assertEqual(
_extract_events([event1]),
Expand All @@ -514,8 +520,8 @@ def test_event_name_truncation(self):
"time": self.example_time_stamp,
"annotation": {
"description": TruncatableString(
value=self.str_256,
truncated_byte_count=300 - 256,
value=self.str_1024,
truncated_byte_count=1100 - 1024,
),
"attributes": {},
},
Expand Down Expand Up @@ -780,3 +786,23 @@ def test_extract_span_kind(self):
self.assertEqual(
_extract_span_kind(-1), ProtoSpan.SpanKind.SPAN_KIND_UNSPECIFIED
)

def test_span_name_truncation(self):
exporter = CloudTraceSpanExporter(self.project_id)
span_data = Span(
name=self.str_1100,
context=SpanContext(
trace_id=int(self.example_trace_id, 16),
span_id=int(self.example_span_id, 16),
is_remote=False,
),
)
# pylint: disable=protected-access
translated_spans = exporter._translate_to_cloud_trace([span_data])
self.assertEqual(
translated_spans[0].display_name,
TruncatableString(
value=self.str_1024,
truncated_byte_count=1100 - 1024,
),
)
Loading