Select Git revision
error-summary.sh

Jens Steidl authored
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