Skip to content

Instantly share code, notes, and snippets.

@Wolf480pl
Created November 13, 2023 23:45
Show Gist options
  • Save Wolf480pl/65dc7d841808058c7d67cb55a2fcfc67 to your computer and use it in GitHub Desktop.
Save Wolf480pl/65dc7d841808058c7d67cb55a2fcfc67 to your computer and use it in GitHub Desktop.
a crude script for exporting device-mapper stats from dmsetup status to prometheus
#!/bin/bash
prefix="device_mapper_status"
d_echo() {
#echo "$@" >&2
true
}
CACHE_FIELDS_FIXED="
meta_block_size meta_blocks_used meta_blocks_total
cache_block_size cache_blocks_used cache_blocks_total
read_hits read_misses write_hits write_misses
demotions promotions dirty
"
scrape_target_cache() {
local labels="$1"
local stats=$(tr '/' ' ')
set -- $stats
for field in $CACHE_FIELDS_FIXED; do
val="$1"
shift
echo "${prefix}_${field}{${labels}} ${val}"
done
# features
feature_cnt="$1"
shift
for ((i=feature_cnt; i > 0; i--)); do
feature="$1"
shift
echo "${prefix}_feature{${labels},feature=\"$feature\"} 1"
done
# core args
core_cnt="$1"
shift
for ((i=core_cnt; i > 0; i-=2)); do
key="$1"
val="$2"
shift 2
echo "${prefix}_core_arg{${labels},arg=\"$key\"} $val"
done
# policy
policy_name="$1"
shift
echo "${prefix}_policy{${labels},policy_name=\"${policy_name}\"} 1"
# policy args
policy_cnt="$1"
shift
for ((i=policy_cnt; i > 0; i-=2)); do
key="$1"
val="$2"
shift 2
echo "${prefix}_policy_arg{${labels},arg=\"$key\"} $val"
done
# meta_mode, needs_check
meta_mode="$1"
shift
for mode in rw ro; do
val=0
if [ "$mode" = "$meta_mode" ]; then
val=1
fi
echo "${prefix}_meta_mode{${labels},mode=\"$mode\"} ${val}"
done
needs_check="$1"
shift
if [ "$needs_check" = "-" ]; then
needs_check_val=0
else
needs_check_val=1
fi
echo "${prefix}_needs_check{${labels}} ${needs_check_val}"
# should be nothing left
echo "$@" |scrape_unk_target "$labels"
}
scrape_unk_target() {
local labels="$1"
local unk_args=$(wc -w)
echo "${prefix}_unknown_status_vals{${labels}} ${unk_args}"
}
scrape_device() {
local dev="$1"
while read start len type stats; do
local fun="scrape_target_${type}"
if [ "$(type -t $fun)" != "function" ]; then
d_echo "no stats for $type"
fun=scrape_unk_target
fi
local labels="dev=\"${dev}\",offset=\"${start}\",type=\"${type}\""
echo "$stats" |$fun "$labels"
done < <(dmsetup status "$dev")
}
for f in /dev/mapper/*; do
dev=$(basename "$f")
if [ "$dev" = "control" ]; then
continue
fi
d_echo "$dev" >&2
scrape_device "$dev"
done
[Unit]
Description=Collect device-mapper metrics for prometheus-node-exporter
[Service]
Type=oneshot
Environment=TMPDIR=/var/lib/prometheus/node-exporter
Environment=LC_ALL=C
[Unit]
Description=Run dm-status metrics collection every 30 seconds
ConditionPathExists=/usr/sbin/dmsetup
ConditionPathExistsGlob=|/dev/mapper/*
[Timer]
OnBootSec=0
OnUnitActiveSec=30s
[Install]
WantedBy=timers.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment