mescripts/prtg-proxmox-aio.bash
2025-07-21 14:35:48 +02:00

265 lines
8.4 KiB
Bash

#!/usr/bin/env bash
#
echo "Starting sensor setup."
monidir="/opt/monitoring"
snmpdconf="/etc/snmp/snmpd.conf"
mkdir -p "$monidir"
# Install snmp & snmpd
if apt install -y smartmontools snmp snmpd tmux vim && systemctl enable --now snmpd; then
echo "SmartMonTools, SNMP, SNMPD, tmux & vim installed."
else
echo "Something went wrong during installation of smartmontools, snmp, snmpd, tmux & vim."
exit 1
fi
# Configure snmpd
if grep -E '\brocommunity\b' "$snmpdconf" | grep -v 'rocommunity:' | grep -v public; then
echo "rocommunity password already set, check line above for details."
else
read -p "Enter the rocommunity password: " rocompw
echo "rocommunity $rocompw" >> "$snmpdconf"
fi
sed -i 's/agentaddress.*/agentaddress udp:161/' "$snmpdconf"
sed -i 's/-u Debian-snmp/-u root/' /lib/systemd/system/snmpd.service
systemctl daemon-reload
read -p "Install Ceph sensors? [y/n] " answer
case "$answer" in
[Yy]|[Yy][Ee][Ss])
echo "Installing Ceph sensors."
touch "$monidir"/snmp-ceph-free.bash
touch "$monidir"/snmp-ceph-used.bash
echo "Files touched."
echo -e "#!/bin/bash
if [ \"\$1\" = \"-g\" ]; then
echo .1.3.6.1.2.1.25.1.8
echo integer
ceph osd df | grep \"TOTAL\" | awk '{print \$12}'
fi
exit 0
# EOF" > "$monidir"/snmp-ceph-free.bash
echo "snmp-ceph-free.bash written."
echo -e "#!/bin/bash
if [ \"\$1\" = \"-g\" ]; then
echo .1.3.6.1.2.1.25.1.9
echo gauge
ceph osd df | grep \"TOTAL\" | awk '{print \$14}'
fi
exit 0
# EOF" > "$monidir"/snmp-ceph-used.bash
echo "snmp-ceph-used.bash written."
chmod u+x $monidir/*
echo "Executable flags set."
if grep -q ceph-free "$snmpdconf"; then
echo "snmp-ceph-free already added to $snmpdconf"
else
echo "pass .1.3.6.1.2.1.25.1.8 /bin/sh /opt/monitoring/snmp-ceph-free.bash" >> "$snmpdconf"
echo "Added snmp-ceph-free.bash to snmpd config."
fi
if grep -q ceph-used "$snmpdconf"; then
echo "snmp-ceph-used already added to $snmpdconf"
else
echo "pass .1.3.6.1.2.1.25.1.9 /bin/sh /opt/monitoring/snmp-ceph-used.bash" >> "$snmpdconf"
echo "Added snmp-ceph-used.bash to snmpd config."
fi
systemctl restart snmpd
echo "ceph sensor configuration done."
;;
[Nn]|[Nn][Oo]|*)
echo "Skipping Ceph sensors."
;;
esac
read -p "Install RAM sensor? [y/n] " answer
case "$answer" in
[Yy]|[Yy][Ee][Ss])
echo "Installing RAM sensor."
touch "$monidir"/snmp-memusedpercent.bash
echo "File touched."
echo -e "#!/bin/bash
#
# Real Memory Percent Calculation
total=\"\$(cat /proc/meminfo | grep 'MemTotal' | awk '{print \$2}')\"
avail=\"\$(cat /proc/meminfo | grep 'MemAvailable' | awk '{print \$2}')\"
used=\$((total - avail))
prcnt=\$(( (used * 100) / total ))
if [ \"\$1\" = \"-g\" ]; then
echo \".1.3.6.1.2.1.25.1.69\"
echo \"integer\"
echo \"\$prcnt\"
fi
exit 0
# EOF" > "$monidir"/snmp-memusedpercent.bash
echo "snmp-memusedpercent.bash written."
chmod u+x $monidir/*
echo "Executable flags set."
if grep -q memusedpercent "$snmpdconf"; then
echo "snmp-memusedpercent already added to $snmpdconf"
else
echo "pass .1.3.6.1.2.1.25.1.69 /bin/sh /opt/monitoring/snmp-memusedpercent.bash" >> "$snmpdconf"
echo "Added snmp-memusedpercent.bash to snmpd config."
fi
systemctl restart snmpd
echo "RAM sensor configuration done."
;;
[Nn]|[Nn][Oo]|*)
echo "Skipping RAM sensor."
;;
esac
read -p "Install SMART sensor? [y/n] " answer
case "$answer" in
[Yy]|[Yy][Ee][Ss])
echo "Installing SMARTEST sensor."
username="monitoring"
userhome="/home/$username"
monidir="/opt/monitoring"
prtgdir="/var/prtg/scriptsxml"
croncmd="/opt/monitoring/smartest.bash >> "$userhome"/prtg_smartest.log 2>&1"
crontime="0 * * * * $croncmd"
# Create user
if useradd -m $username; then
echo "$username created"
# Set password
read -p "Enter password for the "$username" user: " password
echo "$username:$password" | chpasswd
echo "Password set"
else
echo "$username already exists"
fi
# Create directories and files
mkdir -p $prtgdir
# Create files in user home
touch $userhome/active_disks.txt
touch $userhome/excluded_disks.txt
touch $userhome/prtg_smartest.log
touch $userhome/prtgout.xml
touch $monidir/smartest.bash
touch $prtgdir/prtg_smartest.bash
echo "Files touched."
# Change ownership of files
chown $username:$username $userhome/*
chown $username:$username $prtgdir/*
echo "Ownership changed."
# Set executable flags
chmod u+x $prtgdir/*
chmod u+x $monidir/*
echo "Executable flags set."
# Create crontab to check disks every hour
if crontab -l | grep smartest; then
echo "Cronjob already exists."
else
(crontab -l 2>/dev/null; echo "$crontime") | crontab -
echo "Cronjob created"
fi
# Write prtg_smartest.bash
echo -e "#!/usr/bin/env bash
#
cat \"/home/monitoring/prtgout.xml\"
# EOF" > $prtgdir/prtg_smartest.bash
echo "$prtgdir/prtg_smartest.bash written"
# Write smartest.bash
echo -e "#!/usr/bin/env bash
#
#Proxmox SMART Monitoring for PRTG | v2.0 Mar 2025 | exaSys AG
#
channel_id=2
output=\"/home/monitoring/prtgout.xml\"
log=\"/home/monitoring/prtg_smartest.log\"
active_disks=\"/home/monitoring/active_disks.txt\"
excluded_disks=\"/home/monitoring/excluded_disks.txt\"
disk_count_real=\"\$(lsblk -d | tail -n +2 | wc -l)\"
disk_count_current=\"\$(cat \"\$active_disks\" | wc -l)\"
if [ ! -f \"\$active_disks\" ] || [ ! -s \"\$active_disks\" ]; then
lsblk -d | awk '{print \$1}' | tail -n +2 > \"\$active_disks\"
elif [ \"\$disk_count_real\" -gt \"\$disk_count_current\" ]; then
lsblk -d | awk '{print \$1}' | tail -n +2 > \"\$active_disks\"
echo \"Disk(s) added\" >> \"\$log\" 2>&1
else
echo \"<prtg>\" > \"\$output\"
for disk in \$(cat \"\$active_disks\")
do
if grep \"\$disk\" \"\$excluded_disks\" >> \"\$log\" 2>&1; then
echo \"\$disk is excluded\" >> \"\$log\" 2>&1
elif [[ \"\$disk\" == zd* ]]; then
echo \"\$disk is a ZFS device node, excluding\" >> \"\$log\" 2>&1
elif [[ \"\$disk\" == rbd* ]]; then
echo \"\$disk is a Ceph device node, excluding\" >> \"\$log\" 2>&1
else
smartresult=\$(/usr/sbin/smartctl -a /dev/\"\$disk\")
if grep -E \"OK|PASSED\" <<< \"\$smartresult\" >> \"\$log\" 2>&1; then
echo \"\$disk is okay\" >> \"\$log\"
echo -e \"<result>\\\n<id>channel_\$channel_id</id>\\\n<channel>\$disk SMART Status</channel>\\\n<LimitMode>1</LimitMode>\\\n<LimitMinError>0.5</LimitMinError>\\\n<unit>Custom</unit>\\\n<customunit></customunit>\\\n<value>1</value>\\\n</result>\" >> \"\$output\"
channel_id=\$((channel_id + 1))
if grep -i \"Wear_Leveling_Count\" <<< \"\$smartresult\" >> \"\$log\" 2>&1; then
wlcresult=\$(/usr/sbin/smartctl -a /dev/\"\$disk\" | grep -i Wear_Leveling_Count | awk '{print \$4}' | sed 's/^0*//')
echo \"\$disk: \$wlcresult% Lifetime remaining\" >> \"\$log\" 2>&1
echo -e \"<result>\\\n<id>channel_\$channel_id</id>\\\n<channel>\$disk WLC Lifetime</channel>\\\n<LimitMode>1</LimitMode>\\\n<LimitMinWarning>25</LimitMinWarning>\\\n<LimitMinError>10</LimitMinError>\\\n<unit>Custom</unit>\\\n<customunit>%</customunit>\\\n<value>\$wlcresult</value>\\\n</result>\" >> \"\$output\"
channel_id=\$((channel_id + 1))
else
echo \"\$disk: No WLC available\" >> \"\$log\" 2>&1
fi
else
echo \"\$disk: SMART failed\" >> \"\$log\" 2>&1
echo -e \"<result>\\\n<id>channel_\$channel_id</id>\\\n<channel>\$disk SMART Status</channel>\\\n<LimitMode>1</LimitMode>\\\n<LimitMinError>0.5</LimitMinError>\\\n<unit>Custom</unit>\\\n<customunit></customunit>\\\n<value>0</value>\\\n</result>\" >> \"\$output\"
fi
fi
done
fi
echo \"</prtg>\" >> \"\$output\"
# EOF" > $monidir/smartest.bash
echo "$monidir/smartest.bash written."
chmod u+x $monidir/*
echo "Executable flags set."
echo "SMART monitoring configuration done."
# Exclude disks
read -p "Enter raw disk name to exclude (e.g. sr0) or leave empty: " exclude
if [[ -n $exclude ]]; then
echo "$exclude" >> "$userhome"/excluded_disks.txt
fi
echo "Exclusion disk list updated."
# Execute smartest.bash to populate disk list
source /opt/monitoring/smartest.bash
source /opt/monitoring/smartest.bash
echo "Active disk list populated."
;;
[Nn]|[Nn][Oo]|*)
echo "Skipping SMART sensor."
;;
esac
echo "All done."
# EOF