Skip to content

Instantly share code, notes, and snippets.

@schuhwerk
Last active December 2, 2024 18:22
Show Gist options
  • Save schuhwerk/934a8f1a7fab21a3ccc695372556989f to your computer and use it in GitHub Desktop.
Save schuhwerk/934a8f1a7fab21a3ccc695372556989f to your computer and use it in GitHub Desktop.
Log file monitoring and error reporting (via email) script.
#!/bin/bash
# Log file monitoring and error reporting (via email) script.
#
# This script monitors log files for specified error patterns and sends email alerts.
# Features:
# - Configurable file search patterns using find
# - Regex-based error detection
# - Context lines around errors
# - Consolidated email reports
# - Support for custom configuration files
#
# ⚠️ SECURITY NOTICE: This script sends log data via email. Ensure proper email security
# measures are in place as logs may contain sensitive information.
#
# Usage: ./logwatch.sh [config_file] - run without arguments to get a configuration file template.
#
# Author: Vitus Schuhwerk
# License: MIT
# Source: https://gist.github.com/schuhwerk/934a8f1a7fab21a3ccc695372556989f
# Version: 1.0.3
# Default configuration file location
CONFIG_FILE="./logwatch.config.sh"
# Function to print usage information
usage() {
echo "Usage: $0 [config_file]"
echo "Example: $0 '~/logwatch.config.sh'"
exit 1
}
# Function to load configuration
load_config() {
local config_file="${1:-$CONFIG_FILE}"
if [ ! -f "$config_file" ]; then
echo "Error: Configuration file not found: $config_file"
echo "Please create a configuration file with the following format:"
echo ""
echo "#!/bin/bash"
echo "# Configuration file for logwatch.sh. https://gist.github.com/schuhwerk/934a8f1a7fab21a3ccc695372556989f"
echo "# shellcheck disable=SC2034"
echo "FIND_FILES='/var/log/**/*.log'"
echo "EMAIL_TO='[email protected]'"
echo "EMAIL_FROM='[email protected]'"
echo "EMAIL_SUBJECT='Log Error Detection Alert'"
echo "CONTEXT_LINES=3"
echo "# Use extended regex pattern for grep (-iE)"
echo "REGEX_PATTERN='(fatal|database) error'"
exit 1
fi
# Source the configuration file
source "$config_file"
# Validate required configuration variables
local required_vars=("FIND_FILES" "EMAIL_TO" "EMAIL_FROM" "EMAIL_SUBJECT" "CONTEXT_LINES" "REGEX_PATTERN")
for var in "${required_vars[@]}"; do
if [ -z "${!var}" ]; then
echo "Error: Missing required configuration variable: $var"
exit 1
fi
done
}
# Function to validate input parameters
validate_params() {
if [ $# -gt 1 ]; then
usage
fi
if [ $# -eq 1 ]; then
CONFIG_FILE="$1"
fi
}
# Function to check if file exists and is readable
check_files() {
local files=$(ls $FIND_FILES 2>/dev/null)
if [ -z "$files" ]; then
echo "Error: No log files found matching pattern: $FIND_FILES"
exit 1
fi
}
# Function to search for errors and get context
search_errors() {
local log_file="$1"
local output_file="$2"
local grep_result
grep_result=$(grep -iE -A "$CONTEXT_LINES" -B "$CONTEXT_LINES" "$REGEX_PATTERN" "$log_file")
if [ $? -eq 0 ]; then
{
echo -e "\nErrors found in log file: $log_file"
echo "To mark this log as fixed, run:"
echo "mv \"$log_file\" \"${log_file%.*}-fixed.log\""
echo "----------------------------------------"
echo "$grep_result"
} >>"$output_file"
return 0
else
echo "----------------------------------------"
echo -e "\nNo Errors found in log file: $log_file" >>"$output_file"
return 1
fi
}
# Function to send consolidated email
send_consolidated_email() {
local error_file="$1"
local error_count="$2"
local email_body_file=$(mktemp)
if [ "$error_count" -gt 0 ]; then
# Create email body with proper headers
{
echo "From: $EMAIL_FROM"
echo "To: $EMAIL_TO"
echo "Subject: $EMAIL_SUBJECT"
echo "MIME-Version: 1.0"
echo "Content-Type: text/plain; charset=utf-8"
echo
echo "Log Monitoring Summary"
echo "Timestamp: $(date)"
echo "Search Pattern: $REGEX_PATTERN"
echo "Number of files with errors: $error_count"
echo "========================================="
echo
cat "$error_file"
} >"$email_body_file"
# Send email using sendmail
if command -v sendmail >/dev/null 2>&1; then
sendmail -t <"$email_body_file"
echo "Email alert sent with consolidated error report. $error_count file(s) with match(es)."
else
echo "Error: sendmail not found. Please install sendmail or configure an MTA."
exit 1
fi
else
echo "No errors found in any log files, not sending email."
fi
# Cleanup temporary files
rm -f "$error_file" "$email_body_file"
}
# Main execution
main() {
validate_params "$@"
load_config "$CONFIG_FILE"
check_files
local temp_file=$(mktemp)
local files_with_errors=0
echo "Starting log file analysis..." >>"$temp_file"
for log_file in $(ls $FIND_FILES 2>/dev/null); do
echo "Processing: $log_file"
if search_errors "$log_file" "$temp_file"; then
((files_with_errors++))
fi
done
send_consolidated_email "$temp_file" "$files_with_errors"
}
# Execute main function with all provided parameters
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment