a1a17e81a1
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.
261 lines
7.5 KiB
Bash
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 "$@"
|