ollygarden/opentelemetry-agent-skills

otel-ottl

OpenTelemetry Transformation Language (OTTL) expert for writing and debugging telemetry transformations in the OpenTelemetry Collector.

First seen May 18, 2026

Installation

$ npx skills add ollygarden/opentelemetry-agent-skills --skill otel-ottl

Summary

  • OpenTelemetry Transformation Language (OTTL) expert for writing and debugging telemetry transformations in the OpenTelemetry Collector.
  • Use when authoring or reviewing `transform`, `filter`, `tail_sampling` processor configs or `routing` connector configs, debugging OTTL syntax or semantics, transforming traces, metrics, logs, or profiles, or converting data-processing requirements into OTTL statements.

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 ollygarden/opentelemetry-agent-skills · top by installs.

npx skills add ollygarden/opentelemetry-agent-skills

Browse all from ollygarden/opentelemetry-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

Also listed on

Alternate registries and mirrors of this skill.

Repository health

Stars 97
License LICENSE
Default branch main
Open issues 4
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 6,555 B
  • docs SUMMARY.md 423 B

History

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

SKILL.md

OpenTelemetry Transformation Language (OTTL)

OTTL transforms or selects telemetry inside Collector components. This skill is pinned to collector-contrib v0.160.0. Function, path, default, and feature-gate availability varies by release; when the user's version differs, verify against the matching upstream tag.

Workflow

  1. Choose the component. transform rewrites, filter drops, tail_sampling decides whether

to retain traces, and routing sends telemetry to pipelines. A component controls its available contexts and functions.

  1. Choose the lowest usable context. Lower contexts can read their parents (for example, a span

can read resource.attributes), but parents cannot read children. Use datapoint for point attributes instead of traversing metric.data_points.

  1. Verify every emitted function, then write the statement. Confirm each function's exact

identifier and signature in [references/functions.md](references/functions.md). If an identifier is absent, treat it as unsupported instead of deriving or substituting a plausible name. An editor such as set or delete_key mutates data and may have a where condition. Converters such as ParseJSON and IsMatch return values; they do not mutate.

  1. Set error behavior deliberately. ignore logs statement errors and continues; silent

continues without logging; propagate returns the error and can cause the component to drop the payload. In v0.160, transform and filter default to ignore; their stable default-error gates remain registered even though their metadata names v0.159 as the end version. Routing also defaults to ignore while its beta default-error feature gate is enabled. For routing, ignore sends an errored payload to default_pipelines; configure that fallback or the payload is dropped.

  1. Verify end to end. Validate the exact Collector version, then send known telemetry and inspect

file-exporter output. Use the [telemetrygen recipe](../otel-telemetrygen/SKILL.md#verify-collector-behavior).

set(span.attributes["env"], "prod") where resource.attributes["env"] == nil

Load only what the task needs

  • [Contexts](references/contexts.md) — exact paths, hierarchy, enums, and request metadata.
  • [Functions](references/functions.md) — editor/converter signatures and release availability.
  • [Quick reference](references/quick-reference.md) — component YAML, recipes, escaping,

troubleshooting, and safe skeletons.

For a single path or function, read only the relevant section instead of loading the full catalogs.

Safety and correctness gates

  • Guard optional or polymorphic input before conversion: where x != nil, IsString(x), or the

appropriate type check.

  • For JSON-object-only work, guard both the type and shape before calling ParseJSON, for example

IsString(log.body) and IsMatch(log.body.string, "(?s)^\\s\\{.\\}\\s*$"). The RE2 (?s) flag admits pretty-printed objects containing newlines. Checking IsMap after parsing does not prevent arrays or scalar JSON from being parsed.

  • On a version-pinned request, confirm every chosen path and function against that release tag;

do not assume a function listed for this skill's v0.160 anchor exists in an older release. For v0.156 JSON-object parsing, ParseJSON, IsString, and IsMatch are available without the v0.157 alpha lambda feature gate.

  • Request metadata is read-only and may contain credentials. Copy only explicitly allowlisted,

non-sensitive keys. OTLP metadata routing requires include_metadata: true on the receiver. HTTP/client header spelling may retain its form (otelcol.client.metadata["X-Tenant"][0]); gRPC metadata keys are lowercase (otelcol.grpc.metadata["x-tenant"][0]).

  • The routing request context is deprecated as of v0.156; use otelcol.client.metadata or

otelcol.grpc.metadata.

  • Log-record-specific rewrites of shared resource or scope data require flatten_data: true and the

alpha transform.flatten.logs gate. This copies and regroups data; do not enable it accidentally.

  • In v0.160, set(target, nil) remains a no-op by default. The alpha ottl.set.allowNil gate passes

nil to the target instead; target behavior then varies from clearing a value to returning an error. Use a where source != nil guard when the destination must remain unchanged for missing input.

  • Hashing an identifier does not necessarily anonymize it. Apply the organization's data-handling

policy before retaining deterministic hashes of personal data.

Frequent syntax traps

  • In Collector YAML, write an OTTL replacement backreference ${1} as $${1}. A replacement such

as $1REDACTED is literal and silently fails to substitute the capture.

  • Go RE2 rejects large counted repetitions such as (.{1024}).*; use Substring with a nil/type

guard and Len, or truncate_all for a map.

  • Current span-event paths use spanevent., not span_event.. Cache paths are context-qualified,

such as span.cache["parsed"].

  • Quote any OTTL statement containing a map literal when YAML includes a space after :, for

example 'set(log.attributes["a"], {"foo": "bar"})'; otherwise YAML parses : as a mapping.

  • Since v0.159, polymorphic pcommon.Value paths compare by their underlying type; maps and slices

support only equality and inequality, while primitive values also support ordering.

  • Use Decode(value, "base64"); Base64Decode is deprecated.
  • Regex escapes inside OTTL strings are doubled (\\d, \\s, \\.).

Upstream sources