How to read this page
Each section below is one scraper of the hostmetrics receiver (Collector Contrib). A scraper only runs if you list it under scrapers: in the receiver config — and within a running scraper, each metric is either default (emitted as soon as the scraper is on) or opt-in (must be enabled by name). Opt-in metrics are the usual reason a metric you read about never shows up in your backend:
receivers:
hostmetrics:
collection_interval: 30s
scrapers:
cpu:
metrics:
system.cpu.utilization:
enabled: true
filesystem:
metrics:
system.filesystem.utilization:
enabled: true
memory:
load:
disk:
network:
paging:
processes:
The kind column tells you how to query a metric:
- Sum (monotonic) — a counter that only goes up (CPU seconds, bytes written). The raw value is meaningless; chart and alert on its rate.
- Sum (non-monotonic) — a level that happens to be a sum (bytes of memory in use, current connections). Read the value directly.
- Gauge — a point-in-time measurement (utilization fraction, load average). Read directly;
1 as a unit means a 0–1 fraction.
Where a metric has a state-style attribute, each value arrives as its own series — alerting on "memory used" means filtering to state = used, not aggregating across states.
CPU cpu
| Metric | Default | Kind | Unit | Attributes |
system.cpu.time | default | Sum (monotonic) | s | cpu, state (idle, interrupt, nice, softirq, steal, system, user, wait) |
system.cpu.utilization | opt-in | Gauge | 1 | cpu, state (same eight values) |
system.cpu.frequency | opt-in | Gauge | Hz | cpu |
system.cpu.logical.count | opt-in | Sum (non-monotonic) | {cpu} | — |
system.cpu.physical.count | opt-in | Sum (non-monotonic) | {cpu} | — |
system.cpu.time is the source of truth: one cumulative counter per logical core per state, straight from /proc/stat. Query it as a rate and the per-state shares fall out.system.cpu.utilization is the convenience version — a ready 0–1 fraction per core per state — but it is opt-in. If you want to alert on "CPU above 80%", enable it and filter out the idle state (or sum user + system), because each state arrives as its own series.
Load average load
| Metric | Default | Kind | Unit | Attributes |
system.cpu.load_average.1m | default | Gauge | {thread} | — |
system.cpu.load_average.5m | default | Gauge | {thread} | — |
system.cpu.load_average.15m | default | Gauge | {thread} | — |
- Classic 1/5/15-minute load averages. They count runnable threads, so the number is only meaningful relative to core count: enable
system.cpu.logical.count from the cpu scraper if you want to compute load-per-core instead of hardcoding the core count into a threshold. - On Windows this scraper emits an approximation the Collector computes itself (Windows has no native load average).
Memory memory
| Metric | Default | Kind | Unit | Attributes |
system.memory.usage | default | Sum (non-monotonic) | By | state (buffered, cached, free, inactive, slab_reclaimable, slab_unreclaimable, used) |
system.memory.utilization | opt-in | Gauge | 1 | state (same seven values) |
system.memory.limit | opt-in | Sum (non-monotonic) | By | — |
system.memory.page_size | opt-in | Gauge | By | — |
system.linux.memory.available | opt-in | Sum (non-monotonic) | By | — |
system.linux.memory.dirty | opt-in | Sum (non-monotonic) | By | — |
system.memory.linux.shared | opt-in | Sum (non-monotonic) | By | — |
system.memory.linux.hugepages.limit | opt-in | Sum (non-monotonic) | {page} | — |
system.memory.linux.hugepages.page_size | opt-in | Sum (non-monotonic) | By | — |
system.memory.linux.hugepages.reserved | opt-in | Sum (non-monotonic) | {page} | — |
system.memory.linux.hugepages.surplus | opt-in | Sum (non-monotonic) | {page} | — |
system.memory.linux.hugepages.usage | opt-in | Sum (non-monotonic) | {page} | state (free, used) |
system.memory.linux.hugepages.utilization | opt-in | Gauge | 1 | state (free, used) |
system.memory.usage splits physical RAM into states. On Linux, remember that cached and buffered memory is reclaimable — used alone understates what is available, and free dramatically overstates pressure. See why Linux "high memory usage" is usually the page cache.- The honest "how much can apps still allocate" number is
system.linux.memory.available (kernel MemAvailable) — opt-in, Linux only. system.memory.utilization mirrors usage as 0–1 fractions per state and is opt-in. Alert on state = used above ~0.9, not on free below a threshold.
Paging and swap paging
| Metric | Default | Kind | Unit | Attributes |
system.paging.faults | default | Sum (monotonic) | {faults} | type (major, minor) |
system.paging.operations | default | Sum (monotonic) | {operations} | direction (page_in, page_out), type (major, minor) |
system.paging.usage | default | Sum (non-monotonic) | By | device, state (cached, free, used) |
system.paging.utilization | opt-in | Gauge | 1 | device, state (cached, free, used) |
system.paging.usage is swap consumption in bytes per swap device. The interesting alert is usually on rates instead: system.paging.operations with direction = page_in, type = major climbing means the host is actively thrashing.- Major faults hit disk; minor faults are cheap and constant. Don't alert on minor fault volume.
Disk I/O disk
| Metric | Default | Kind | Unit | Attributes |
system.disk.io | default | Sum (monotonic) | By | device, direction (read, write) |
system.disk.operations | default | Sum (monotonic) | {operations} | device, direction (read, write) |
system.disk.io_time | default | Sum (monotonic) | s | device |
system.disk.operation_time | default | Sum (monotonic) | s | device, direction (read, write) |
system.disk.pending_operations | default | Sum (non-monotonic) | {operations} | device |
system.disk.merged | default | Sum (monotonic) | {operations} | device, direction (read, write) |
system.disk.weighted_io_time | default | Sum (monotonic) | s | device |
- Everything here is per block device, and all the interesting metrics are cumulative counters — chart them as rates.
system.disk.io is the bytes counter; system.disk.operations is IOPS. system.disk.pending_operations is the only level-style metric: current queue depth, a good early signal of a saturated or dying disk.- Per-operation latency isn't emitted directly, but rate(
operation_time) ÷ rate(operations) approximates it.
Filesystem filesystem
| Metric | Default | Kind | Unit | Attributes |
system.filesystem.usage | default | Sum (non-monotonic) | By | device, mode, mountpoint, type, state (free, reserved, used) |
system.filesystem.inodes.usage | default | Sum (non-monotonic) | {inodes} | device, mode, mountpoint, type, state (free, reserved, used) |
system.filesystem.utilization | opt-in | Gauge | 1 | device, mode, mountpoint, type — no state |
system.filesystem.usage is df in metric form: bytes per mountpoint, split by state = used / free / reserved (the root-only reserve on ext filesystems; Windows reports only used and free).system.filesystem.utilization is the ready-made used-fraction (used ÷ total) — note it carries no state attribute: the single value already means "fraction used". It is opt-in, which is the most common surprise in this whole receiver: people build a disk-full alert against it and see no data because it was never enabled.system.filesystem.inodes.usage matters on Linux hosts that write many small files — a disk can be "full" with free bytes left when inodes run out.
Network network
| Metric | Default | Kind | Unit | Attributes |
system.network.io | default | Sum (monotonic) | By | device, direction (receive, transmit) |
system.network.packets | default | Sum (monotonic) | {packets} | device, direction (receive, transmit) |
system.network.errors | default | Sum (monotonic) | {errors} | device, direction (receive, transmit) |
system.network.dropped | default | Sum (monotonic) | {packets} | device, direction (receive, transmit) |
system.network.connections | default | Sum (non-monotonic) | {connections} | protocol (tcp), state (ESTABLISHED, TIME_WAIT, ...) |
system.network.conntrack.count | opt-in | Sum (non-monotonic) | {entries} | — |
system.network.conntrack.max | opt-in | Sum (non-monotonic) | {entries} | — |
- Byte, packet, error, and drop counters per interface and direction — all monotonic, so query as rates. A rising
system.network.errors or system.network.dropped rate on a real interface (not docker veths) is worth an alert. system.network.connections is a level metric grouped by TCP state: a TIME_WAIT or CLOSE_WAIT pile-up is visible here long before the app errors.- The conntrack pair (opt-in, Linux) lets you alert on connection-tracking table exhaustion —
count approaching max silently drops new connections on NAT-ing hosts.
Process counts processes
| Metric | Default | Kind | Unit | Attributes |
system.processes.count | default | Sum (non-monotonic) | {processes} | status (blocked, idle, running, sleeping, stopped, zombies, ...) |
system.processes.created | default | Sum (monotonic) | {processes} | — (Linux and OpenBSD only) |
system.processes.count grouped by status is the cheap way to catch zombie accumulation or a fork bomb (zombies and running respectively); system.processes.created is a monotonic born-process counter.
Per-process process
| Metric | Default | Kind | Unit | Attributes |
process.cpu.time | default | Sum (monotonic) | s | state (system, user, wait) |
process.memory.usage | default | Sum (non-monotonic) | By | — |
process.memory.virtual | default | Sum (non-monotonic) | By | — |
process.disk.io | default | Sum (monotonic) | By | direction (read, write) |
process.cpu.utilization | opt-in | Gauge | 1 | state (system, user, wait) |
process.memory.utilization | opt-in | Gauge | 1 | — |
process.disk.operations | opt-in | Sum (monotonic) | {operations} | direction (read, write) |
process.threads | opt-in | Sum (non-monotonic) | {threads} | — |
process.open_file_descriptors | opt-in | Sum (non-monotonic) | {count} | — |
process.handles | opt-in | Sum (non-monotonic) | {count} | — (Windows only) |
process.context_switches | opt-in | Sum (monotonic) | {count} | type (involuntary, voluntary) |
process.paging.faults | opt-in | Sum (monotonic) | {faults} | type (major, minor) |
process.signals_pending | opt-in | Sum (non-monotonic) | {signals} | — |
process.uptime | opt-in | Gauge | s | — |
- This scraper emits a separate resource per process, identified by resource attributes:
process.pid, process.executable.name, process.command_line, process.owner, process.parent_pid, and friends. That's what makes filters like process.executable.name = sqlservr.exe work in alert rules. - It is also the cardinality hot spot of the receiver: hundreds of processes × several metrics each, re-resolved every interval. Scope it with the
include/exclude process name filters in the scraper config rather than shipping everything. - Reading other users' processes usually needs elevated permissions; set
mute_process_exe_error, mute_process_io_error, and mute_process_user_error to true unless you run the Collector as root, or the logs fill with permission errors.
System system
| Metric | Default | Kind | Unit | Attributes |
system.uptime | default | Gauge | s | — |
- One gauge: seconds since boot. Useful as a dead-man signal (host rebooted = uptime reset) and for excluding freshly booted hosts from other alerts.
Alert patterns that map onto these metrics
Four rules cover most host fleets. Each is a single threshold rule in Telemtra alerts once the metric is flowing:
- Disk filling up —
system.filesystem.utilization > 0.8, grouped by mountpoint. Remember to enable the metric (opt-in); the value is already the used fraction, no state filter needed. - CPU pressure —
system.cpu.utilization (opt-in) with state = idle below 0.2, or sum of user + system above 0.8, averaged over 5 minutes. - Real memory pressure —
system.memory.utilization (opt-in) with state = used > 0.9 — and not a threshold on free, which the page cache keeps near zero on any healthy Linux box. - One process misbehaving —
process.cpu.utilization (opt-in) filtered by process.executable.name, e.g. alerting when a database or worker binary alone crosses 80%.
For swap thrash, add a rate alert on system.paging.operations (direction = page_in, type = major); for flaky NICs, a rate alert on system.network.errors.
Further reading
To put this receiver into a working pipeline, the Linux host observability guide pairs hostmetrics with syslog and Nginx log collection, and the Windows guide does the same for Event Logs. For the wider receiver landscape see our Collector receivers tour, and for replacing a vendor agent wholesale, server monitoring with OpenTelemetry. Upstream definitions live in the contrib repo and the system semantic conventions — note the conventions allow attributes (like state on filesystem utilization) that the Collector implementation does not emit. Create a Telemtra workspace to point the metrics pipeline at.