OTTL transforms or selects telemetry inside Collector components. This skill is pinned to collector-contrib v0.162.0. Function, path, default, and feature-gate availability varies by release; when the user's version differs, verify against the matching upstream tag.
Workflow
- Choose the component.
transformrewrites,filterdrops,tail_samplingdecides whether to retain traces, androutingsends telemetry to pipelines. A component controls its available contexts and functions. - Choose the lowest usable context. Lower contexts can read their parents (for example, a span
can read
resource.attributes), but parents cannot read children. Usedatapointfor point attributes instead of traversingmetric.data_points. - Verify every emitted function, then write the statement. Confirm each function's exact
identifier and signature in references/functions.md. If an identifier
is absent, treat it as unsupported instead of deriving or substituting a plausible name. An
editor such as
setordelete_keymutates data and may have awherecondition. Converters such asParseJSONandIsMatchreturn values; they do not mutate. - Set error behavior deliberately.
ignorelogs statement errors and continues;silentcontinues without logging;propagatereturns the error and can cause the component to drop the payload. Transform and filter default toignore; the transform default-error gate was removed in v0.162.0, so naming it in--feature-gatesfails startup (history: theotel-collectorskill's transform quirks), and the filter gate is stable and cannot be disabled. Routing also defaults toignorewhile its beta default-error feature gate is enabled. For routing,ignoresends an errored payload todefault_pipelines; configure that fallback or the payload is dropped. - Verify end to end. Validate the exact Collector version, then send known telemetry and inspect file-exporter output. Use the telemetrygen recipe.
set(span.attributes["env"], "prod") where resource.attributes["env"] == nil
Load only what the task needs
- Contexts — exact paths, hierarchy, enums, and request metadata.
- Functions — editor/converter signatures and release availability.
- Quick reference — 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 exampleIsString(log.body) and IsMatch(log.body.string, "(?s)^\\s*\\{.*\\}\\s*$"). The RE2(?s)flag admits pretty-printed objects containing newlines. CheckingIsMapafter 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.162 anchor exists in an older release.
For v0.156 JSON-object parsing,
ParseJSON,IsString, andIsMatchare 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: trueon 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
requestcontext is deprecated as of v0.156; useotelcol.client.metadataorotelcol.grpc.metadata. - Log-record-specific rewrites of shared resource or scope data require
flatten_data: trueand the alphatransform.flatten.logsgate. This copies and regroups data; do not enable it accidentally. - Since v0.161,
set(target, nil)is no longer a no-op: theottl.set.allowNilgate became beta in v0.161 and stable (cannot be disabled) in v0.162. A nil value empties a map, slice, orpcommon.Valuetarget (an attribute key is created with an empty value) and errors on scalar targets. Use awhere source != nilguard 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$1REDACTEDis literal and silently fails to substitute the capture. - Go RE2 rejects large counted repetitions such as
(.{1024}).*; useSubstringwith a nil/type guard andLen, ortruncate_allfor a map. - Current span-event paths use
spanevent.*, notspan_event.*. Cache paths are context-qualified, such asspan.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.Valuepaths compare by their underlying type; maps and slices support only equality and inequality, while primitive values also support ordering. - Use
Decode(value, "base64");Base64Decodewas removed in v0.161. - Regex escapes inside OTTL strings are doubled (
\\d,\\s,\\.).