Skip to content
Snippets Groups Projects
Select Git revision
  • 79b10945aa246d43bbc7e7463d72d90fc55d391d
  • master default protected
  • extended_maintenance
3 results

error-summary.sh

Blame
  • error-summary.sh 5.58 KiB
    #!/usr/bin/env bash
    
    ### META
    # AUTHORS:
    #	- Jörg Sachse (<Joerg.Sachse@slub-dresden.de>)
    #	- Jens Steidl (<Jens.Steidl@slub-dresden.de>)
    
    #hh error_summary.sh - aggregate Rosetta Errors by error type
    #hh
    #hh Usage: error_summary.sh [-h] [-V] [-m] [-n NUM] [-d DAYS] [-w] [-c]
    #hh
    #hh Options:
    #hh	You can use the following CLI arguments to configure the behaviour of
    #hh	error-summary.sh. Please note that the CLI arguments need to be space
    #hh	separated. Combining arguments like "-cw" is currently NOT supported.
    #hh
    #hh	-h, --help
    #hh		Show this help and exit.
    #hh	-V, --version
    #hh		Show version number and exit.
    #hh	-m, --man, --manpage, --manual
    #hh		Create a manpage from this help section and exit.
    #hh		Requires "help2man".
    #hh	-M, --showman
    #hh		Print the Manpage.
    #hh		Requires "help2man".
    #hh	-n, --chars NUMBER_OF_CHARS
    #hh		Set max length of error message lines.
    #hh		Default: 200
    #hh	-d, --days NUMBER_OF_DAYS
    #hh		Set how many days back the error summary should go through the
    #hh		logs.
    #hh		Default: 10
    #hh	-w, --warn
    #hh		Count Warnings as well as Errors.
    #hh		Default: unset (only count Errors)
    #hh	-c, --class
    #hh		Instead of a fixed message length, summarize and print errors
    #hh		by their respective Java class names. If this option is set,
    #hh		"-n|--chars" is ignored.
    #hh		Defaut: unset (use message length)
    #hh
    #hh Examples:
    #hh	error-summary.sh -n 50 -w -d 15		Cut messages after 50 characters, count warnings as well, filter logs from the last 15 days.
    #hh	error-summary.sh -w -c			Count Erros AND Warnings, count messages by their respective Java class names.
    
    
    
    ### DEFAULTS
    HOW_MANY_CHARS=300
    HOW_MANY_DAYS=10
    WARN=""		# Default: do not filter for Warnings, only show Errors
    
    # get correct log path, this differs between servers
    if [[ -d "/operational_shared/logs/${HOSTNAME}.slub-dresden.de/" ]]; then
    	SERVER_LOG_DIR="/operational_shared/logs/${HOSTNAME}.slub-dresden.de/"
    else
    	SERVER_LOG_DIR="/operational_shared/logs/${HOSTNAME}/"
    fi
    
    # list external required binaries here (space separated)
    REQUIREMENTS="help2man grep sed gzip man find file sort uniq"
    for REQUIREMENT in ${REQUIREMENTS}; do
    	command -v "${REQUIREMENT}" >/dev/null 2>&1 || { echo >&2 "ERROR: '${REQUIREMENT}' required but not installed. Aborting."; exit 1; }
    done
    
    
    ### FUNCTIONS
    
    # Don't just call this function "help()", as that's a reserved command in Bash.
    comment_help() {
        sed -rn 's/^#hh ?//;T;p' "$0"
    }
    
    create_manpage(){
    	# https://www.gnu.org/software/help2man/
    	help2man --section 1 --source="SLUB Dresden" --no-info "${0}" | gzip > ./"$( basename "${0}" ".sh" ).gz"
    }
    
    show_manpage(){
    	help2man --section 1 --source="SLUB Dresden" --no-info "${0}" | man -l -
    }
    
    get_cli_args(){
    	while [[ $# -gt 0 ]]; do
    		case ${1} in
    			-h|--help)
    				comment_help
    				exit 0
    				;;
    			-V|--version)
    				echo "$( basename "${0}" ) v1.0.0"
    				echo -e "\n\nCopyright (C)\n"
    				echo "This software is licensed under the GNU General Public License version 3 (GNU GPLv3)."
    				exit 0
    				;;
    			-m|--man|--manpage|--manual)
    				create_manpage
    				exit 0
    				;;
    			-M|--showman)
    				show_manpage
    				exit 0
    				;;
    			-n|--chars)
    				HOW_MANY_CHARS="${2}"
    				shift; shift;
    				;;
    			-d|--days)
    				HOW_MANY_DAYS="${2}"
    				shift; shift;
    				;;
    			-w|--warn)
    				COUNT_WARNINGS="true"
    				shift;
    				;;
    			-c|--class)
    				PRINT_ONLY_CLASSNAMES="true"
    				shift;
    				;;
    			*)
    				echo "'${1}' is not a valid parameter. Please use '$( basename "${0}" ) --help'. Exiting."
    				exit 1
    				;;
    		esac
    	done
    }
    
    set_filter_string(){
    	if [[ "${COUNT_WARNINGS}" == "true" ]]; then
    		WARN="|WARN"
    	fi
    
    	if [[ "${PRINT_ONLY_CLASSNAMES}" == true ]]; then
    		FILTER_STRING=" (ERROR${WARN})\s+\[[^[]*\]"
    	else
    		FILTER_STRING=" (ERROR${WARN})\s+\[.{0,${HOW_MANY_CHARS}}"
    	fi
    }
    
    # thx @Steidl!
    # grep -o "STARTZEICHENKETTE..\{ANZAHL_ZEICHEN_NACH_STARTZEICHENKETTE\}" | sort | uniq -c | sort -nr
    get_last_n_days(){
    	LOGFILES="$( find "${SERVER_LOG_DIR}/" -maxdepth 1 -mtime -"${HOW_MANY_DAYS}" -name "server.log*" )"
    	for LOGFILE in ${LOGFILES}; do
    		if file -b "${LOGFILE}" | grep "gzip compressed data" > /dev/null; then
    			GREP_CMD="zgrep"
    		elif file -b "${LOGFILE}" | grep "ASCII text" > /dev/null; then
    			GREP_CMD="grep"
    		elif file -b "${LOGFILE}" | grep "UTF-8 Unicode text" > /dev/null; then
    			GREP_CMD="grep"
    		else
    			>&2 echo "ERROR: unknown filetype, cannot find error strings from file '${LOGFILE}'."
    		fi
    		${GREP_CMD} -oP "${FILTER_STRING}" "${LOGFILE}"
    	done | \
    	sed "s/Worker [0-9]*/Worker XX/g" | \
    	sed "s/Worker-[0-9]*/Worker-XX/g" | \
    	sed "s/Receiver [0-9]*/Receiver XX/g" | \
    	sed "s/IE[0-9]*/IEXXXXX/g" | \
    	sed "s/${HOSTNAME}/Rosetta-Server/g" | \
    	sed "s/lockID [0-9]*for/lockID XXXXXXXXXXfor/g" | \
    	sed "s/https-jsse-nio-8443-exec-[0-9]*/https-jsse-nio-8443-exec-XX/g" | \
    	sed "s/job [0-9]*/job XXXXXXXXX/g" | \
    	sed "s/SIP ID [0-9\.]*/SIP ID XXXXXX/g" | \
    	sed "s/SIP [0-9]*/SIP XXXXXX/g" | \
    	sed "s/FL[0-9]*/FLXXXXXX/g" | \
    	sort | uniq -c | sort -nr
    }
    
    
    
    ### MAIN
    
    get_cli_args "${@}"
    
    echo ""
    echo "USING THE FOLLOWING SETTINGS:"
    echo -e "\tSERVERNAME: '${HOSTNAME}'"
    echo -e "\tFILTERING LOGS FROM $( date -d "${HOW_MANY_DAYS} days ago" +%Y-%m-%d ) UNTIL $( date -d today +%Y-%m-%d )"
    echo -e "\tHOW MANY CHARACTERS: ${HOW_MANY_CHARS}"
    echo -en "\tCOUNT WARNINGS: "; [[ "${COUNT_WARNINGS}" == "true" ]] && echo "yes" || echo "no"
    echo ""
    echo "YOU CAN RUN THIS REPORT YOURSELF! TO FIND OUT HOW, LOGIN TO ${HOSTNAME} AND RUN:"
    echo -e "\t$( pwd )/$( basename "${0}" ) --showman"
    echo ""
    echo -n "--------------------"
    echo ""
    
    set_filter_string
    
    echo ""
    echo "REPORT LAST ${HOW_MANY_DAYS} DAYS:"
    get_last_n_days
    
    echo ""
    echo "REPORT SINCE YESTERDAY 00:00 O'CLOCK:"
    HOW_MANY_DAYS=1
    get_last_n_days