Check the exporter on the machine itself
active, a LISTEN line and a node_load1 value mean the exporter
is fine. Next, check whether Prometheus collects it:
prometheus.
The Prometheus exporter for the machine itself: serves CPU, memory, disk, network and service metrics on :9100.
sudo systemctl enable --now prometheus-node-exporter
turn it on
systemctl status prometheus-node-exporter
is the service alive
ss -tlnp | grep 9100
where it listens
curl -s localhost:9100/metrics | less
everything it serves
curl -s localhost:9100/metrics | grep -c '^node_'
value count
curl -s localhost:9100/metrics | grep MemAvailable
one metric
curl -s localhost:9100/metrics | promtool check metrics
format
sudo systemctl restart prometheus-node-exporter
after editing ARGS
node_exporter is the Prometheus exporter for the
machine itself. It reads /proc, /sys and the systemd state and
serves current values over HTTP on port 9100, path /metrics: CPU,
memory, disks, file systems, network, load and service state. It
stores nothing and sends nothing anywhere: Prometheus comes for the
metrics on a schedule (prometheus).
In Ubuntu this is the prometheus-node-exporter package: a service of
the same name, the program /usr/bin/prometheus-node-exporter, and
the prometheus user. On the training machine the package is
installed and the service is off:
The exporter answers a second or two after it starts.
The /metrics answer is text. Each metric has two comment lines and
value lines:
The first line of the output is a single line, wrapped here.
| Line | What is in it |
|---|---|
# HELP name text |
what the metric measures |
# TYPE name type |
counter, gauge, histogram, summary or untyped |
name{labels} value |
one value: a series with its own label set |
The value is a floating-point number, often in exponent notation:
2.95616512e+08 is 295,616,512 bytes, about 282 MiB. A metric with
labels has several value lines:
The name tells the units: _bytes, _seconds; _total marks a
counter (promql). The node_ prefix is machine
metrics, go_ and process_ are about the exporter itself. On the
training machine the answer is about 1900 lines: roughly 270 metrics
and 1300 node_* values.
| Metric | Meaning |
|---|---|
node_cpu_seconds_total |
CPU seconds since boot by core (cpu) and mode (mode: idle, user, system, iowait…) |
node_load1, node_load5, node_load15 |
load average over 1, 5 and 15 minutes |
node_memory_MemAvailable_bytes |
memory that can be taken without swapping out; next to it are MemTotal, MemFree and the other /proc/meminfo fields |
node_filesystem_avail_bytes |
free space on the file system for ordinary users, like the Avail column of df |
node_filesystem_size_bytes |
file system size |
node_disk_read_bytes_total, node_disk_written_bytes_total |
bytes read from and written to a disk (device) |
node_network_receive_bytes_total, node_network_transmit_bytes_total |
bytes received and sent through an interface (device) |
node_systemd_unit_state |
1 for the unit's current state (name, state), 0 for the others |
node_boot_time_seconds |
boot time in Unix seconds |
node_uname_info |
kernel version and host name in labels, value 1 |
How much memory can be taken is MemAvailable. MemFree is memory
used by nothing at all; the file cache is not in it, although the
kernel gives the cache back on demand. On the training machine
MemFree is about 13 MiB and MemAvailable about 280. More on load and memory:
load-average and memory-swap.
A collector is the part of the exporter that reads one source:
meminfo reads /proc/meminfo, filesystem the mounted file
systems, netdev the interfaces, systemd the units, textfile the
files with your own metrics. More than forty are on on the training
machine. Which ones, and whether the last read worked, is in the
node_scrape_collector_success metric:
0 for a collector means its source could not be read; the reason is
in the service journal. The --collector.<name> and
--no-collector.<name> flags turn a collector on or off (see
"Configuration").
The filesystem collector does not serve node_filesystem_* for every
mount point. It skips whatever matches
--collector.filesystem.mount-points-exclude, which on the training
machine defaults to:
The expression is wrapped here. A volume mounted under /mnt/… or
/media/… does not get into the metrics at all: it has no series, and
a rule with its mountpoint is empty (node-exporter).
File system types are cut by --collector.filesystem.fs-types-exclude
(tmpfs is not in that list; proc, sysfs, overlay, squashfs
are). A flag in ARGS sets your own list and replaces the default.
The textfile collector reads the *.prom files in
/var/lib/prometheus/node-exporter on every request to /metrics and
serves their lines along with its own. This is how a script with no
HTTP server of its own tells Prometheus, for example, the time of the
last successful backup:
# HELP and # TYPE lines in the file are optional: without them the
exporter writes its own, and the type is untyped. The directory
belongs to root, so writing to it takes sudo.
The exporter has no settings file, only command-line flags. The
service takes them from the ARGS variable in
/etc/default/prometheus-node-exporter; the package leaves it empty
(ARGS=""), so everything is at its default:
After an edit, run sudo systemctl restart prometheus-node-exporter.
reload does not fit here: see node-exporter. All
flags with descriptions: prometheus-node-exporter --help.
By default the exporter listens on port 9100 on every address of the machine:
The --web.listen-address flag sets the address and port. It goes
into ARGS in /etc/default/prometheus-node-exporter or into a
service drop-in (sudo systemctl edit prometheus-node-exporter → the
file /etc/systemd/system/prometheus-node-exporter.service.d/override.conf,
where an ExecStart= line replaces the start command). Where the flag
is actually set:
systemctl cat prometheus-node-exporter shows the unit with its
drop-ins, each file under a # /path line;systemctl status prometheus-node-exporter shows the whole command
with its flags in the CGroup line under the process number;ss -tlnp | grep prometheus-node shows which port it listens on now.There is no password and no encryption: whoever reaches the port sees
the metrics. --web.listen-address=127.0.0.1:9100 leaves access from
the machine itself only, and Prometheus on another machine then gets
connection refused. When Prometheus lives on another machine, the
exporter listens on its external address, and the firewall opens
the port to the Prometheus address only.
Metrics are served only on the /metrics path. On any other path the
exporter answers with an HTML page and code 200, and Prometheus with a
wrong metrics_path writes expected a valid start token, got "<"
into lastError (prometheus).
| Directive | What it does | Example |
|---|---|---|
--web.listen-address ARGS |
The address and port where the exporter waits for Prometheus; without an address, every address of the machine. | --web.listen-address=127.0.0.1:9100 |
--web.telemetry-path ARGS |
The path that serves the metrics. | --web.telemetry-path=/metrics |
--collector.<имя> ARGS |
Turn on a collector that is off by default. | --collector.processes |
--no-collector.<имя> ARGS |
Turn off a collector that is on by default. | --no-collector.zfs |
--collector.disable-defaults ARGS |
Turn off every default collector; the needed ones are turned on with --collector.<name>. | --collector.disable-defaults --collector.meminfo |
--collector.textfile.directory ARGS |
The directory of *.prom files the exporter serves along with its own metrics. | --collector.textfile.directory=/var/lib/prometheus/node-exporter |
--collector.netdev.device-exclude ARGS |
A regular expression of network interfaces left out of node_network_*. | --collector.netdev.device-exclude=^(lo|veth.*)$ |
--collector.filesystem.mount-points-exclude ARGS |
A regular expression of mount points that get no node_filesystem_*; /mnt and /media are in it by default. | --collector.filesystem.mount-points-exclude=^/(dev|proc|run|sys)($|/) |
--collector.systemd.unit-include ARGS |
A regular expression of units whose state goes into node_systemd_unit_state. | --collector.systemd.unit-include=(nginx|ssh)\.service |
Nothing found. Try a shorter query.
active, a LISTEN line and a node_load1 value mean the exporter
is fine. Next, check whether Prometheus collects it:
prometheus.
On node2, turn on the exporter and check that it listens on more
than 127.0.0.1. On node1, add a target to the node job and reload
the config:
After one scrape interval up{instance="node2:9100"} should become 1.
If it is 0, the target's lastError names the cause
(prometheus).
Write to a temporary file in the same directory and rename it: mv
swaps the file as a whole, so the exporter never reads it half
written.
The script runs as root: the directory belongs to it. The exporter
skips files without the .prom extension. A "no backup for over a
day" rule is time() - backup_last_success_timestamp_seconds > 86400
(promql).
Each output line is wrapped here. A service that is not running:
node_systemd_unit_state{name="nginx.service",state="active"} == 0.
curl localhost:9100/metrics answers Failed to connect, and the
target in Prometheus is down with the error:
Nobody listens on the port. Check systemctl status
prometheus-node-exporter, then ss -tlnp | grep prometheus-node:
the exporter may listen on another port or on 127.0.0.1 only while
Prometheus goes to the external address.
Prometheus did not get an answer within scrape_timeout (10 seconds by
default). Usually a firewall on the exporter's machine silently drops
the packets: connection refused would have come at once. Check the
firewall rules for port 9100.
The journal says Deactivated successfully. The exporter has nothing
to reread: the signal reload sends makes it exit. restart applies
the ARGS flags, and start brings a stopped exporter back.
curl -s localhost:9100/metrics | grep node_network_receive is empty,
and rate(node_network_receive_bytes_total[1m]) returns nothing. A
single-VM machine has only the lo interface, and the exporter skips
it: --collector.netdev.device-exclude defaults to ^lo$. A machine
with a network interface has the series, one per device.
node_filesystem_avail_bytes{mountpoint="/mnt/data"} is empty although
df sees the volume. The mount point matches
--collector.filesystem.mount-points-exclude, which by default covers
/mnt, /media, /run and more (node-exporter). Set
your own expression in ARGS, for example
--collector.filesystem.mount-points-exclude=^/(dev|proc|run|sys)($|/),
and restart the exporter. Which mount points it sees:
curl -s localhost:9100/metrics | grep '^node_filesystem_size_bytes'.
A file in the textfile directory could not be parsed. Which one and why is in the journal:
A value line is a name, a space and a number: name 42 or
name{label="x"} 42. The exporter serves the other files of the
directory as usual.
The metrics tell a lot about the machine: the kernel version, mount
points, the list of services, network interfaces. An exporter on
*:9100 without a firewall, on a machine with a public address, gives
all this to anyone. Limit access with the listen address or a
firewall rule.
top, free,
iostat.enable --now, restart, status.node_load1 and its neighbours mean./metrics from the terminal.Found an inaccuracy? Report an error in the article