Files
linux-scripts/nagios-to-prometheus-bridge.sh
chiefgeek a1a17e81a1 Sync all scripts from website downloads — 352 scripts total
Includes updated JS challenge scripts with Claude-User whitelist,
same-site referer bypass, Blackbox-Exporter allowed bot, and all
new exporters, cheat sheets, and automation scripts.
2026-05-25 03:31:08 +02:00

261 lines
7.5 KiB
Bash

#!/bin/bash
#############################################################
#### Nagios to Prometheus Bridge ####
#### Run Nagios check plugins and convert output to ####
#### Prometheus textfile collector format ####
#### ####
#### Author: Phil Connor ####
#### Contact: contact@mylinux.work ####
#### License: MIT ####
#### Version: 1.0 ####
#### ####
#### Usage: ./nagios-to-prometheus-bridge.sh [OPTIONS] ####
#############################################################
#
# Converts Nagios plugin output (exit codes + performance data)
# into Prometheus .prom files for the node_exporter textfile collector.
#
# Metrics generated:
# - nagios_check_status (exit code: 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN)
# - nagios_check_duration_seconds (execution time)
# - nagios_check_last_run_timestamp (unix timestamp)
# - nagios_check_perfdata_<label> (one gauge per performance data label)
#
# Requirements:
# - Bash 4.0+
# - Standard Linux utilities (grep, awk, sed, bc)
# - The target Nagios plugin must be installed and executable
#
set -euo pipefail
#########################
### Configuration ###
#########################
NODE_DIR="${NODE_DIR:-/var/lib/node_exporter}"
METRIC_PREFIX="${METRIC_PREFIX:-nagios_check}"
DEBUG="${DEBUG:-}"
PLUGIN_CMD=""
CHECK_NAME=""
OUTPUT_FILE=""
#########################
### Logging ###
#########################
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1" >&2
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1" >&2
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
}
log_debug() {
[[ -n "$DEBUG" ]] && echo "[DEBUG] $1" >&2
}
#########################
### Parse Arguments ###
#########################
show_help() {
cat <<EOF
Nagios to Prometheus Bridge
Runs a Nagios check plugin and converts its output to Prometheus
textfile collector format (.prom file).
Usage: $0 [OPTIONS]
OPTIONS:
--plugin "COMMAND" Nagios plugin command to execute (required)
--name NAME Check name for metric labels (required)
--output PATH Output .prom file path (default: <NODE_DIR>/<name>.prom)
--help Show this help
ENVIRONMENT:
NODE_DIR Textfile collector directory (default: /var/lib/node_exporter)
METRIC_PREFIX Metric name prefix (default: nagios_check)
DEBUG Enable debug output if set
EXAMPLES:
$0 --plugin "/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /" --name check_disk_root
$0 --plugin "/usr/local/nagios/libexec/check_memory -w 80 -c 90" --name check_memory
$0 --plugin "/usr/lib/nagios/plugins/check_http -H example.com -S -C 30" --name check_ssl --output /tmp/ssl.prom
EOF
exit 0
}
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
--plugin) PLUGIN_CMD="$2"; shift 2 ;;
--name) CHECK_NAME="$2"; shift 2 ;;
--output) OUTPUT_FILE="$2"; shift 2 ;;
--help) show_help ;;
*) log_error "Unknown option: $1"; exit 1 ;;
esac
done
if [[ -z "$PLUGIN_CMD" ]]; then
log_error "Missing required option: --plugin"
exit 1
fi
if [[ -z "$CHECK_NAME" ]]; then
log_error "Missing required option: --name"
exit 1
fi
if [[ -z "$OUTPUT_FILE" ]]; then
OUTPUT_FILE="${NODE_DIR}/${CHECK_NAME}.prom"
fi
}
#########################
### Metric Helpers ###
#########################
sanitize_name() {
local name="$1"
name="${name,,}" # lowercase
name="${name// /_}" # spaces to underscores
name=$(echo "$name" | sed 's/[^a-z0-9_]/_/g') # remove invalid chars
name=$(echo "$name" | sed 's/__*/_/g') # collapse multiple underscores
name=$(echo "$name" | sed 's/^_//; s/_$//') # trim leading/trailing underscores
echo "$name"
}
strip_unit() {
local value="$1"
# Remove common unit suffixes (MB, GB, KB, %, s, ms, us, B, etc.)
value=$(echo "$value" | sed 's/[a-zA-Z%]*$//')
echo "$value"
}
#########################
### Execute Plugin ###
#########################
run_plugin() {
log_debug "Executing: $PLUGIN_CMD"
local start_time end_time duration
local plugin_output=""
local exit_code=0
start_time=$(date +%s%N)
# Run the plugin command, capturing output and exit code
plugin_output=$(eval "$PLUGIN_CMD" 2>&1) || exit_code=$?
end_time=$(date +%s%N)
duration=$(echo "scale=3; ($end_time - $start_time) / 1000000000" | bc 2>/dev/null || echo "0")
log_debug "Exit code: $exit_code"
log_debug "Output: $plugin_output"
log_debug "Duration: ${duration}s"
# Build metrics output
local metrics=""
local timestamp
timestamp=$(date +%s)
# Status metric
metrics+="# HELP ${METRIC_PREFIX}_status Nagios check exit code (0=OK 1=WARNING 2=CRITICAL 3=UNKNOWN)
# TYPE ${METRIC_PREFIX}_status gauge
${METRIC_PREFIX}_status{check=\"${CHECK_NAME}\"} ${exit_code}
"
# Duration metric
metrics+="# HELP ${METRIC_PREFIX}_duration_seconds Time taken to execute the check
# TYPE ${METRIC_PREFIX}_duration_seconds gauge
${METRIC_PREFIX}_duration_seconds{check=\"${CHECK_NAME}\"} ${duration}
"
# Last run timestamp
metrics+="# HELP ${METRIC_PREFIX}_last_run_timestamp Unix timestamp of last check execution
# TYPE ${METRIC_PREFIX}_last_run_timestamp gauge
${METRIC_PREFIX}_last_run_timestamp{check=\"${CHECK_NAME}\"} ${timestamp}
"
# Parse performance data
local perfdata=""
if echo "$plugin_output" | grep -q '|'; then
perfdata=$(echo "$plugin_output" | sed 's/^[^|]*|//' | sed 's/^ *//')
log_debug "Perfdata raw: $perfdata"
fi
if [[ -n "$perfdata" ]]; then
# Parse each perfdata item: label=value;warn;crit;min;max
local item label raw_value value metric_name
for item in $perfdata; do
[[ "$item" == *"="* ]] || continue
label="${item%%=*}"
raw_value="${item#*=}"
# Extract the value (first field before semicolons)
value="${raw_value%%;*}"
# Strip quotes from label
label="${label//\'/}"
label="${label//\"/}"
# Strip unit suffix from value
value=$(strip_unit "$value")
# Validate value is numeric
if ! echo "$value" | grep -qE '^-?[0-9]*\.?[0-9]+$'; then
log_debug "Skipping non-numeric perfdata: $label=$value"
continue
fi
metric_name=$(sanitize_name "$label")
metrics+="# HELP ${METRIC_PREFIX}_perfdata_${metric_name} Performance data: ${label}
# TYPE ${METRIC_PREFIX}_perfdata_${metric_name} gauge
${METRIC_PREFIX}_perfdata_${metric_name}{check=\"${CHECK_NAME}\"} ${value}
"
done
fi
# Atomic write: write to temp file then move
local tmpfile
tmpfile=$(mktemp "${OUTPUT_FILE}.XXXXXX")
echo "$metrics" > "$tmpfile"
mv "$tmpfile" "$OUTPUT_FILE"
log_info "Metrics written to ${OUTPUT_FILE} (exit_code=${exit_code}, perfdata_items=$(echo "$perfdata" | wc -w))"
}
#########################
### Main ###
#########################
main() {
parse_args "$@"
# Ensure output directory exists
local output_dir
output_dir=$(dirname "$OUTPUT_FILE")
mkdir -p "$output_dir"
run_plugin
}
main "$@"