Skip to content

Make url_sanitization for span names optional #44228

@arielvalentin

Description

@arielvalentin

Component(s)

processor/redaction

Is your feature request related to a problem? Please describe.

I would like the ability to disable span name processing when enabling the url_sanitizer on the redaction processor.

The sanitizer is renaming spans in undesirable scenarios where it already has a "low cardinality/sanitized" name.

This results in lower cardinality spans that are much less useful to our users. Where I expected span names to be preserved like "POST /twirp/users.api.v1.UserService/Update"; the span name was renamed to "POST /twirp/*/Update" like in the debug output below:

otel-collector-1  | 2025-11-13T06:39:54.684Z    info    ResourceSpans #0
otel-collector-1  | Resource SchemaURL: 
otel-collector-1  | Resource attributes:
otel-collector-1  |      -> service.name: Str(example-service)
otel-collector-1  |      -> service.version: Str(1.0.0)
otel-collector-1  | ScopeSpans #0
otel-collector-1  | ScopeSpans SchemaURL: 
otel-collector-1  | InstrumentationScope example-instrumentation 1.0.0
otel-collector-1  | Span #0
otel-collector-1  |     Trace ID       : 5b8aa5a2d2c872e8321cf37308d69df2
otel-collector-1  |     Parent ID      : 
otel-collector-1  |     ID             : 051581bf3cb55c13
otel-collector-1  |     Name           : POST /twirp/*/Update
otel-collector-1  |     Kind           : Client
otel-collector-1  |     Start time     : 2023-11-13 11:55:43 +0000 UTC
otel-collector-1  |     End time       : 2023-11-13 11:55:43.5 +0000 UTC
otel-collector-1  |     Status code    : Unset
otel-collector-1  |     Status message : 
otel-collector-1  | Attributes:
otel-collector-1  |      -> http.method: Str(POST)
otel-collector-1  |      -> http.request.method: Str(POST)
otel-collector-1  |      -> http.url: Str(*//example.com/twirp/*/Update)
otel-collector-1  |      -> url.full: Str(*//example.com/twirp/*/Update)
otel-collector-1  |      -> url.path: Str(/twirp/*/Update)
otel-collector-1  |      -> url.template: Str(/twirp/users.api.v1.UserService/Update)
otel-collector-1  |      -> http.status_code: Int(200)
otel-collector-1  |      -> log.file.name: Str(input.json)
otel-collector-1  |      -> redaction.masked.keys: Str(http.url,url.full,url.path)
otel-collector-1  |      -> redaction.masked.count: Int(3)
otel-collector-1  | Span #1
otel-collector-1  |     Trace ID       : 5b8aa5a2d2c872e8321cf37308d69df2
otel-collector-1  |     Parent ID      : 051581bf3cb55c13
otel-collector-1  |     ID             : 5fb397be161d0b51
otel-collector-1  |     Name           : POST /twirp/*/Update
otel-collector-1  |     Kind           : Server
otel-collector-1  |     Start time     : 2023-11-13 11:55:43.1 +0000 UTC
otel-collector-1  |     End time       : 2023-11-13 11:55:43.4 +0000 UTC
otel-collector-1  |     Status code    : Unset
otel-collector-1  |     Status message : 
otel-collector-1  | Attributes:
otel-collector-1  |      -> http.method: Str(POST)
otel-collector-1  |      -> http.request.method: Str(POST)
otel-collector-1  |      -> http.url: Str(*//example.com/twirp/*/Update)
otel-collector-1  |      -> url.full: Str(*//example.com/twirp/*/Update)
otel-collector-1  |      -> url.path: Str(/twirp/*/Update)
otel-collector-1  |      -> http.route: Str(/twirp/users.api.v1.UserService/Update)
otel-collector-1  |      -> http.status_code: Int(200)
otel-collector-1  |      -> log.file.name: Str(input.json)
otel-collector-1  |      -> redaction.masked.keys: Str(http.url,url.full,url.path)
otel-collector-1  |      -> redaction.masked.count: Int(3)
otel-collector-1  |     {"resource": {"service.instance.id": "e0e411fa-e1af-449e-a034-fa2aa546c4b3", "service.name": "otelcol-contrib", "service.version": "0.139.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces"}

Describe the solution you'd like

I want to be able to bypass name processing for spans when using the URL sanitizer. This will allow me to preserve existing names.

Describe alternatives you've considered

My workaround at this point is to copy the name to a separate attribute before applying the processor and then later restoring it.

Additional context

receivers:
  otlpjsonfile:
    include:
      - /input/input.json
    start_at: beginning

processors:
  redaction:
    allow_all_keys: true
    url_sanitizer:
      enabled: true
      attributes: ["http.url", "url.full", "url.path"]
    summary: debug

exporters:
  debug:
    verbosity: detailed

service:
  pipelines:
    traces:
      receivers: [otlpjsonfile]
      processors: [redaction]
      exporters: [debug]
{"resourceSpans":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"example-service"}},{"key":"service.version","value":{"stringValue":"1.0.0"}}]},"scopeSpans":[{"scope":{"name":"example-instrumentation","version":"1.0.0"},"spans":[{"traceId":"5b8aa5a2d2c872e8321cf37308d69df2","spanId":"051581bf3cb55c13","name":"POST /twirp/users.api.v1.UserService/Update","kind":3,"startTimeUnixNano":"1699876543000000000","endTimeUnixNano":"1699876543500000000","attributes":[{"key":"http.method","value":{"stringValue":"POST"}},{"key":"http.request.method","value":{"stringValue":"POST"}},{"key":"http.url","value":{"stringValue":"https://example.com/twirp/users.api.v1.UserService/Update"}},{"key":"url.full","value":{"stringValue":"/twirp/users.api.v1.UserService/Update"}},{"key":"url.path","value":{"stringValue":"/twirp/users.api.v1.UserService/Update"}},{"key":"url.template","value":{"stringValue":"/twirp/users.api.v1.UserService/Update"}},{"key":"http.status_code","value":{"intValue":"200"}}],"status":{"code":0}},{"traceId":"5b8aa5a2d2c872e8321cf37308d69df2","spanId":"5fb397be161d0b51","parentSpanId":"051581bf3cb55c13","name":"POST /twirp/users.api.v1.UserService/Update","kind":2,"startTimeUnixNano":"1699876543100000000","endTimeUnixNano":"1699876543400000000","attributes":[{"key":"http.method","value":{"stringValue":"POST"}},{"key":"http.request.method","value":{"stringValue":"POST"}},{"key":"http.url","value":{"stringValue":"https://example.com/twirp/users.api.v1.UserService/Update"}},{"key":"url.full","value":{"stringValue":"/twirp/users.api.v1.UserService/Update"}},{"key":"url.path","value":{"stringValue":"/twirp/users.api.v1.UserService/Update"}},{"key":"http.route","value":{"stringValue":"/twirp/users.api.v1.UserService/Update"}},{"key":"http.status_code","value":{"intValue":"200"}}],"status":{"code":0}}]}]}]}

Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions