diff --git a/README.md b/README.md index c48517d273965884552fe967b89b5448d3c1f0a5..b3f2628f240f203dc1c99cf726b2b80946295915 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,12 @@ Pipe logs to Mattermost or Slack webhooks # Requirements * Mattermost or Slack instance -* `tail` and `curl` in `$PATH` +* `curl`, `jq`, `tail` -## TODO - -* Config file(s) -* Init script with defaults override, restart, etc -* Make binary deps paths configurable? \ No newline at end of file +# Installation +1. `git clone https://git.ethitter.com/debian/eth-log-alerting.git /usr/local/eth-log-alerting` +2. `cp /usr/local/eth-log-alerting/init.sh /etc/init.d/eth_log_alerting` +3. `cp /usr/local/eth-log-alerting/defaults /etc/default/eth_log_alerting` +4. Edit `/etc/default/eth_log_alerting` +5. `sudo update-rc.d eth_log_alerting defaults` +6. `/etc/init.d/eth_log_alerting start` diff --git a/defaults b/defaults new file mode 100644 index 0000000000000000000000000000000000000000..cadef453ce6af25324a2a707193d73ea488dba97 --- /dev/null +++ b/defaults @@ -0,0 +1,9 @@ +LOG_FILE="" +WEBHOOK_URL="" +USERNAME="" +CHANNEL="" +COLOR="" +ICON_URL="" +GREP="" + +DAEMON_OPTIONS="$LOG_FILE $WEBHOOK_URL \"$USERNAME\" \"$CHANNEL\" \"$COLOR\" $ICON_URL \"$GREP\"" \ No newline at end of file diff --git a/init.sh b/init.sh index 3e834c4dddebbb0510756de5feac8ebfe736be3b..d4d10ad2342678b2b86ff352a84bb941a5f55c5e 100755 --- a/init.sh +++ b/init.sh @@ -1,17 +1,131 @@ #!/bin/sh -LISTENER_BIN=/usr/local/eth-log-alerting/pipe.sh -test -x $LISTENER_BIN || exit 5 -PIDFILE=/var/run/eth_log_alerting.pid +### BEGIN INIT INFO +# Provides: eth_log_alerting +# Required-Start: $network +# Required-Stop: $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Pipe log entries to Mattermost +### END INIT INFO + +# Defaults +DAEMON_NAME="ETH Log Alerting" +DAEMON_EXECUTABLE="/usr/local/eth-log-alerting/pipe.sh" +DAEMON_OPTIONS="" +DAEMON_HOMEDIR="/usr/local/eth-log-alerting" +DAEMON_PIDFILE="/var/run/eth_log_alerting.pid" +DAEMON_LOGFILE="/var/log/eth_log_alerting.log" +INIT_SLEEPTIME="2" + +# Defaults can be overridden in this file +DAEMON_DEFAULTS_FILE="/etc/default/eth_log_alerting" + +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin + +# Load alternate configuration if exists +test -f $DAEMON_DEFAULTS_FILE && . $DAEMON_DEFAULTS_FILE + +. /lib/lsb/init-functions + +# Usually no need to edit below this point. Just have these ready: +# +# * DAEMON_EXECUTABLE - full path to the executable +# * DAEMON_OPTIONS - options to pass to the executable +# * DAEMON_NAME - a decriptive name +# * DAEMON_HOMEDIR - place where to cd before running +# * DAEMON_PIDFILE - pid file name +# * DAEMON_LOGFILE - log file name +# * INIT_SLEEPTIME - how long to wait for startup and shutdown +# +# The rest will be taken care of. Executable is run with "nohup", so no +# need to fork. + +is_running () { + # Test whether pid file exists or not + test -f $DAEMON_PIDFILE || return 1 + + # Test whether process is running or not + read PID < "$DAEMON_PIDFILE" + ps -p $PID >/dev/null 2>&1 || return 1 + + # Is running + return 0 +} + +root_only () { + if [ "$(id -u)" != "0" ]; then + echo "Only root should run this operation" + exit 1 + fi +} + +run () { + if is_running; then + PID="$(cat $DAEMON_PIDFILE)" + echo "Daemon is already running as PID $PID" + return 1 + fi + + cd $DAEMON_HOMEDIR + + nohup $DAEMON_EXECUTABLE $DAEMON_OPTIONS >>$DAEMON_LOGFILE 2>&1 & + echo $! > $DAEMON_PIDFILE + read PID < "$DAEMON_PIDFILE" + + sleep $INIT_SLEEPTIME + if ! is_running; then + echo "Daemon died immediately after starting. Please check your logs and configurations." + return 1 + fi + + echo "Daemon is running as PID $PID" + return 0 +} + +stop () { + if is_running; then + read PID < "$DAEMON_PIDFILE" + kill $PID + fi + sleep $INIT_SLEEPTIME + if is_running; then + while is_running; do + echo "waiting for daemon to die (PID $PID)" + sleep $INIT_SLEEPTIME + done + fi + rm -f "$DAEMON_PIDFILE" + return 0 +} case "$1" in - start) - echo -n "Starting log alerting.... " - startproc -f -p $PIDFILE $LISTENER_BIN - echo "running" - ;; - *) - echo "Usage: $0 start" - exit 1 - ;; -esac + start) + root_only + log_daemon_msg "Starting $DAEMON_NAME" + run + log_end_msg $? + ;; + stop) + root_only + log_daemon_msg "Stopping $DAEMON_NAME" + stop + log_end_msg $? + ;; + restart) + root_only + $0 stop && $0 start + ;; + status) + status_of_proc \ + -p "$DAEMON_PIDFILE" \ + "$DAEMON_EXECUTABLE" \ + "$DAEMON_NAME" \ + && exit 0 \ + || exit $? + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac \ No newline at end of file diff --git a/pipe.sh b/pipe.sh index 7fbb3fcc787246a429c363297478a721d6e6bbb3..1eb97e7496996f471154a3d400e598b553aecb19 100755 --- a/pipe.sh +++ b/pipe.sh @@ -1,3 +1,28 @@ -#!/bin/sh -# TODO: path and config for send.sh -/usr/bin/tail -Fq log.log | while read x ; do send.sh "$x" "#errors" "danger"; done +#!/bin/bash + +# Defaults and aliases +LOG_FILE=$1 +WEBHOOK_URL=$2 +USERNAME=${3:-logbot} +CHANNEL=${4:-#logs} +COLOR=${5:-default} +ICON_URL=$6 +GREP=$7 + +tail -n0 -F "$LOG_FILE" | while read LINE; do + (echo "$LINE" | grep -e "$GREP") && jq -n --arg line_encoded " $LINE" \ "{ \ + channel: \"$CHANNEL\", \ + username: \"$USERNAME\", \ + attachments: [ { \ + fallback: \"New entry in $LOG_FILE\", \ + pretext: \"\`$LOG_FILE\`\", \ + text: \$line_encoded, \ + color: \"$COLOR\" \ + } ],\ + icon_url: \"$ICON_URL\" \ + }" | cat <(echo "payload=") <(cat -) | curl \ + -X POST \ + -s \ + -d@- \ + $WEBHOOK_URL; +done diff --git a/send.sh b/send.sh deleted file mode 100755 index b92de7edbd51170a406056fc4b6d8f8a1fd641cf..0000000000000000000000000000000000000000 --- a/send.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -MSG=${1:-Oops} -CHANNEL=${2:-#errors} -COLOR=${3:-default} - -# TODO: source these from a common config -USERNAME="Log bot" -CONTEXT="New log entry" -ICON_URL="" -WEBHOOK_URL="" - -/usr/bin/curl \ - -X POST \ - -s \ - --data-urlencode "payload={ \ - \"channel\": \"$CHANNEL\", \ - \"username\": \"$USERNAME\", \ - \"attachments\": [ { \ - \"fallback\": \"New log entry\", \ - \"pretext\": \"$CONTEXT\", \ - \"text\": \"$MSG\", \ - \"color\": \"$COLOR\" \ - } ],\ - \"icon_url\": \"$ICON_URL\" \ - }" \ - $WEBHOOK_URL