From 20724ed62fda8a858a04891664f6ed5f6ef3ddd5 Mon Sep 17 00:00:00 2001 From: Jan Philipp Timme <jan.philipp@timme.it> Date: Thu, 8 Aug 2019 17:29:15 +0200 Subject: [PATCH] Massive plugin refactoring --- .gitignore | 2 +- Readme.md | 20 +++++----- install.sh | 26 ++++++++++++ logwatch.functions.sh | 39 ++++++++++++++++++ postfix-stats.sh | 92 +++++++++++++++---------------------------- settings.sh | 4 -- 6 files changed, 107 insertions(+), 76 deletions(-) create mode 100755 install.sh create mode 100755 logwatch.functions.sh delete mode 100755 settings.sh diff --git a/.gitignore b/.gitignore index 2668ab7..98e6ef6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -current-logline.db +*.db diff --git a/Readme.md b/Readme.md index 5d357ad..663db1d 100644 --- a/Readme.md +++ b/Readme.md @@ -1,20 +1,18 @@ -# check-mk-postfix-logstats +# check-mk-logstats + +This is a collection of simple plugins for linux Check_MK agents. +They parse a bunch of logfiles and extract numbers out of them, which Check_MK can graph out for you. -This is a fairly simple plugin for linux Check_MK agents which parses your postfix logfile and returns a bunch of numbers. It might not perform ideal, feel free to adapt and improve. + ## Installation -Please note that this script needs permission to read your postfix log (`/var/log/mail.info` on Debian). -So give it appropriate permissions. +Please note that the scripts need permissions to read your logfiles, so be prepared to handle that. -* Clone this repository into e.g. `/opt/check-mk-postfix-stats`. -* Edit the `settings.sh` (just check if the path to your logfile is okay) -* Create a launcher for the plugin: -``` -echo /opt/check-mk-postfix-stats/postfix-stats.sh > /usr/lib/check_mk_agent/plugins/postfix-stats -chmod +x /usr/lib/check_mk_agent/plugins/postfix-stats -``` +* Clone this repository into e.g. `/opt/check-mk-logstats`. +* Enable the plugins you want by copying their launchers into `/usr/lib/check_mk_agent/plugins/` +* Do NOT use symlinks, the bash scripts need their real CWD! * Go into your Check_MK installation and monitor the new service That's about it. diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..bbee71e --- /dev/null +++ b/install.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +TARGET_PLUGIN_DIR="/usr/lib/check_mk_agent/plugins" + +# Enter folder where installer and plugins live +cd `dirname $0` + +# This script expects $1 to be the name of the plugin to install +if [[ "" == "$1" ]]; then + echo "Please provide the name of the plugin to install." + echo "Example: $0 postfix-stats.sh" + exit 1 +fi + +plugin_file=$1 +if [[ ! -f "$plugin_file" ]]; then + echo "Plugin file does not exist!" + exit 1 +fi + +# Plugin file should exist at this point, so let's build and install the launcher +launcher_path="$TARGET_PLUGIN_DIR/000-launch-$plugin" +plugin_path=$(pwd) +echo "$plugin_path/$plugin_file" > $launcher_path +chmod +x $launcher_path +exit 0 diff --git a/logwatch.functions.sh b/logwatch.functions.sh new file mode 100755 index 0000000..c31800b --- /dev/null +++ b/logwatch.functions.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# This function requires these variables to be set: +# $1 - Path of logfile to look at +# $2 - Path of file to store log offsets in +# This function sets these variables, which define the range of lines to look at: +# - log_start +# - log_end +function lookAtLog { + logfile=$1 + dbfile=$2 + ### First time setup (if required) + if [ ! -f "$dbfile" ]; then + # Get initial log position + log_end=$(wc -l $logfile | cut -d ' ' -f 1) + # Write initial log position + echo $log_end > $dbfile + fi + # Get old log position + log_start=$(cat $dbfile) + # Get new log position + log_end=$(wc -l $logfile | cut -d ' ' -f 1) + # Write new log position into file + echo $log_end > $dbfile + # Make sure we do not have a log rotation going on + # This is the case when log_start > log_end. + if [ $log_end -lt $log_start ]; then + # In this case we start reading the new file from its beginning + log_start=0 + fi +} + +# This function requires these variables to be set: +# $logfile - The file to inspect +# $log_start - The line offset where to start inspecting +# $log_end - The line offset where to stop inspecting +function getLogLines { + sed -n "$log_start","$log_end"p $logfile +} diff --git a/postfix-stats.sh b/postfix-stats.sh index ca86c82..0ac131e 100755 --- a/postfix-stats.sh +++ b/postfix-stats.sh @@ -1,8 +1,8 @@ #!/bin/bash # # This script is supposed to be called periodically. -# It goes through the last few lines of a logfile and counts some events. -# The events are then reported to something. +# It goes through the last few lines of a postfix mail.info log and counts events. +# The resulting numbers are then reported in the simple check_mk format. # # Debugging option @@ -11,13 +11,14 @@ # Go into appropriate directory cd `dirname $0` -DBFILE="current-logline.db" +# Include log watch functions +. ./logwatch.functions.sh -# Load configuration -. ./settings.sh +# Use helper function to get $log_start and $log_end for current log +lookAtLog "/var/log/mail.info" "postfix-stats.db" -### COUNTERS ### +### Initialize counters ### log_lines_total=0 log_lines_smtp=0 log_lines_smtpd=0 @@ -48,73 +49,44 @@ mo_dkim_signed=0 mo_dkim_unsigned=0 -### First time setup (if required) -if [ ! -f "$DBFILE" ]; then - # Get initial log position - new_log_position=$(wc -l $LOGFILE | cut -d ' ' -f 1) - # Write initial log position - echo $new_log_position > $DBFILE -fi - -### Action ### - -# Get old log position -old_log_position=$(cat $DBFILE) - -# Get new log position -new_log_position=$(wc -l $LOGFILE | cut -d ' ' -f 1) - -# Write new log position -echo $new_log_position > $DBFILE - -# Get date for new log position -db_last_modified=$(stat --terse $DBFILE | cut -d ' ' -f 13) - -# Make sure we do not have a log rotation going on -# This is visible when old_log_position > new_log_position. -if [ $new_log_position -lt $old_log_position ]; then - # In this case, we set old_log_position to 0 - old_log_position=0 -fi +### Do the statistics ### # Collect number of log lines -log_lines_total=`expr $new_log_position - $old_log_position` -log_lines_smtp=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtp\[' | wc -l) -log_lines_smtpd=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtpd\[' | wc -l) - -# Get lines and analyse them a bit, do the counting +log_lines_total=`expr $log_end - $log_start` +log_lines_smtp=$(getLogLines | grep '\/smtp\[' | wc -l) +log_lines_smtpd=$(getLogLines | grep '\/smtpd\[' | wc -l) # Collect outbound email statistics - localhost is excluded. -mo_sent=$( sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtp\[' | grep 'status=sent' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) -mo_deferred=$( sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtp\[' | grep 'status=deferred' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) -mo_deliverable=$( sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtp\[' | grep 'status=deliverable' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) -mo_undeliverable=$( sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtp\[' | grep 'status=undeliverable' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) -mo_bncd_total=$( sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtp\[' | grep 'status=bounced' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) -mo_bncd_spam=$( sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtp\[' | grep 'status=bounced' | grep -i 'spam' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) -mo_bncd_reputation=$( sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtp\[' | grep -i 'reputation' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) +mo_sent=$( getLogLines | grep '\/smtp\[' | grep 'status=sent' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) +mo_deferred=$( getLogLines | grep '\/smtp\[' | grep 'status=deferred' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) +mo_deliverable=$( getLogLines | grep '\/smtp\[' | grep 'status=deliverable' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) +mo_undeliverable=$( getLogLines | grep '\/smtp\[' | grep 'status=undeliverable' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) +mo_bncd_total=$( getLogLines | grep '\/smtp\[' | grep 'status=bounced' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) +mo_bncd_spam=$( getLogLines | grep '\/smtp\[' | grep 'status=bounced' | grep -i 'spam' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) +mo_bncd_reputation=$( getLogLines | grep '\/smtp\[' | grep -i 'reputation' | grep -v 'relay=127\.0\.0\.1\|relay=localhost\|relay=::1' | wc -l) # Collect inbound email statistics -mi_accept=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtpd\[' | grep '\/smtpd\[' | grep ': [0-9A-F]*: client=' | wc -l) -mi_reject=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtpd\[' | grep ': NOQUEUE: reject:' | wc -l) -mi_proxy_accept=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtpd\[' | grep ': proxy-accept: END-OF-MESSAGE: ' | wc -l) -mi_proxy_reject=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtpd\[' | grep ': proxy-reject: END-OF-MESSAGE: ' | wc -l) +mi_accept=$(getLogLines | grep '\/smtpd\[' | grep '\/smtpd\[' | grep ': [0-9A-F]*: client=' | wc -l) +mi_reject=$(getLogLines | grep '\/smtpd\[' | grep ': NOQUEUE: reject:' | wc -l) +mi_proxy_accept=$(getLogLines | grep '\/smtpd\[' | grep ': proxy-accept: END-OF-MESSAGE: ' | wc -l) +mi_proxy_reject=$(getLogLines | grep '\/smtpd\[' | grep ': proxy-reject: END-OF-MESSAGE: ' | wc -l) # Collect connection data -mi_connects=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtpd\[' | grep ': connect from' | wc -l) -mi_connects_tls=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep '\/smtpd\[' | grep 'Anonymous TLS connection established from' | wc -l) +mi_connects=$(getLogLines | grep '\/smtpd\[' | grep ': connect from' | wc -l) +mi_connects_tls=$(getLogLines | grep '\/smtpd\[' | grep 'Anonymous TLS connection established from' | wc -l) # Collect DMARC data -mi_dmarc_pass=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep 'opendmarc\[' | grep 'pass$' | wc -l) -mi_dmarc_fail=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep 'opendmarc\[' | grep 'fail$' | wc -l) -mi_dmarc_none=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep 'opendmarc\[' | grep 'none$' | wc -l) +mi_dmarc_pass=$(getLogLines | grep 'opendmarc\[' | grep 'pass$' | wc -l) +mi_dmarc_fail=$(getLogLines | grep 'opendmarc\[' | grep 'fail$' | wc -l) +mi_dmarc_none=$(getLogLines | grep 'opendmarc\[' | grep 'none$' | wc -l) # Collect DKIM data -mi_dkim_signed=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep 'opendkim\[' | grep 'SSL$\|message has signatures from' | wc -l) -mi_dkim_error=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep 'opendkim\[' | grep -v 'SSL$\|message has signatures from\|DKIM-Signature field added\|no signing table match for' | wc -l) -mo_dkim_signed=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep 'opendkim\['| grep 'DKIM-Signature field added' | wc -l) -mo_dkim_unsigned=$(sed -n "$old_log_position","$new_log_position"p $LOGFILE | grep 'opendkim\['| grep 'no signing table match for' | wc -l) +mi_dkim_signed=$(getLogLines | grep 'opendkim\[' | grep 'SSL$\|message has signatures from' | wc -l) +mi_dkim_error=$(getLogLines | grep 'opendkim\[' | grep -v 'SSL$\|message has signatures from\|DKIM-Signature field added\|no signing table match for' | wc -l) +mo_dkim_signed=$(getLogLines | grep 'opendkim\['| grep 'DKIM-Signature field added' | wc -l) +mo_dkim_unsigned=$(getLogLines | grep 'opendkim\['| grep 'no signing table match for' | wc -l) -# Report counter results +### Report counter results ### echo "P postfixdetails sent=$mo_sent|deferred=$mo_deferred|deliverable=$mo_deliverable|undeliverable=$mo_undeliverable|bounced=$mo_bncd_total|bounced-spam=$mo_bncd_spam|bounced-reputation=$mo_bncd_reputation|accepted=$mi_accept|proxy-accepted=$mi_proxy_accept|rejected=$mi_reject|proxy-rejected=$mi_proxy_reject|connections-in=$mi_connects|tls-connections-in=$mi_connects_tls|dmarc-pass=$mi_dmarc_pass|dmarc-fail=$mi_dmarc_fail|dmarc-none=$mi_dmarc_none|dkim-signed-in=$mi_dkim_signed|dkim-error-in=$mi_dkim_error|dkim-signed-out=$mo_dkim_signed|dkim-unsigned-out=$mo_dkim_unsigned Additional metrics related to postfix" # That's it. diff --git a/settings.sh b/settings.sh deleted file mode 100755 index b1be64c..0000000 --- a/settings.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -### Configuration ### -LOGFILE="/var/log/mail.info" -- GitLab