# OpenTelemetry Collector filtering gets simpler: OTTL context inference lands in the Filter Processor

- Link: https://thestackobserver.com/opentelemetry-collector-filtering-gets-simpler-ottl-context-inference-lands-in-the-filter-processor/
- Published: 2026-03-04T12:39:22-05:00
- Author: Stackxx

Filtering telemetry should be one of the most boring things you do in an observability
pipeline: drop noisy stuff, keep what you need, don’t accidentally remove signals
you care about. In practice, it’s often the opposite—especially in OpenTelemetry
Collector configurations where you end up thinking more about the Collector’s internal
data model than about your actual filtering intent.

That’s why the OpenTelemetry project’s update in collector-contrib v0.146.0 is worth
paying attention to: **OTTL context inference** is now available in the **Filter
Processor**. Instead of splitting your drop rules across different context blocks(
resource vs span vs span event vs datapoint…), you can write flat, readable conditions
with prefixes that make the context obvious.

## The old problem: context blocks turn intent into bureaucracy

In legacy configurations, filter rules must be placed inside specific context sections
like `resource`, `span`, or `spanevent`. Even when your intent is a single logical
policy—“drop spans from a particular container unless severity is WARN+” or “drop
events matching some pattern”—you’re forced to express it as multiple disjoint lists
purely because of internal structure.

That has two costs:

 * **Human cost**: configs become hard to review. Every PR turns into “wait, what
   context is this evaluated in?”
 * **Operational cost**: when configs are hard to reason about, teams ship changes
   slower and keep more noise “just in case.”

## What changed: `*_conditions` fields with context inference

With context inference, the Filter Processor adds four new top-level config fields:

 * `trace_conditions`
 * `metric_conditions`
 * `log_conditions`
 * `profile_conditions`

You now write a flat list of conditions and specify context explicitly by prefixing
paths with `resource`, `scope`, `span`, `spanevent`, `metric`, or `datapoint` (depending
on the signal type). The processor infers the evaluation context from that prefix
and groups/executes the conditions appropriately.

The result is a config that reads like policy, not like a schema puzzle.

## Evaluation semantics: short-circuiting improves both correctness and cost

One subtle but important detail: inference isn’t just syntactic sugar. The processor
executes grouped conditions hierarchically from higher to lower levels (for traces:
resource → scope → span → spanevent). If a higher-level condition matches, the processor
drops the subtree immediately and skips evaluating deeper levels. That means:

 * You avoid wasting CPU evaluating span-event rules for resources you already know
   you want to drop.
 * It’s easier to predict the blast radius of a rule: a resource-level match removes
   everything under it.

## Cross-context conditions: power with a sharp edge

The new system also allows cross-context expressions (for example: “drop span events
if the resource host is localhost OR event name is grpc.timeout”). These expressions
can be evaluated at a specific level (e.g., per span event), which is powerful—but
it means you need to be careful about what you are (and aren’t) dropping. In the
example above, the _span events_ get dropped; the parent spans remain.

**Practical guidance:** when adopting context inference, document whether your policy
is intended to drop resources, spans, span events, or individual datapoints—and 
write one “explainability” comment per rule group in your config repo.

## Migration strategy: adopt without breaking production

The OpenTelemetry maintainers note that the legacy configuration remains supported
and backwards compatible. So you can adopt this incrementally:

 1. **Start with a single service**: convert its noisiest drop rules into `*_conditions`.
 2. **Validate with sampling**: run a canary Collector instance and compare output 
    volumes and exemplars.
 3. **Measure cost**: if you have very high-cardinality telemetry, the short-circuit
    behavior can be a meaningful CPU win.
 4. **Standardize patterns**: create a shared library of “blessed” filtering snippets
    for your org.

## Why this matters beyond “nicer YAML”

OpenTelemetry adoption is no longer a science experiment; it’s infrastructure. Changes
like this reduce the friction of operating the Collector at scale—especially in 
Kubernetes clusters where the Collector ends up as a shared platform service. In
practice, easier filtering leads to:

 * Less telemetry noise (and lower spend)
 * Fewer accidental drops
 * Faster review cycles on observability PRs

## Sources

 * [OpenTelemetry Blog: “OTTL context inference comes to the Filter Processor”](https://opentelemetry.io/blog/2026/ottl-context-inference-come-to-filterprocessor/)
 * [OpenTelemetry Collector Contrib: Filter Processor (source)](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/9c4165139f101a43895d9273192ddb9ae3204844/processor/filterprocessor)
