Trace Filters
Decide which traces KubeSense stores — drop noise, or collect only what you need — and how every combination of rules, conditions and domains behaves.
Trace filters decide which traces KubeSense keeps. Each rule either drops the traces it matches or collects only the traces it matches. Filtering happens as traces arrive, before anything is stored. A dropped trace is never written, so it does not appear in trace search, on the Services or Endpoints pages, or in any view built from traces.
Manage them under Settings → Trace Filters.
Filters apply to traces from the KubeSense sensor (eBPF), OpenTelemetry and Datadog. They run in KubeSense, after the traces have been sent to it; see Where filtering happens.
warning: Filtering is not retroactive and cannot be undone for traffic it has already dropped. Traces stored before a rule was enabled stay stored; traces dropped while it was enabled are gone. Check a rule, especially a Collect only rule, before enabling it on production domains.
The rule list
Each row in Trace Filters is one rule. The toggle on a row enables or disables it. A disabled rule has no effect at all, which makes it the safe way to pause a rule without losing it.
Changes take effect within about two minutes of saving, once the collectors pick up the new rules.
Anatomy of a rule
Click Create New to open the rule form. It reads top to bottom as one sentence: <Action> traces in <domains> that match <conditions>.
| Field | What it does |
|---|---|
| Name | Optional label shown in the list. Up to 128 characters. Left empty, the rule is named after what it does, for example Drop namespace (prod-us). Names need not be unique. |
| Applies to | Select domain(s) limits the rule to the domains you pick. All domains applies it everywhere, including domains added later. |
| Action | Drop discards matching traces. Collect only keeps matching traces and discards the rest. |
| Match when | The conditions. Each condition is a field and one or more values. Use + to add a condition, up to 8 per rule. |
Fields you can match on
| Field | Matches | Example values |
|---|---|---|
| Namespace | The Kubernetes namespace. A trace matches if its own namespace, the client's namespace or the server's namespace is in the list. | payments, kube-system |
| Workload | The workload (Deployment, StatefulSet, DaemonSet, …) that produced the span. | checkout-api |
| Container | The container name. | envoy |
| Endpoint | The endpoint as shown on the Endpoints page: the normalised route or operation name. | GET /healthz |
| Tag | An OpenTelemetry resource attribute or a tag on a Datadog span, written key:value or as a bare key. See Tag conditions. | deployment.environment:staging |
Values are matched exactly and are case-sensitive. There are no wildcards or prefixes: payments does not match payments-v2. The value picker suggests values seen in your data, which is the reliable way to get them right.
How rules combine
Three rules cover every combination:
| Where | Combined with | Meaning |
|---|---|---|
| Values inside one condition | OR | Any one value matching is enough. |
| Conditions inside one rule | AND | Every condition must match. |
| Separate rules | Depends on the action | See below. |
Drop rules are independent. A trace is dropped if any Drop rule matches it. Two Drop rules drop traces matching either one; one Drop rule with two conditions drops only traces matching both.
Collect only rules form one allowlist. All Collect only rules that apply to a domain merge, field by field:
- Values for the same field add up. A rule collecting namespace
prodand another collecting namespacestagingtogether collect both. - Different fields must all pass. A rule collecting namespace
prodand another collecting workloadapitogether collect only traces that are inprodand fromapi.
This means that for Collect only, putting conditions in one rule or splitting them across rules gives the same result. For Drop it does not.
Drop wins. A trace that passes the Collect only allowlist is still dropped if a Drop rule matches it. That is how "collect only production, except one noisy job" is written — see the examples below.
When a trace has no value for a field
Not every trace carries every field. External services, legacy VMs and Docker hosts often have no namespace, and a span may have no workload.
- Collect only: a condition on a field the trace has no value for is skipped, and the trace is kept. Without this, one rule collecting namespace
prodwould silently drop every span that has no namespace at all. - Drop: a condition on a field the trace has no value for does not match, so the trace is not dropped by it. In a Drop rule with several conditions, one missing field means the whole rule does not match.
Two Collect only rules are exceptions and drop a trace that lacks the value: a rule listing domains and nothing else drops traces whose domain cannot be determined (see Rules without conditions), and a bare-key tag such as team drops traces without that attribute (see Tag conditions). Drop rules have no exceptions: a missing value never causes a drop, and a bare-key tag in a Drop rule drops every trace that has the attribute, whatever its value.
Domains and scope
A rule with Select domain(s) only affects traces from the domains it lists. Traces from other domains never consult it.
A rule with All domains applies to every domain, and combines with each domain's own rules as if it had been written for that domain too. A domain can widen an All domains rule, for example by adding more values to drop, but it cannot switch one off.
Rules may overlap. If two rules cover the same field in the same domain, the form marks the field with "Another rule already covers this field for one of the selected domains — the two will combine", and the rules combine as described above.
How a trace's domain is determined
A trace's domain is the KubeSense domain it was collected from. For OpenTelemetry it is read from the resource attribute kubesense.cluster, then k8s.cluster.name, cluster_name, kube_cluster_name. Datadog traces use kubesense.cluster, then the environment (kubesense.env, then env, which carries DD_ENV), then cluster_name, each looked for in the Datadog Agent's container tags, then the batch, then its spans (where a tracer's DD_TAGS arrive); a Datadog trace naming none of them goes to the default domain configured for pushed traces, if one is set. Because the environment ranks above cluster_name, a service that sets DD_ENV should name its domain with kubesense.cluster in DD_TAGS. Sensor (eBPF) traces take the domain of the sensor that captured them.
Rules without conditions
Removing every condition from a rule is allowed, and the result depends on the action and scope:
| Action | Applies to | Result |
|---|---|---|
| Drop | Selected domains | Every trace from those domains is dropped. Use it to stop collecting a domain without uninstalling anything. |
| Drop | All domains | Every trace from every domain is dropped. The form warns "This rule drops every trace from every domain". |
| Collect only | Selected domains | Collect only from these domains. Every other domain is dropped, including traces whose domain cannot be determined. Several such rules add up to one list of domains. |
| Collect only | All domains | Not allowed. It would be an allowlist admitting nothing. |
The Collect only + selected domains row is the one rule whose reach goes beyond the domains it names: it drops traffic from every domain it does not list.
warning: Collect only from selected domains drops traces with no resolvable domain, such as OpenTelemetry spans that carry none of the cluster attributes. Make sure every service you want to keep reports its cluster before enabling it.
Tag conditions
A tag condition matches a trace's resource attributes (OpenTelemetry) — the attributes that describe the process or service, not individual spans — or, for Datadog, the tags stored on each span. Each entry is either:
key:value— the attribute exists and has exactly this value, for exampledeployment.environment:staging;key— a bare key, meaning the attribute exists, with any value.
For OpenTelemetry, tags are checked once per incoming batch, before its spans are processed, so a whole batch is kept or dropped together. For Datadog, each span is checked on its own, before it is processed. Sensor (eBPF) traces have no resource attributes, so tag conditions never apply to them.
Which Datadog tags a condition sees
A Datadog trace has no resource attributes, so a tag condition checks each span against the tags it is stored with. It looks in three places, in this order, and uses the first value it finds:
- Container tags added by the Datadog Agent, such as
kube_namespace,pod_name,kube_deploymentandimage_name. - Tags that describe the whole batch:
telemetry.sdk.language,telemetry.sdk.version,process.runtime.versionandservice.version(fromDD_VERSION). Through the Datadog Agent these also includedeployment.environment(fromDD_ENV),host.nameandcontainer.id. - The span's own tags. This is where
DD_TAGS, andDD_ENVasenv, arrive when a tracer sends straight to KubeSense. They also include request tags such ashttp.method: a rule onhttp.method:GETdrops just the spans for GET requests.
Write the key exactly as it appears on the trace in KubeSense, for example team:payments for DD_TAGS=team:payments.
A tag condition cannot share a rule with any other field, because tags are read at an earlier stage than namespace, workload, container and endpoint. To combine them, write two rules.
Tags in a Drop rule
A Drop rule takes one tag condition. A batch is dropped if any entry matches:
env:cidrops batches whoseenvattribute isci;- a bare
debugdrops every batch that carries adebugattribute, whatever its value.
Tags in a Collect only rule
A Collect only rule can take several tag conditions, each shown as its own box:
- Inside one box, any entry is enough, even when entries name different keys.
env:prodandteam:paymentsin one box collect batches that have either. - Every box must be satisfied. With a box
env:prodand a second boxteam:payments, a batch that carriesenvmust haveenv:prod, and a batch that carriesteammust haveteam:payments. - A box whose keys a batch does not carry is skipped, like any other missing field, unless the box contains a bare key. In the example above, a batch with
env:prodand noteamattribute is kept. - A bare key requires the attribute. A box containing
envdrops batches that have noenvattribute and no other entry of the box matching. This is the way to say "collect only services that reportenv". To require a specific value and the attribute's presence, use two boxes:env:prodand a bareenv.
Collect only rules over the same attribute keys combine: one rule collecting env:prod and another collecting env:staging together collect both.
Examples
Each example is written as the rule you would enter. AND separates conditions in one rule; commas separate values in one condition.
| Goal | Rule(s) | What happens |
|---|---|---|
| Stop collecting health checks | Drop · Endpoint GET /healthz, GET /ready | Traces to either endpoint are dropped. Everything else is kept. |
| Drop a CI namespace in two domains | Drop · Selected domains dev-us, dev-eu · Namespace ci | ci traffic in those two domains is dropped. ci in other domains is kept. |
| Drop one workload, but only in one namespace | Drop · Namespace batch AND Workload nightly-report | Only nightly-report in batch is dropped. nightly-report elsewhere, and other batch workloads, are kept. |
| Drop two things independently | Drop · Namespace batch and, separately, Drop · Workload nightly-report | Anything in batch is dropped, and nightly-report is dropped wherever it runs. |
| Collect only production namespaces | Collect only · Namespace prod, prod-payments | Traces in those namespaces are kept; other namespaces are dropped. Spans with no namespace, such as external calls, are kept. |
| Collect only production, minus a noisy job | Collect only · Namespace prod and Drop · Workload noisy-cron | prod is collected, except noisy-cron, which is dropped. |
| Two Collect only rules on different fields | Collect only · Namespace prod and Collect only · Workload api | Only traces in prod and from api are kept. Rules for different fields narrow each other. |
| Two Collect only rules on the same field | Collect only · Namespace prod and Collect only · Namespace staging | Both namespaces are kept. |
| Collect only from two domains | Collect only · Selected domains prod-us, prod-eu · no conditions | Only those domains are collected. Every other domain, and traces with no domain, are dropped. |
| Stop collecting a domain entirely | Drop · Selected domains sandbox · no conditions | Every trace from sandbox is dropped. |
| Drop staging OpenTelemetry services | Drop · Tag deployment.environment:staging | Batches from services reporting that environment are dropped. Sensor traces are unaffected. |
| Collect only services that report a team | Collect only · Tag team | Batches without a team attribute are dropped. Any value of team is kept. |
| Collect only prod services owned by payments | Collect only · Tag box 1 env:prod · Tag box 2 team:payments | A batch reporting env must report prod, and one reporting team must report payments. A batch missing an attribute skips that box, so env:prod with no team is kept. |
| The same, with both attributes required | Collect only · Tag boxes env:prod, team:payments, env, team | Only batches reporting exactly env:prod and team:payments are kept. |
The order rules are checked in
For each trace, KubeSense decides in this order and stops at the first drop:
- Domain. If a Collect only rule lists domains and this trace's domain is not among them, it is dropped. If a Drop rule with no conditions covers the domain, it is dropped.
- Tags. For OpenTelemetry, tag conditions are checked once per incoming batch, and a batch that fails is dropped whole. For Datadog they are checked per span.
- Collect only. Each field with a Collect only rule must match, unless the trace has no value for that field.
- Drop. Any matching Drop rule, or any Drop rule whose conditions all match, drops the trace.
- Otherwise the trace is kept.
Where filtering happens
Filters run in KubeSense as traces arrive, not in the sensor or in your tracers. Filtered traces are still sent to KubeSense and discarded on arrival, so a rule saves storage but not the network traffic from where the traces came from. To stop a domain sending traffic at all, stop or uninstall its sensor and tracers rather than filtering it.
How early a trace is dropped depends on where it came from:
| Source | When rules are checked |
|---|---|
| OpenTelemetry | Domain and tag rules are checked once per incoming batch, before its spans are processed, so a dropped batch costs almost nothing. A batch that does not name its domain is checked span by span instead. |
| Datadog | Domain and tag rules are checked for each span before it is processed, against the domain and tags the span is stored with, so a dropped span costs almost nothing. |
| Sensor (eBPF) | Every rule is checked per trace, after KubeSense has matched the trace to its pod, workload and domain. A domain excluded by a Collect only domain list is still dropped, but only after that matching work is done. |
Trace filters apply only to traces. The network flow data the sensor captures is not affected by them.
Restricting who can change a rule
Every trace filter rule is open by default: anyone whose role has Trace Filters at Editor can change it. Restricting a rule narrows that to its owner and the people the owner names. The rule stays visible to everyone with Trace Filters access. Only changing it is restricted.
Opening the dialog
In the rule list, open the rule's ⋯ menu and choose Access. Anyone who can see the rule can open the dialog and read who may change it. Only the rule's owner or a Trace Filter Admin can change it.
Restricting a rule
- Click Restrict Editing.
- Under People with access, add people by name or email. Each person gets a level, Viewer or Editor. The owner is pinned at the top and cannot be removed.
- Under Everyone else, choose what anyone with Trace Filters access who is not named gets. Viewer is the default.
- Click Save. Nothing is saved until you do.
| Level | What they can do |
|---|---|
| Viewer | See the rule and what it matches |
| Editor | Also edit it, enable or disable it, and delete it |
Restore Full Access removes the restriction and the list of people with it.
A restricted rule shows a lock beside its name. For someone who may not change it, the toggle and Delete rule are disabled, and the rule opens with Save off and a note saying it is restricted.
warning: A restriction protects that one rule. Anyone with Trace Filters write access can still create other rules, including one that covers every domain, and all enabled rules apply together.
Owners and Trace Filter Admins
Whoever creates a rule owns it. Rules that existed before this feature are owned by their creator where that user still exists, and stay unrestricted until someone restricts them.
Trace Filter Admin is a role permission (see Role Access). Someone who holds it, along with Trace Filters at Editor, can change any restricted rule and who has access to it. Each time they change access on a rule they do not own, the audit log records it as an admin override. A rule with no owner can only be restricted by a Trace Filter Admin, who becomes its owner.
Things to know
- A grant never gives more than the person's role allows. Someone whose role has Trace Filters at Viewer cannot change a rule, whatever level they are given on it.
- The address you add must belong to an existing user. Saving is refused otherwise, and the message names the addresses that did not match.
- If someone else changes the rule's access while you have the dialog open, your save is refused and the dialog shows their version.
- Exclude on the Endpoints and trace pages adds to an existing rule only when you may change that rule. Otherwise it creates a new rule, which has the same effect.
- The API enforces the restriction, so it applies to direct API calls and API keys as well as the page.
- Every access change is recorded in Settings → Audit Logs.
note: If the dialog says changing access is not enabled on this deployment, an administrator needs to set TRACE_FILTER_ACCESS_CONTROL_ENABLED=true on the KubeSense API. Restrictions that already exist are enforced either way.
Limits and validation
The form and the API refuse a rule that could not behave as written:
- At most 8 conditions per rule.
- Each field appears once per rule. List all of its values in that one condition instead.
- Every condition needs at least one value.
- A tag condition cannot be combined with namespace, workload, container or endpoint in the same rule.
- A Drop rule takes one tag condition, because its entries already match on any of them.
- Tag entries must name an attribute key.
:prodis refused;env:prodandenvare accepted. Spaces around the key and value are trimmed when you save. - A Collect only rule with no conditions must name the domains to collect from.
Dropping an endpoint from the Endpoints page
Where enabled, each row on the Endpoints page has an Exclude button. It creates a Drop rule on that endpoint, scoped to the row's domain, which then appears in Settings → Trace Filters like any other rule.
Checking what your rules drop
Every trace a rule drops is counted, so a rule that drops more than intended shows up without waiting for someone to notice missing traces:
- Every 60 seconds the collector writes one
kubesense_trace_dropline per reason, tenant, rule, source and domain to its log, for examplekubesense_trace_drop reason=field_rule tenant=1 rule=drop-health-checks source=otel domain=prod-us detail=namespace count=1520 unit=spans window_s=60.ruleis the rule's name, orkuid:and the start of its ID for an unnamed rule; when several rules caused the drop they are joined with+. - Where KubeSense pushes its own metrics to VictoriaMetrics,
kubecol_collector_trace_filter_drop_countbreaks drops down bytenant_id,source,domain,service,field,reasonandrule, counted in spans.