Skip to main content
In this lesson we’ll demonstrate using the OpenTelemetry Transformation Language (OTTL) with the OpenTelemetry Collector to filter and transform telemetry before exporting it. Examples focus on traces for clarity, but the same OTTL concepts apply to metrics and logs by targeting the appropriate context in the processor configuration.

What you’ll need

  • An OpenTelemetry Collector instance.
  • One or more instrumented services that send OTLP (gRPC or HTTP) to the collector.
  • The demo services in this article (auth, flight, payment) or any services that produce spans to validate filter behavior.

Starting Collector configuration

Below is a minimal collector configuration used for this demo. It receives OTLP on the standard ports and prints telemetry to the debug exporter so you can easily validate filtering behavior.
Run your sample apps (for example ./app.sh) to generate spans from each service. The collector debug exporter prints spans to the console and is useful for verifying whether OTTL rules are including or dropping spans as expected.

Adding the OTTL filter processor

To filter spans with OTTL, add the filter/ottl processor and configure rules under the traces context. The processor has an error_mode setting that determines how OTTL evaluation errors are handled:
Three error_mode options:
  • ignore: Log errors and continue evaluating other rules (no telemetry dropped due to OTTL evaluation errors).
  • silent: Do not log errors and continue evaluating other rules.
  • propagate: Stop processing and drop the telemetry when an OTTL error occurs.
Example of wiring the processor into a traces pipeline:
Key point: under the processor, the traces section lists rule categories (e.g., span) and each rule is an OTTL expression. If an expression evaluates to true for a span, that span will be dropped by the filter processor.

Filter by resource attribute (service name)

Drop spans originating from a specific service by matching the resource.attributes["service.name"] resource attribute:
Drop multiple services by adding multiple rules:
Keep only one service (drop all others) by inverting the comparison:

Filter by span name

Match spans by their name. When writing YAML, wrap the OTTL expression in single quotes and use double quotes inside as needed:
This will drop any span named validate card across all services.

Filter by span attributes

OTTL can read span attributes for flexible filtering. Examples: Match a single attribute value:
Combine conditions using logical operators:
  • OR example (drop spans for username john or mary):
  • AND example (both conditions must match to drop the span):

Regular expression matching with IsMatch

Use IsMatch to evaluate regex patterns. For example, to drop spans where the username is exactly john or mary:
This is case-sensitive by default. Adjust the regex for case-insensitive matching (e.g., use (?i)).

Negation (not)

Invert conditions using not. If the inner expression contains logical operators, wrap it in parentheses:
The above will drop any span that does not match both username john and email john@gmail.com.

Quick reference: common OTTL span filters

GoalOTTL expression (YAML string)
Drop spans from flight-service'resource.attributes["service.name"] == "flight-service"'
Drop spans named validate card'name == "validate card"'
Drop spans with username john or mary (OR)'attributes["username"] == "john" or attributes["username"] == "mary"'
Drop spans matching regex on username`‘IsMatch(attributes[“username”], ”^(johnmary)$”)‘`
Keep only flight-service (drop others)'resource.attributes["service.name"] != "flight-service"'
Note: In YAML, put each OTTL expression as a quoted string (single quotes recommended) to avoid parsing issues.
Be careful with error_mode: propagate. If an OTTL rule errors under propagate, telemetry may be dropped. Use ignore during testing to avoid inadvertently losing data.

Putting it into the Collector pipeline (complete example)

A typical configuration that applies a simple username regex-based drop looks like this:
After updating the config, restart the collector and re-run your sample apps (e.g., ./app.sh) to validate that matching spans are filtered. Inspect the collector logs and the debug exporter output to confirm behavior.

Summary

  • OTTL lets you write expressive, targeted rules to drop spans based on span properties (name, trace ID, span ID), resource attributes (for example service.name), and span attributes.
  • Use logical operators (and, or, not) and regex via IsMatch for flexible matching.
  • error_mode determines collector behavior on OTTL evaluation errors: ignore, silent, or propagate.
  • The same OTTL concepts apply to metrics and logs; use the appropriate context (metrics, logs) within the processor configuration.
Transforming telemetry (e.g., setting/removing attributes or renaming metrics) is a separate use of OTTL and is outside the scope of this article.

Watch Video