
otel-ottl
★ 71by dash0hq · part of dash0hq/agent-skills
OpenTelemetry Transformation Language (OTTL) expert. Use when writing or debugging OTTL expressions for any OpenTelemetry Collector component that supports…
OpenTelemetry Transformation Language (OTTL) expert. Use when writing or debugging OTTL expressions for any OpenTelemetry Collector component that supports…
Inspect the full instructions your agent will receiveExpandCollapse
This is the exact playbook injected into your agent when the skill activates — shown here so you can audit it before installing. You don't need to read it to use the skill.
by dash0hq
OpenTelemetry Transformation Language (OTTL) expert. Use when writing or debugging OTTL expressions for any OpenTelemetry Collector component that supports…
npx skills add https://github.com/dash0hq/agent-skills --skill otel-ottl
Download ZIPGitHub71
OpenTelemetry Transformation Language (OTTL)
Components that use OTTL
OTTL is not limited to the transform and filter processors. Processors (transform, filter, attributes, span, tailsampling, cumulativetodelta, logdedup, lookup), connectors (routing, count, sum, signaltometrics), and the hostmetrics receiver all accept OTTL expressions. See components for the full list with use cases.
OTTL syntax
Path expressions
Navigate telemetry data using dot notation:
span.name
span.attributes["http.method"]
resource.attributes["service.name"]
Contexts (first path segment): resource, scope, span, spanevent, metric, datapoint, log.
Enumerations
Use int64 constants for enumeration fields:
span.status.code == STATUS_CODE_ERROR
span.kind == SPAN_KIND_SERVER
Operators
Assignment: = — Comparison: ==, !=, >, <, >=, <= — Logical: and, or, not
Functions
Converters (uppercase, return values):
ToUpperCase(span.attributes["http.request.method"])
Substring(log.body.string, 0, 1024)
Concat(["prefix", span.attributes["request.id"]], "-")
IsMatch(metric.name, "^k8s\\..*$")
Editors (lowercase, modify data in-place):
set(span.attributes["region"], "us-east-1")
delete_key(resource.attributes, "internal.key")
limit(log.attributes, 10, [])
See function-reference for the full list of editors and converters.
Conditional statements
Use where to apply transformations conditionally:
span.attributes["db.statement"] = "REDACTED" where resource.attributes["service.name"] == "accounting"
Nil checks
Use nil for absence checking (not null):
resource.attributes["service.name"] != nil
Validation workflow
-
Validate config syntax — run
otelcol validate --config=config.yamlto catch compilation errors before starting the Collector. -
Test with the debug exporter — route transformed telemetry to a
debugexporter and inspect the output:
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
processors: [transform, batch]
exporters: [debug] # swap in production exporter once validated
-
Set
error_mode: ignorein production — see Error handling . -
Promote to production exporters — replace
debugwith the production exporter.
Common patterns
-
Redact sensitive data — strategies: replace, mask, hash, delete, and drop.
-
Normalize high-cardinality attributes — path segments, IP masking, and attribute count/length limits.
Error handling
Compilation errors
Occur during processor initialization and prevent Collector startup:
-
Invalid syntax (missing quotes)
-
Unknown functions
-
Invalid path expressions
-
Type mismatches
Runtime errors
Occur during telemetry processing:
-
Accessing non-existent attributes
-
Type conversion failures
-
Function execution errors
Error mode configuration
Always set error_mode explicitly.
Mode Behavior When to use
propagate (default) Stops processing current item Development and strict environments where you want to catch every error
ignore Logs error, continues processing Production — set this unless you have a specific reason not to
silent Ignores errors without logging High-volume pipelines with known-safe transforms where error logs are noise
processors:
transform:
error_mode: ignore
trace_statements:
- context: span
statements:
- set(span.attributes["parsed"], ParseJSON(span.attributes["json_body"]))
Performance
Use where clauses to skip items early.
# BAD — runs replace_pattern on every span
replace_pattern(span.attributes["url.path"], "/\\d+", "/{id}")
# GOOD — skips spans that lack the attribute
replace_pattern(span.attributes["url.path"], "/\\d+", "/{id}") where span.attributes["url.path"] != nil
References
npx skills add https://github.com/dash0hq/agent-skills --skill otel-ottlRun this in your project — your agent picks the skill up automatically.
No common issues documented yet. If you hit a problem, the repository's GitHub Issues page is the best place to look.