wiki:NginxLogWatch

Version 1 (modified by chris, 3 years ago) (diff)

--

This is a very crude script to grep Nginx logs for 50x errors, it is run via logrotate, see below.

nginx-logwatch

#!/bin/bash

# The log file we are checking, best run the script via logrotate,
# for example edit /etc/logrotate.d/nginx to:
#
#   prerotate
#          /usr/local/bin/nginx-logwatch chris@webarchitects.co.uk
#          if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
#                  run-parts /etc/logrotate.d/httpd-prerotate; \
#          fi \
#   endscript

# check that the script is being run by root
if [[ "$(id -u)" != "0" ]] ; then
  echo "You must run $0 as root or via sudo" 
  exit 2
fi

# check for a logfile on standard input 
if [[ $1 ]]; then
  LOGFILE=$1
elif [[ ! $1 ]]; then
  echo "You need to provide the logfile as the first argument, eg:"
  echo "$0 /var/log/nginx/crin.org.access.log"
  exit
fi

# Optional email address to send the results to
EMAIL=$2

# grep for all the lines with error codes  
#ERRORS=$(grep '1.[0|1]" [4|5]0[2|3|4] ' $LOGFILE)
#ERRORS=$(grep '1.[0|1]" [4|5]0[2|3|4] ' $LOGFILE)
ERRORS=$(grep '1.[0|1]" 50[2|3|4] ' $LOGFILE)
# grep for to totals for these errors codes 
#ERRORS_403=$(grep -c '1.[0|1]" 403 ' $LOGFILE)
#ERRORS_404=$(grep -c '1.[0|1]" 404 ' $LOGFILE)
ERRORS_502=$(grep -c '1.[0|1]" 502 ' $LOGFILE)
ERRORS_503=$(grep -c '1.[0|1]" 503 ' $LOGFILE)
ERRORS_504=$(grep -c '1.[0|1]" 504 ' $LOGFILE)

# check to see if any errors were found
if [[ $ERRORS ]]; then
  # check for a email address 
  if [[ $EMAIL ]]; then
    # name of the server
    HOSTNAME=$(hostname)
    # email subject line
    #SUBJECT="$ERRORS_403 403, $ERRORS_404 404, $ERRORS_502 502, $ERRORS_503 503 and $ERRORS_504 504 errors from $HOSTNAME"
    #SUBJECT="$ERRORS_403 403, $ERRORS_502 502, $ERRORS_503 503 and $ERRORS_504 504 errors from $HOSTNAME"
    SUBJECT="$ERRORS_502 502, $ERRORS_503 503 and $ERRORS_504 504 errors from $HOSTNAME"
    # we were supplied with a email address so send the results by email using mutt
    echo "$ERRORS" | mutt -s "$SUBJECT" $EMAIL
  # we don't have a email address so display the results of the grep
  else [[ ! $EMAIL ]]
    echo "Supply a email address on the command line to send the following results by email" 
    echo ""
    #echo "Total 403 errors: $ERRORS_403"
    #echo "Total 404 errors: $ERRORS_404"
    echo "Total 502 errors: $ERRORS_502"
    echo "Total 503 errors: $ERRORS_503"
    echo "Total 504 errors: $ERRORS_504"
    echo ""
    echo "Lines with errors from $LOGFILE"
    echo ""
    echo "$ERRORS" 
    echo ""
    echo "This script is best piped into a pager, eg:"
    echo "$0 | less"
  fi
else
   # we don't want any output if a email address is specified as the script is run via cron
   if [[ ! $EMAIL ]] ; then
     #echo "No recent 403, 404, 502, 503 or 504 errors were found" 
     #echo "No recent 403, 502, 503 or 504 errors were found" 
     echo "No recent 502, 503 or 504 errors were found" 
   fi
fi

/etc/logrotate.d/nginx

/var/log/nginx/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                /usr/local/bin/nginx-logwatch /var/log/nginx/crin.org.ssl_access.log root@localhost
                /usr/local/bin/nginx-logwatch /var/log/nginx/crin.org.access.log root@localhost
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate >/dev/null 2>&1
        endscript
}/var/log/nginx/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                /usr/local/bin/nginx-logwatch /var/log/nginx/crin.org.ssl_access.log root@localhost
                /usr/local/bin/nginx-logwatch /var/log/nginx/crin.org.access.log root@localhost
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate >/dev/null 2>&1
        endscript
}