LinkMesh

Search docs, blog and changelog

ENDE

Snippets · Pipelines

Count error logs per service as a metric (count connector)

To alert on errors per service you need a number, not the log lines. The count connector counts the log records matching its condition - severity ERROR or higher - per resource, so per service, and the metrics pipeline remote-writes that counter; the logs themselves go nowhere. In the CI run below, five log records became one counter per service: 2 for checkout, 1 for catalog.

Signals
LogsMetrics
Category
Reduction
Source
OTLP logs
Components
otlpbatchmemory_limiterprometheusremotewrite
Destination
Prometheus (remote write)

Included steps

  1. Receive OTLP logs
  2. Count ERROR and above per service (count connector)
  3. Convert the delta counts to cumulative
  4. Remote-write the counter

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
  batch:
    timeout: 1s
  # The count connector emits delta sums; Prometheus remote write only
  # accepts cumulative ones.
  deltatocumulative: {}

connectors:
  count:
    logs:
      app.log.errors:
        description: Log records with severity ERROR or higher, per service.
        conditions:
          - severity_number >= SEVERITY_NUMBER_ERROR

exporters:
  prometheusremotewrite:
    endpoint: https://prometheus.example.internal/api/v1/write

service:
  pipelines:
    # The logs themselves go nowhere: only the counts are kept.
    logs:
      receivers: [otlp]
      processors: [memory_limiter]
      exporters: [count]
    metrics:
      receivers: [count]
      processors: [deltatocumulative, batch]
      exporters: [prometheusremotewrite]

LinkMesh

LinkMesh has no block for connectors today: its pipelines are built from sources, processors and destinations, and a connector is none of the three. Run this config on a collector you configure directly; LinkMesh-managed collectors can still send it the traces or logs it consumes.

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).

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.

5 log records in, 0 log records out

  1. Before

    body
    payment provider timed out
    severity
    ERROR
    severity_number
    17
    resource.service.name
    checkout

    After

    Dropped

  2. Before

    body
    payment provider timed out
    severity
    ERROR
    severity_number
    17
    resource.service.name
    checkout

    After

    Dropped

  3. Before

    body
    order 1001 placed
    severity
    INFO
    severity_number
    9
    resource.service.name
    checkout

    After

    Dropped

  4. Before

    body
    index unavailable
    severity
    FATAL
    severity_number
    21
    resource.service.name
    catalog

    After

    Dropped

  5. Before

    body
    slow query 1.2s
    severity
    WARN
    severity_number
    13
    resource.service.name
    catalog

    After

    Dropped

0 metrics in, 2 metrics out (0 data points in, 2 out)

  1. Before

    (not in the input)

    After

    metric
    app.log.errors
    point 1
    2
    resource.service.name
    checkout
  2. Before

    (not in the input)

    After

    metric
    app.log.errors
    point 1
    1
    resource.service.name
    catalog

The gotcha

The count connector emits delta sums, and Prometheus remote write only takes cumulative ones - silently. In our test, without deltatocumulative in the metrics pipeline, the exporter sent nothing at all, with nothing in the collector log; with it, both series arrived as app_log_errors_total.

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).