123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- #!/usr/bin/env bash
- # Turn on extended globbing
- shopt -s extglob
- # Bail on any error
- set -e
- prog=$(basename $0)
- print_help() {
- cat <<EOF
- NAME
- $prog - Gather asterisk log files
- SYNOPSIS
- $prog [ --help ] [ --dateformat="<dateformat>" ]
- [ --timezone="<timezone>" ] [ --append-logfiles ]
- [ --tarball-uniqueid="<uniqueid>" ]
- [ <logfiles> | <pattern> ... ]
- DESCRIPTION
- Gathers log files, optionally converts POSIX timestamps
- to readable format. and creates a tarball.
- Options:
- --help
- Print this help.
- --dateformat="<dateformat>"
- A Python strftime format string to be used when converting
- POSIX timestamps in log files to readable format. If not
- specified as an argument or in the config file, no conversion
- is done.
- --timezone="<timezone>"
- The timezone to use when converting POSIX timestamps to
- readable format. It can be specified in "<continent>/<city>"
- format or in abbreviation format such as "CST6CDT". If not
- specified as an argument or in the config file, the "local"
- timezone is used.
- --append-logfiles
- Append any log files specified on the command line to the
- config file specified ones instead of overriding them.
- --tarball-uniqueid="<uniqueid>"
- Normally DATEFORMAT is used to make the tarballs unique
- but you can use your own unique id in the tarball names
- such as a Jira issue id.
- <logfiles> | <pattern>
- A list of log files or log file search patterns. Unless
- --append-logfiles was specified, these entries will override
- those specified in the config files.
- If no files are specified on the command line the, value of
- LOGFILES from ast_debug_tools.conf will be used. Failing
- that, the following patterns will be used:
- /var/log/asterisk/messages*
- /var/log/asterisk/queue*
- /var/log/asterisk/debug*
- /var/log/asterisk/security*
- NOTES
- Any files output will have ':' characters changed to '-'. This is
- to facilitate uploading those files to Jira which doesn't like the
- colons.
- FILES
- /etc/asterisk/ast_debug_tools.conf
- ~/ast_debug_tools.conf
- ./ast_debug_tools.conf
- # Readable Local time for the tarball names
- DATEFORMAT='date +%FT%H-%M-%S%z'
- # A list of log files and/or log file search patterns using the
- # same syntax as COREDUMPS.
- #
- LOGFILES=(/var/log/asterisk/messages* /var/log/asterisk/queue* \\
- /var/log/asterisk/debug* /var/log/asterisk/security*)
- # $prog converts POSIX timestamps to readable format
- # using this Python strftime format string. If not specified
- # or an empty string, no format covnersion is done.
- LOG_DATEFORMAT="%m/%d %H:%M:%S.%f"
- # The timezone to use when converting POSIX timestamps to
- # readable format. It can be specified in "<continent>/<city>"
- # format or in abbreviation format such as "CST6CDT". If not
- # specified, the "local" timezone is used.
- # LOG_TIMEZONE=
- EOF
- exit 1
- }
- append_logfiles=false
- declare -a LOGFILES
- declare -a ARGS_LOGFILES
- # Read config files from least important to most important
- [ -f /etc/asterisk/ast_debug_tools.conf ] && source /etc/asterisk/ast_debug_tools.conf
- [ -f ~/ast_debug_tools.conf ] && source ~/ast_debug_tools.conf
- [ -f ./ast_debug_tools.conf ] && source ./ast_debug_tools.conf
- if [ ${#LOGFILES[@]} -eq 0 ] ; then
- LOGFILES+=(/var/log/asterisk/messages* /var/log/asterisk/queue* \
- /var/log/asterisk/debug* /var/log/asterisk/security*)
- fi
- DATEFORMAT=${DATEFORMAT:-'date +%FT%H-%M-%S%z'}
- # Use "$@" (with the quotes) so spaces in patterns or
- # file names are preserved.
- # Later on when we have to iterate over LOGFILES, we always
- # use the indexes rather than trying to expand the values of LOGFILES
- # just in case.
- for a in "$@" ; do
- case "$a" in
- --dateformat=*)
- LOG_DATEFORMAT=${a#*=}
- ;;
- --timezone=*)
- LOG_TIMEZONE=${a#*=}
- ;;
- --append-logfiles)
- append_logfiles=true
- ;;
- --tarball-uniqueid=*)
- tarball_uniqueid=${a#*=}
- ;;
- --help|-*)
- print_help
- ;;
- *)
- ARGS_LOGFILES+=("$a")
- # If any files are specified on the command line, ignore those
- # specified in the config files unless append-logfiles was specified.
- if ! $append_logfiles ; then
- LOGFILES=()
- fi
- esac
- done
- # append logfiles/patterns specified as command line arguments to LOGFILES.
- for i in ${!ARGS_LOGFILES[@]} ; do
- LOGFILES+=("${ARGS_LOGFILES[$i]}")
- done
- # At this point, all glob entries that match files should be expanded.
- # Any entries that don't exist are probably globs that didn't match anything
- # and need to be pruned.
- for i in ${!LOGFILES[@]} ; do
- if [ ! -f "${LOGFILES[$i]}" ] ; then
- unset LOGFILES[$i]
- continue
- fi
- done
- # Sort and weed out any dups
- IFS=$'\x0a'
- readarray -t LOGFILES < <(echo -n "${LOGFILES[*]}" | sort -u )
- unset IFS
- if [ "${#LOGFILES[@]}" -eq 0 ] ; then
- echo "No log files found"
- print_help
- fi
- # Timestamp to use for output files
- df=${tarball_uniqueid:-$(${DATEFORMAT})}
- # Extract the Python timestamp conver script from the end of this
- # script and save it to /tmp/.ast_tsconvert.py
- ss=`egrep -n "^#@@@SCRIPTSTART@@@" $0 |cut -f1 -d:`
- tail -n +${ss} $0 >/tmp/.ast_tsconvert.py
- tmpdir=$(mktemp -d)
- if [ -z "$tmpdir" ] ; then
- echo "${prog}: Unable to create temporary directory."
- exit 1
- fi
- trap "rm -rf $tmpdir" EXIT
- tardir=asterisk-${df}.logfiles
- # Now iterate over the logfiles
- for i in ${!LOGFILES[@]} ; do
- lf=${LOGFILES[$i]}
- destdir="$tmpdir/$tardir/$(dirname $lf)"
- destfile="$tmpdir/$tardir/$lf"
- mkdir -p "$destdir" 2>/dev/null || :
- if [ -n "$LOG_DATEFORMAT" ] ; then
- echo "Converting $lf"
- cat "$lf" | python /tmp/.ast_tsconvert.py --format="$LOG_DATEFORMAT" --timezone="$LOG_TIMEZONE" > "${destfile}"
- else
- echo "Copying $lf"
- cp "$lf" "${destfile}"
- fi
- done
- echo "Creating /tmp/$tardir.tar.gz"
- tar -czvf /tmp/$tardir.tar.gz -C $tmpdir $tardir 2>/dev/null
- exit
- # Be careful editng the inline scripts.
- # They're space-indented.
- # We need the python bit because lock_infos isn't
- # a valid symbol in asterisk unless DEBUG_THREADS was
- # used during the compile. Also, interrupt and continue
- # are only valid for a running program.
- #@@@SCRIPTSTART@@@
- import argparse
- import datetime as dt
- import dateutil.tz as tz
- import re
- import sys
- import time
- parser = argparse.ArgumentParser(description="Make POSIX timestamps readable")
- parser.add_argument('--format', action='store', required=True)
- parser.add_argument('--timezone', action='store', required=False)
- args=parser.parse_args()
- # We only convert timestamps that are at the beginning of a line
- # or are preceeded by a whilespace character or a '['
- rets = re.compile(r'(^|(?<=\s|\[))\d+(\.\d+)?', flags=re.M)
- if args.timezone and len(args.timezone) > 0:
- tzf = tz.tzfile('/usr/share/zoneinfo/' + args.timezone)
- else:
- tzf = tz.tzfile('/etc/localtime')
- now = time.time()
- a_year_ago = now - (86400.0 * 365)
- def convert(match):
- ts = float(match.group(0))
- if ts <= now and ts > a_year_ago and len(args.format) > 0:
- return dt.datetime.fromtimestamp(ts, tzf).strftime(args.format)
- else:
- return match.group(0)
- while 1:
- line = sys.stdin.readline()
- if not line:
- break
- print(rets.sub(convert, line))
|