LinkMesh

Search docs, blog and changelog

ENDE

Snippets · Sources

Collect host metrics (CPU, memory, disk, network, processes)

Every host needs the same baseline: CPU, memory, disk, filesystem, network and load, and per-process numbers when something misbehaves. The hostmetrics receiver reads them from the operating system, so one collector per host replaces a separate node exporter or agent.

Signals
Metrics
Category
Collection
Source
Host (hostmetrics)
Components
batchmemory_limiterotlphttp
Destination
OTLP/HTTP endpoint

OpenTelemetry Collector

OpenTelemetry Collector YAML
receivers:
  hostmetrics:
    collection_interval: 30s
    # On a host, set root_path: /hostfs when the collector runs in a container
    # with the host's / mounted there; on a VM leave it out.
    scrapers:
      cpu: {}
      memory: {}
      disk: {}
      filesystem: {}
      network: {}
      load: {}
      process:
        # Without this the scraper logs an error every interval for every
        # process whose owner it cannot resolve (see the gotcha).
        mute_process_user_error: true
        mute_process_exe_error: true
        mute_process_io_error: true

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80
    spike_limit_percentage: 25
  batch:
    timeout: 5s

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

service:
  pipelines:
    metrics:
      receivers: [hostmetrics]
      processors: [memory_limiter, batch]
      exporters: [otlphttp]

LinkMesh

Library › Sources › Host Metrics

Collection Interval
30s
Scrapers
["cpu","memory","disk","filesystem","network","load","process"]

What LinkMesh then pushes to the collector, under receivers:

Pushed to the collector
hostmetrics/input_src_00000501:
  collection_interval: 30s
  scrapers:
    cpu: {}
    disk: {}
    filesystem: {}
    load: {}
    memory: {}
    network: {}
    process: {}

The same, as an API call (see automation recipes):

API call
curl -X POST "$LINKMESH/sources" \
  -H "Authorization: Bearer $LMSAT" \
  -H "Content-Type: application/json" \
  -d '{
  "defaultConfig": {
    "collection_interval": "30s",
    "scrapers": [
      "cpu",
      "memory",
      "disk",
      "filesystem",
      "network",
      "load",
      "process"
    ]
  },
  "name": "Host Metrics",
  "receiverType": "hostmetrics"
}'

The rest of the collector config above (memory_limiter, batch, otlphttp) is not part of this template: in LinkMesh those are separate sources, processors and destinations on the route.

Generated from LinkMesh's template catalogue by linkmesh-server snippet-render 1.464.3, not written by hand.

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.

The gotcha

The process scraper needs to resolve each process owner. In the official otelcol-contrib container - distroless, running as uid 10001 - it cannot: in our test it logged "error reading username for process ... open /etc/passwd: no such file or directory" at every collection interval. mute_process_user_error: true took that to zero. This config also sets the matching mutes for executable-path and I/O errors.

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: Sources