LinkMesh

Search docs, blog and changelog

ENDE

Snippets · Processors

Drop all telemetry from a service

Load generators, synthetic probes and test services produce real-looking telemetry you do not want in production dashboards or bills. This filter drops every log record, metric and span whose resource service.name is load-generator or starts with synthetic-.

Signals
LogsMetricsTraces
Category
Reduction
Source
OTLP
Components
otlpbatchfiltermemory_limiterotlphttp
Destination
OTLP/HTTP endpoint

OpenTelemetry Collector

OpenTelemetry Collector YAML
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80
    spike_limit_percentage: 25
  # Drops everything a named service sends: here a load generator and any
  # service whose name starts with synthetic-.
  filter/drop-by-service:
    error_mode: ignore
    logs:
      log_record:
        - resource.attributes["service.name"] == "load-generator"
        - IsMatch(resource.attributes["service.name"], "^synthetic-")
    metrics:
      metric:
        - resource.attributes["service.name"] == "load-generator"
        - IsMatch(resource.attributes["service.name"], "^synthetic-")
    traces:
      span:
        - resource.attributes["service.name"] == "load-generator"
        - IsMatch(resource.attributes["service.name"], "^synthetic-")
  batch:
    timeout: 5s

exporters:
  otlphttp:
    endpoint: https://your-backend:4318

service:
  pipelines:
    logs:
      receivers: [otlp]
      processors: [memory_limiter, filter/drop-by-service, batch]
      exporters: [otlphttp]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, filter/drop-by-service, batch]
      exporters: [otlphttp]
    traces:
      receivers: [otlp]
      processors: [memory_limiter, filter/drop-by-service, batch]
      exporters: [otlphttp]

LinkMesh

LinkMesh has no built-in template for this job. Add it as a custom processor in raw mode, with filter as the component type and this body - the same lines as under filter/drop-by-service in the collector config:

Custom processor body (filter)
error_mode: ignore
logs:
  log_record:
    - resource.attributes["service.name"] == "load-generator"
    - IsMatch(resource.attributes["service.name"], "^synthetic-")
metrics:
  metric:
    - resource.attributes["service.name"] == "load-generator"
    - IsMatch(resource.attributes["service.name"], "^synthetic-")
traces:
  span:
    - resource.attributes["service.name"] == "load-generator"
    - IsMatch(resource.attributes["service.name"], "^synthetic-")

How custom components are validated and rolled out: create a custom processor.

Download config.yamlValidated with otelcol-contrib v0.161.0 on 2026-10-26

Complete config files, each checked with the collector's own validate command (otelcol-contrib v0.161.0). Replace https://your-backend:4318 with your own OTLP endpoint before you run it.

Before and after

Example telemetry in, and what this exact config sent out when we ran it in otelcol-contrib v0.161.0. CI re-runs it on every change and fails if the output differs. Changed values are highlighted.

4 log records in, 2 log records out

  1. Before

    body
    order 1002 accepted
    resource.service.name
    checkout

    After

    body
    order 1002 accepted
    resource.service.name
    checkout
  2. Before

    body
    virtual user 17 started
    resource.service.name
    load-generator

    After

    body
    tagged by the app, not the resource
    attributes.service.name
    load-generator
    resource.service.name
    checkout
  3. Before

    body
    probe ok
    resource.service.name
    synthetic-login-probe

    After

    Dropped

  4. Before

    body
    tagged by the app, not the resource
    attributes.service.name
    load-generator
    resource.service.name
    checkout

    After

    Dropped

2 metrics in, 1 metric out (2 data points in, 1 out)

  1. Before

    metric
    http.server.request.count
    point 1
    120
    resource.service.name
    checkout

    After

    Dropped

  2. Before

    metric
    vu.active
    point 1
    50
    resource.service.name
    load-generator

    After

    Dropped

  3. Before

    (not in the input)

    After

    metric
    http.server.request.count
    point 1
    120
    resource.service.name
    checkout

2 spans in, 1 span out

  1. Before

    span
    POST /orders
    resource.service.name
    checkout

    After

    span
    POST /orders
    resource.service.name
    checkout
  2. Before

    span
    GET /login
    resource.service.name
    synthetic-login-probe

    After

    Dropped

The gotcha

service.name is a resource attribute, and resource.attributes is what the conditions read. In our test a record from checkout that carried service.name = load-generator as a record attribute was kept, because the resource said checkout: 4 log records in, 2 out. A condition written as attributes["service.name"] validates fine and drops nothing.

Manage this across a fleet

LinkMesh manages collector configuration across a fleet from one self-hosted control plane, so a change like this is made once rather than host by host. The first 25 Collectors are free after a no-card registration in the OpenSight Customer Portal (5 without one).

Doing this in LinkMesh: Filter records on a route