dash0hq/agent-skills

otel-ottl

OpenTelemetry Transformation Language (OTTL) expert.

First seen Mar 13, 2026

Installation

$ npx skills add dash0hq/agent-skills --skill otel-ottl

Summary

  • OpenTelemetry Transformation Language (OTTL) expert.
  • Use when writing or debugging OTTL expressions for any OpenTelemetry Collector component that supports OTTL (processors, connectors, receivers, exporters).
  • Triggers on tasks involving telemetry transformation, filtering, attribute manipulation, data redaction, sampling policies, routing, or Collector configuration.
  • Covers syntax, contexts, functions, error handling, and performance.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from dash0hq/agent-skills.

npx skills add dash0hq/agent-skills

Browse all from dash0hq/agent-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 87
License LICENSE
Default branch main
Open issues 2
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0
More metadata
author
dash0
version
1.0.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 6,070 B
  • docs SUMMARY.md 452 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 515 installs

SKILL.md

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](./rules/components.md) 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](./rules/function-reference.md) for the full list of editors and converters.

Conditional statements

Use where to apply transformations conditionally:

<!-- eval:skip -->

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

  1. Validate config syntax — run otelcol validate --config=config.yaml to catch compilation errors before starting the Collector.
  2. Test with the debug exporter — route transformed telemetry to a debug exporter and inspect the output:
exporters:
  debug:
    verbosity: detailed

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [transform]
      exporters: [debug]   # swap in production exporter once validated
  1. Set error_mode: ignore in production — see [Error handling](#error-handling).
  2. Promote to production exporters — replace debug with the production exporter.

Common patterns

<!-- keep-in-sync: each entry must match a ## heading in ./rules/patterns.md -->

  • [Set attributes](./rules/patterns.md#set-attributes)
  • [Drop telemetry by pattern](./rules/patterns.md#drop-telemetry-by-pattern)
  • [Drop stale data](./rules/patterns.md#drop-stale-data)
  • [Backfill missing timestamps](./rules/patterns.md#backfill-missing-timestamps)
  • [Filter processor example](./rules/patterns.md#filter-processor-example)
  • [Transform processor example](./rules/patterns.md#transform-processor-example)
  • [Defensive nil checks](./rules/patterns.md#defensive-nil-checks)
  • [Redact sensitive data](./rules/redaction.md) — strategies: replace, mask, hash, delete, and drop.
  • [Normalize high-cardinality attributes](./rules/cardinality.md) — path segments, IP masking, and attribute count/length limits.
  • [Enrich telemetry with static attributes](./rules/enrichment.md)

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

Set error_mode explicitly for clarity; ignore is the default.

Mode Behavior When to use
ignore (default) Logs the error and continues to the next statement Production and general use — the default for the transform and filter processors
propagate Returns the error up the pipeline, dropping the payload from the Collector Development and strict environments where you want to catch every error
silent Ignores errors without logging High-volume pipelines with known-safe transforms where error logs are noise
processors:
  transform:
    error_mode: ignore
    trace_statements:
      - set(span.attributes["parsed"], ParseJSON(span.attributes["json_body"]))

Statements are a flat list; the Collector infers the context (span, metric, datapoint, log, and so on) from the path prefixes. Use the object form with an explicit context: only when a statement group mixes paths that cannot be inferred to a single context, or when you need a group-level condition or error_mode.

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