Normalizes an Attributes object so arrays become filterable in trace backends.
For each key whose value is an array of strings/numbers:
Replaces the value with a comma-joined string
Adds a {key}_count attribute with the array length
Raw OTel array attributes display as protobuf values { string_value: "..." } and are
poorly filterable in most backends (Datadog, Honeycomb, etc.); flattening to a joined
string + count companion sidesteps this. Non-array values pass through unchanged.
The count suffix uses _count (not .count) because dotted-namespace trace viewers
render dot-separated keys as nested objects — using .count would make the parent key
collide with its own value. _count keeps them as siblings in the rendered tree.
Applied at the chokepoints where attributes are set on spans (setActiveSpanAttributes,
BaseService.perform, Jobbable.performLater / runTracked) so call sites can return
arrays naturally without thinking about backend representation.
Normalizes an
Attributesobject so arrays become filterable in trace backends. For each key whose value is an array of strings/numbers:{key}_countattribute with the array lengthRaw OTel array attributes display as protobuf
values { string_value: "..." }and are poorly filterable in most backends (Datadog, Honeycomb, etc.); flattening to a joined string + count companion sidesteps this. Non-array values pass through unchanged.The count suffix uses
_count(not.count) because dotted-namespace trace viewers render dot-separated keys as nested objects — using.countwould make the parent key collide with its own value._countkeeps them as siblings in the rendered tree.Applied at the chokepoints where attributes are set on spans (
setActiveSpanAttributes,BaseService.perform,Jobbable.performLater/runTracked) so call sites can return arrays naturally without thinking about backend representation.