とーますメモ

Ruby on Rails / Goなどの学習メモ

【PHP】エラーログが出たら、Slackに通知を送る設定

SwatchやLogwatchなんかを使うのが定番っぽいが
Swatchは監視対象が複数ある場合は、複数のプロセスが常時立ち上がるのと
長い間更新されていないのが不安だったので断念。
Logwatchの場合は、別にこれでも良かったが、Postfixがデフォルトでインストールされるのが嫌だったので、自作のシェルスクリプトをcronで回すことにした。

WEBHOOK_URLとPHP_LOG_PATHは、任意のものを指定し、CHANNELやICONなんかも必要に応じて変更する。

#!/bin/bash

# 件名
RE_LOG_LEVEL="WARNING|ERROR|ALERT"
MAIL_SUBJECT="[Notification] Found PHP Error! ($RE_LOG_LEVEL)"

# 本文に使用する一時ファイルを指定する
MESSAGEFILE=$(mktemp -t webhooks.XXXX)

# 終了時に一時ファイルを削除
trap "
rm ${MESSAGEFILE}
" 0

# 本文を生成
PHP_LOG_PATH='/var/log/php7.2-fpm.log'
sudo tail $PHP_LOG_PATH >> $MESSAGEFILE

INFO='good'
WARN='warning'
ERROR='danger'

CHANNEL="#general"
ICON=":rotating_light:"

TS=`date "+%s"`
TODAY=`date "+%d-%b-%Y"`
RE_TODAY=`echo ${TODAY//\-/\\\-}`
MESSAGE=`cat ${MESSAGEFILE} | grep -E "^\[$RE_TODAY.*?\] ($RE_LOG_LEVEL)"`

WARNING_COUNT=`cat ${MESSAGEFILE} | grep -c "WARNING"`
ERROR_COUNT=`cat ${MESSAGEFILE} | grep -c "ERROR"`
ALERT_COUNT=`cat ${MESSAGEFILE} | grep -c "ALERT"`

WEBHOOK_URL="https://hooks.slack.com/services/XXXXX....."

if [ -n "$MESSAGE" ]; then
  data=`cat << EOF
    payload={
      "text": "$MAIL_SUBJECT",
      "channel": "$CHANNEL",
      "username": "$HOSTNAME",
      "icon_emoji": "$ICON",
      "link_names": 1 ,
      "attachments": [{
        "fallback": "[Notification]",
        "title": "[WARNING]: $WARNING_COUNT    [ERROR]: $ERROR_COUNT    [ALERT]: $ALERT_COUNT",
        "pretext": "\\\`AUTO MESSAGE\\\`",
        "text": "$MESSAGE",
        "color": "$ERROR",
        "mrkdwn_in": ["text", "pretext"],
        "footer": "created at",
        "footer_icon": "https://platform.slack-edge.com/img/default_application_icon.png",
        "ts": $TS
      }]
    }
EOF`

  # メッセージ送信
  curl -X POST --data-urlencode "$data" $WEBHOOK_URL
fi

exit 0;

あとはこのスクリプトをcron設定すればOK
thoames.hatenadiary.jp