zfs_host: zed and pool capacity and scrub metrics for the node exporter textfile collector
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
# Directory the node exporter reads textfile metrics from (the Debian default).
|
||||||
|
zfs_host_textfile_dir: /var/lib/prometheus/node-exporter
|
||||||
|
zfs_host_metrics_interval: 5min
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
# ZFS event daemon and pool metrics for the node exporter. zed keeps its default zed.rc and
|
||||||
|
# logs to the journal, which journal_upload ships.
|
||||||
|
- name: Install the ZFS event daemon
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: zfs-zed
|
||||||
|
install_recommends: false
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Enable the ZFS event daemon
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: zfs-zed
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
# Check mode does not install the package.
|
||||||
|
ignore_errors: "{{ ansible_check_mode }}"
|
||||||
|
|
||||||
|
- name: Install the pool metrics script
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: zfs-pool-metrics.j2
|
||||||
|
dest: /usr/local/sbin/zfs-pool-metrics
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Install the pool metrics units
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ item }}.j2"
|
||||||
|
dest: /etc/systemd/system/{{ item }}
|
||||||
|
mode: "0644"
|
||||||
|
loop:
|
||||||
|
- zfs-pool-metrics.service
|
||||||
|
- zfs-pool-metrics.timer
|
||||||
|
register: zfs_host_units
|
||||||
|
|
||||||
|
- name: Enable the pool metrics timer
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: zfs-pool-metrics.timer
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
daemon_reload: "{{ zfs_host_units.changed }}"
|
||||||
|
# Check mode does not write the units.
|
||||||
|
ignore_errors: "{{ ansible_check_mode }}"
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Pool capacity and the last scrub for the node exporter textfile collector.
|
||||||
|
# A scrub in progress or cancelled keeps the previous end time: the pool has no newer completed scrub.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
dir={{ zfs_host_textfile_dir }}
|
||||||
|
out=$dir/zfs_pool.prom
|
||||||
|
tmp=$(mktemp "$dir/.zfs_pool.XXXXXX")
|
||||||
|
trap 'rm -f "$tmp"' EXIT
|
||||||
|
|
||||||
|
# Value of a metric line of the previous run, 0 if there is none.
|
||||||
|
previous() {
|
||||||
|
awk -v m="$1" -v p="$2" 'index($0, m "{pool=\"" p "\"}") == 1 {v = $2} END {print v + 0}' "$out" 2>/dev/null || echo 0
|
||||||
|
}
|
||||||
|
|
||||||
|
status=$(zpool status -p)
|
||||||
|
{
|
||||||
|
echo '# TYPE zfs_pool_size_bytes gauge'
|
||||||
|
echo '# TYPE zfs_pool_allocated_bytes gauge'
|
||||||
|
echo '# TYPE zfs_pool_fragmentation_ratio gauge'
|
||||||
|
zpool list -Hp -o name,size,allocated,fragmentation | while IFS=$'\t' read -r pool size alloc frag; do
|
||||||
|
echo "zfs_pool_size_bytes{pool=\"$pool\"} $size"
|
||||||
|
echo "zfs_pool_allocated_bytes{pool=\"$pool\"} $alloc"
|
||||||
|
if [[ $frag =~ ^[0-9]+$ ]]; then
|
||||||
|
echo "zfs_pool_fragmentation_ratio{pool=\"$pool\"} $(awk -v f="$frag" 'BEGIN {print f / 100}')"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo '# TYPE zfs_pool_scrub_end_timestamp_seconds gauge'
|
||||||
|
echo '# TYPE zfs_pool_scrub_errors gauge'
|
||||||
|
zpool list -Hp -o name | while read -r pool; do
|
||||||
|
scan=$(awk -v p="$pool" '$1 == "pool:" {cur = $2} cur == p && $1 == "scan:" {sub(/^[ \t]*scan:[ \t]*/, ""); print; exit}' <<< "$status")
|
||||||
|
end=0
|
||||||
|
errors=0
|
||||||
|
if [[ $scan =~ ^scrub\ repaired\ .*\ with\ ([0-9]+)\ errors\ on\ (.+)$ ]]; then
|
||||||
|
errors=${BASH_REMATCH[1]}
|
||||||
|
end=$(date -d "${BASH_REMATCH[2]}" +%s)
|
||||||
|
elif [[ $scan =~ ^scrub\ (in\ progress|canceled) ]]; then
|
||||||
|
end=$(previous zfs_pool_scrub_end_timestamp_seconds "$pool")
|
||||||
|
errors=$(previous zfs_pool_scrub_errors "$pool")
|
||||||
|
fi
|
||||||
|
echo "zfs_pool_scrub_end_timestamp_seconds{pool=\"$pool\"} $end"
|
||||||
|
echo "zfs_pool_scrub_errors{pool=\"$pool\"} $errors"
|
||||||
|
done
|
||||||
|
} > "$tmp"
|
||||||
|
|
||||||
|
chmod 0644 "$tmp"
|
||||||
|
mv "$tmp" "$out"
|
||||||
|
trap - EXIT
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=ZFS pool metrics for the node exporter textfile collector
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/sbin/zfs-pool-metrics
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=ZFS pool metrics for the node exporter textfile collector
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnBootSec=1min
|
||||||
|
OnUnitActiveSec={{ zfs_host_metrics_interval }}
|
||||||
|
AccuracySec=10s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
Reference in New Issue
Block a user