Last active
July 17, 2020 09:44
-
-
Save gildas/012891cba31d38245acd7d608b88d35a to your computer and use it in GitHub Desktop.
view pm2 log files through the bunyan log viewer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
shopt -s extglob | |
set -o errtrace | |
#set -o errexit | |
set +o noclobber | |
# Defaults {{{ | |
NOOP= | |
VERBOSE=${VERBOSE:0} | |
LOGVIEW_OPTS=%{LOGVIEW_OPTS:=} | |
FOLLOW=--nostream | |
TAIL=15 | |
LOGPAGER=0 | |
LOGCOLOR=--color | |
LOGTIME=-L | |
LOGFORMAT="--output short" | |
LOGLEVEL=${LOGLEVEL:=} | |
LOGFILTER= | |
# Defaults }}} | |
# DO NOT MODIFY ANYTHING AFTER THIS LINE ############################################################### | |
# General variables | |
SUBSYSTEM= | |
VERSION=1.0.0 | |
# tracing and messages {{{ | |
function trace() { [[ $VERBOSE == 2 ]] && echo -e "Trace: $@" >&2; } | |
function verbose() { [[ $VERBOSE == 1 ]] && echo -e "$@"; } | |
function warn() { echo -e "\033[33mWarning: $@\033[0m"; } | |
function error() { echo -e "\033[1;31mError: $@\033[0m" >&2; } | |
function die() { error "$1" ; exit ${2:-1} ; } | |
function die_on_error() { local status=$?; [[ $status != 0 ]] && die "$@, Error: $status" $status || return 0; } | |
# }}} | |
# Arguments {{{ | |
function usage() { # {{{2 | |
echo "$(basename $0) [options] [subsystem|pm2 id]" | |
echo " View and Interpret logs for the given subsystem" | |
echo " Subsystems can be: config, line or line_connector, pnp or pnp_provider," | |
echo " pureconnect or pureconnect_connector." | |
echo " Subsystems can also be mentioned by their pm2 id." | |
echo " " | |
echo " Options below can also be set in the environment variable LOGVIEW_OPTS. Example:" | |
echo " export LOGVIEW_OPTS=\"--follow --more --local --short\"" | |
echo " " | |
echo " Options are:" | |
echo " --condition CONDITION, --filter CONDITION, -c CONDITION" | |
echo " Runs each log message through the condition and" | |
echo " only show those that return truish. E.g.:" | |
echo " -c 'this.pid == 123'" | |
echo " -c 'this.level == DEBUG'" | |
echo " -c 'this.msg.indexOf("boom") != -1'" | |
echo " \"CONDITION\" must be legal JS code. \`this\` holds the log record." | |
echo " The TRACE, DEBUG, ... FATAL values are defined to help with " | |
echo " comparing \`this.level\`." | |
echo " --level LEVEL" | |
echo " Shows only messages at or above the specified level." | |
echo " \"LEVEL\" can be a level name or a numeric value." | |
echo " --color" | |
echo " Colorizes the output (Default)." | |
echo " --no-color" | |
echo " Does not colorize the output." | |
echo " --follow, --tail, -f " | |
echo " Follows the log file like \`tail -f\`." | |
echo " --no-follow, --no-stream, --nostream" | |
echo " Does not follow the log file." | |
echo " --lines LINES" | |
echo " Shows the last \"LINES\" lines of the log." | |
echo " --pager, --more " | |
echo " Pauses at the end of every page." | |
echo " Pipes output into \$PAGER, less, or more" | |
echo " --no-pager, --no-more " | |
echo " Does not Pause at the end of every page." | |
echo " --local, --localtime, -L" | |
echo " Shows timestamps to the local time of this machine (Default)." | |
echo " --utc" | |
echo " Shows timestamps in UTC" | |
echo " --long" | |
echo " shows more information for each log entry." | |
echo " --short" | |
echo " shows less information for each log entry (Default)." | |
echo " --help " | |
echo " Prints some help on the output." | |
echo " --quiet " | |
echo " Runs the script as silently as possible." | |
echo " --noop, --dry-run, --dryrun " | |
echo " Does not run any command that would change the state of the OS." | |
echo " Used with \`-v -v\` (yes, -v twice), it will show the actual " | |
echo " command it would execute." | |
echo " --verbose " | |
echo " Runs the script verbosely." | |
echo " --version, -V " | |
echo " Shows the version of this application." | |
echo " --yes, --assumeyes, -y " | |
echo " Answers yes to any questions automatically." | |
} # 2}}} | |
function parse_args() { # {{{2 | |
local status=0 | |
while (( "$#" )); do | |
trace "Parsing option: $1" | |
# Replace --parm=arg with --parm arg | |
[[ $1 == --*=* ]] && set -- "${1%%=*}" "${1#*=}" "${@:2}" | |
case $1 in | |
# GENERAL Stuff | |
-c|--condition|--filter) | |
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing" | |
LOGFILTER="-c '$2'" | |
shift | |
;; | |
--color) | |
LOGCOLOR="--color" | |
;; | |
--no-color|--no_color) | |
LOGCOLOR="--no-color" | |
;; | |
-f|--follow|--tail) | |
FOLLOW= | |
;; | |
--lines) | |
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing" | |
TAIL=$2 | |
shift | |
;; | |
--no-follow|--no-stream|--nostream) | |
FOLLOW="--nostream" | |
;; | |
--pager|--more) | |
LOGPAGER=1 | |
;; | |
--no-pager|--no-more) | |
LOGPAGER=0 | |
;; | |
-L|--local|--localtime|--local_time|--local-time) | |
LOGTIME=-L | |
;; | |
--utc|--UTC) | |
LOGTIME= | |
;; | |
-l|--level) | |
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing" | |
LOGLEVEL="--level $2" | |
shift | |
;; | |
--long) | |
LOGFORMAT="--output long" | |
;; | |
--short) | |
LOGFORMAT="--output short" | |
;; | |
# Standard options | |
-h|-\?|--help) | |
usage | |
exit 0 | |
;; | |
--noop|--dry_run|--dry-run) | |
warn "This program will execute in dry mode, your system will not be modified" | |
NOOP=: | |
;; | |
--quiet) | |
VERBOSE=0 | |
;; | |
-v|--verbose) | |
VERBOSE=$((VERBOSE + 1)) | |
;; | |
--version|-V) | |
echo "$(basename $0) version $VERSION" | |
exit 0 | |
;; | |
-?*) # Invalid options | |
warn "Unknown option $1 will be ignored" | |
;; | |
--) # Force end of options | |
shift | |
break | |
;; | |
*) # End of options | |
ARGS+=( "$1" ) | |
break | |
;; | |
esac | |
shift | |
done | |
# Set all positional arguments back in the proper order | |
eval set -- "${ARGS[@]}" | |
# Validations | |
trace "$# Positional arguments: $@" | |
[[ $# < 1 ]] && die "Missing subsystem name or id" | |
SUBSYSTEM=$1 | |
return 0 | |
} # 2}}} | |
# }}} | |
function main() { # {{{ | |
parse_args "$@" ; status=$? && [[ $status != 0 ]] && die "Failed to parse command line, error: $status" $status | |
# Seems like --pager does not work with bunyan, so let's DIY!!! | |
if [[ $LOGPAGER == 1 ]]; then | |
if command -v less; then | |
LOGPAGER=${PAGER:-less} | |
else | |
LOGPAGER=${PAGER:-more} | |
fi | |
trace "pm2 logs --raw --lines=$TAIL $FOLLOW $SUBSYSTEM | bunyan $LOGCOLOR $LOGTIME $LOGLEVEL $LOGFILER $LOGFORMAT | $LOGPAGER" | |
$NOOP pm2 logs --raw --lines=$TAIL $FOLLOW $SUBSYSTEM | bunyan $LOGCOLOR $LOGTIME $LOGLEVEL $LOGFILER $LOGFORMAT | $LOGPAGER | |
else | |
trace "pm2 logs --raw --lines=$TAIL $FOLLOW $SUBSYSTEM | bunyan $LOGCOLOR $LOGTIME $LOGLEVEL $LOGFILER $LOGFORMAT" | |
$NOOP pm2 logs --raw --lines=$TAIL $FOLLOW $SUBSYSTEM | bunyan $LOGCOLOR $LOGTIME $LOGLEVEL $LOGFILER $LOGFORMAT | |
fi | |
die_on_error "Failed to view log $SUBSYSTEM" | |
exit 0 | |
} # }}} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment