Skip to content

Conversation

@cyrille-leclerc
Copy link
Member

@cyrille-leclerc cyrille-leclerc commented Oct 6, 2025

Description

set_semconv_span_name(semconvVersion, Optional[originalSpanNameAttribute])

Transform Processor function based solution for #43124

The set_semconv_span_name() function overwrites a span name using the OpenTelemetry semantic conventions for HTTP, RPC, messaging, and database spans. In other cases, the original span.name remains unchanged.

The primary use case of the set_semconv_span_name() function is to address high-cardinality issues in span metrics when span.name doesn't comply with the OpenTelemetry requirement that span names be low cardinality.

Parameters:

  • semconvVersion is the version of the Semantic Conventions used to generate the span.name.
  • originalSpanNameAttribute is the optional name of the attribute used to copy the original span.name if different from the new name derived from semantic conventions. When not provided, the original span name is not copied.

Examples

Span New span name using set_semconv_span_name("1.37.0") Comments

span.name: GET /api/v1/users/{id}
span.kind: server
span.attributes["http.request.method"]: GET
span.attributes["http.route"]: /api/v1/users/{id}

GET /api/v1/users/{id}
Compliant span names don't get modified

span.name: GET /api/v1/users/123 # /!\ high cardinality
span.kind: server
span.attributes["http.request.method"]: GET
span.attributes["http.route"]: /api/v1/users/{id}

GET /api/v1/users/{id}
High cardinality span name GET /api/v1/users/123 gets sanitized without loss of information when recommended semantic convention span attributes are provided (e.g. http.request.method and http.route).

span.name: GET /api/v1/users/123 # /!\ high cardinality
span.kind: server
span.attributes["http.request.method"]: GET

GET
High-cardinality span name GET /api/v1/users/123 is sanitized with some loss of information when recommended semantic convention span attributes are missing (e.g., http.route).

Backward compatibility: GetSemconvSpanName() supports the version 1.37 of the semantic conventions and backward compatibility
for the following attributes:

Attribute Backward compatibility
http.request.method http.method
rpc.method rpc.grpc.method
rpc.service rpc.grpc.service
db.system.name db.system
db.operation.name db.operation
db.collection.name db.name

Transform processor syntax examples:

  • set_semconv_span_name("1.37.0")

  • set_semconv_span_name("1.37.0", "original_span_name")

  • Ingestion pipeline preventing high cardinality on the span.name attribute of the metrics produced by the span metrics connector:

    processors:
      # prevent high-cardinality span names
      transform/sanitize_span_name:
        error_mode: ignore
        trace_statements:
          - set_semconv_span_name("1.37.0")
    connectors:
      spanmetrics:
    service:
      pipelines:
        traces:
          receivers: [otlp]
          processors: [..., transform/sanitize_span_name, ...]
          exporters: [otlp, spanmetrics]
        metrics:
          receivers: [spanmetrics, ...]
          exporters: [otlp]

Exceptions

Exception when the passed semconvVersion is not supported by the set_semconv_span_name() function:

Error: invalid configuration: processors::transform: unable to parse OTTL statement "set_semconv_span_name(\"1.38.0\")": couldn't create function: unsupported semconv version: 1.38.0, supported version: 1.37.0
Example with the OTel Demo

The OTel Demo handles the Next.js OTel span name high cardinality problem vercel/next.js#54694 with a fragile rewrite rule here .

set_semconv_span_name() offer a solid a flexible solution combining

  • The safety net against high cardinality span names set_semconv_span_name("1.37.0", "original_span_name")
  • With flexibility to keep meaningful span names for critical use cases: set(span.attributes["http.route"], "/api/products/{productId}") where ...
  transform:
    error_mode: ignore
    trace_statements:
      # Next.js
      - set(span.attributes["http.route"], "/api/products/{productId}") where 
        span.kind == SPAN_KIND_SERVER and
        resource.attributes["service.name"] == "frontend" and
        span.attributes["http.route"] == nil and
        IsMatch(span.attributes["http.target"], "\\/api\\/products\\/.*") # e.g. /api/products/1YMWWN1N4O

      - set(span.attributes["http.route"], "/api/cart") where 
        span.kind == SPAN_KIND_SERVER and
        resource.attributes["service.name"] == "frontend" and
        span.attributes["http.route"] == nil and
        IsMatch(span.attributes["http.target"], "\\/api\\/cart") # e.g. # /api/cart

      - set_semconv_span_name("1.37.0", "original_span_name") # copy original name for verification

Link to tracking issue

Fixes #43124

Testing

Tested successfully with the OpenTelemetry Demo

Documentation

Done, README.md updated.

@cyrille-leclerc cyrille-leclerc changed the title OTTL function get_sem_conv_span_name OTTL function get_sem_conv_span_name() Oct 6, 2025
@cyrille-leclerc
Copy link
Member Author

@iblancasa would that UX meet your expectations?

@cyrille-leclerc cyrille-leclerc changed the title OTTL function get_sem_conv_span_name() OTTL function GetSemconvSpanName() Oct 13, 2025
@cyrille-leclerc
Copy link
Member Author

@iblancasa @Frapschen the PR of he OTTL based solution to deal with high cardinality span names is ready for review

@cyrille-leclerc cyrille-leclerc marked this pull request as ready for review October 29, 2025 22:49
@cyrille-leclerc
Copy link
Member Author

cyrille-leclerc commented Oct 30, 2025

@evan-bradley @edmocosta @TylerHelmuth please review updated PR for set_semconv_span_name(semconvVersion, Optional[originalSpanNameAttribute]):

  • It's now an editor that modifies the span.name
  • The param semconvVersion is required.
    • Invalid values fail with messages like
      Error: invalid configuration: processors::transform: unable to parse OTTL statement "set_semconv_span_name(\"1.38.0\")": couldn't create function: unsupported semconv version: 1.38.0, supported version: 1.37.0
      
  • The parameter originalSpanNameAttribute is optional
  • Documentation in the readme.md is updated, included switching from HTML <table> syntax to plain markdown

@Frapschen Frapschen added the ready to merge Code review completed; ready to merge by maintainers label Nov 7, 2025
@edmocosta
Copy link
Contributor

edmocosta commented Nov 7, 2025

I'm sorry for the long delay, but let's please wait for a code-owner & approver review before adding the ready to merge label, we need that approval to get it merged, as described here. Thanks!

@edmocosta edmocosta added waiting-for-code-owners and removed ready to merge Code review completed; ready to merge by maintainers labels Nov 7, 2025
# Conflicts:
#	processor/transformprocessor/go.mod
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spanmetricsconnector: set span name based on semantic conventions