mkr wrapによるバッチ処理のロギングと監視

このエントリーは、7/27に開催される技術書博覧会で販売する「Mackrelではじめるお手軽Webサービス監視」の「バッチ処理のロギングと監視」の章のアップデート内容です。*1

gishohaku.dev

mkr wrapによるバッチ処理のロギングと監視

このエントリーでは、シェルスクリプトによるバッチ処理において、OSが提供する枠組みの中で運用に必要な仕組みを作り込み、Mackerelでの監視に組み込む方法について述べます。

なお、本章では、GNU Bashのバージョン 4.2.46(2)-release(x86_64-redhat-linux-gnu) を動作環境とし、bashインタープリターが/bin/bashであるものとして記述を行っています。

mkrコマンド

mackerelのコマンドラインツール mkrmkr wrap コマンドは、コマンドが失敗(非ゼロで終了)した場合にMackerel上にアラートを発生させます。

mkrは、mackerel向けのコマンドラインツールです。mackerel-agentの提供されているpackageレポジトリーから、yumaptコマンド等でインストールすることができます。

バッチ処理の監視に必要な要素

例外処理

特にオプションを付与していないシェルスクリプトには、個々のコマンド実行ごとにエラーハンドリングが必要です。しかし実装時の負担が大きいため、-eおよび-uオプションで、コマンドのエラー終了や未定義変数の参照などの 実行時エラーを補足できるようにします。

mkr wrapコマンドを使用することにより、-eオプションを使用して、エラー発生時にコマンドの実行を打ち切った場合にも、エラーの発生をハンドリングすることができます。

ロギングとスタックトレース

ログについては、loggerコマンドを使用してsyslogに集約します。

シェルスクリプトにはスタックトレースという機能が存在しませんが、-xオプションの出力を標準エラー出力で補足してエラー発生時にログ出力することで、処理をトレース可能にします。

実装例

以下に示す処理は、PostgreSQLのバックアップを pg_basebackupコマンドによりバックアップを行うバッチ処理の例です。

メイン処理

次のスクリプトがメイン処理の実装です。

#!/bin/bash
set -eux

DATE=$(date '+%Y%m%d%H%M%S')
su - postgres -c "/usr/pgsql-9.6/bin/pg_basebackup -D - -X f -P -F tar -z" > /var/backup/db/archive/db-archive-${DATE}.tgz

WAL_DIR="/var/backup/db/wal"
find ${WAL_DIR} -maxdepth 1 |grep "\.backup" |sort -r |head -1 |xargs -r basename |xargs -r  /usr/pgsql-9.6/bin/pg_archivecleanup -d ${WAL_DIR}

echo "postgres-backup complete"

処理内の出力は全て標準出力ないし標準エラー出力に出力します。

スクリプト内で-e-uオプションをエラー処理のために設定しています。また-xオプションでスクリプトのトレースができるようにしています。

echoコマンドによる標準出力への出力は、ログメッセージとして使用しています。

Cronの設定例

crontabの設定には、mkr wrapコマンドの引数に実行するコマンドを記述します。([@lst:code010_code02])

0 9 * * 2 mkr wrap -n postgres-backup -- /usr/local/bin/postgres-backup 2>&1 |logger -is -t postgres-backup &&  exit ${PIPESTATUS[0]}

スクリプトの標準出力及び標準エラー出力は全てloggerにパイプします。

コマンドの実行をパイプしているため、コマンド実行時のステータスはloggerコマンドの終了ステータス(通常0)です。実行するコマンドの終了するステータスをmkr wrapコマンドに反映するため、bashのPIPESTATUSを使用して、最初に実行したコマンドのステータスを返せるようにします。

CentOS6などの古い世代向けのパッケージでは、mkrコマンドは/usr/local/bin配下に インストールされます。この場合は、crontab内ではフルパスの/usr/local/bin/mkrを記述するか、 環境変数PATHを設定します。

dash環境でのパイプ処理の記述

DebianUbuntuなど、デフォルトのインタープリターがdashでありbashでない環境では、PIPESTATUSが使用できません。この場合は、moreutilsパッケージのmispipeコマンドを使用して、実行するコマンドのステータスをmkr wrapコマンドに反映できるようにします。 *2

sudo apt update
sudo apt install moreutils
08 14 * * * mkr wrap -n postgresql-backup -- mispipe "/usr/local/bin/postgresql-backup 2>&1" "logger -is -t postgresql-backup"

syslogの設定

処理のトレースなどでsyslogの出力が増えることにより、syslogd のデフォルト設定では出力の取りこぼしが発生します。

これに対応するために、[@lst:code_010_code_05]のように/etc/rsyslog.confに、$SystemLogRateLimitInterval 0を追記します。

$SystemLogRateLimitInterval 0

上記の設定を行うと、次のようにログが出力されます。

f:id:setoazusa:20190726094144p:plain

下の画面イメージは、スクリプトの実行に失敗している場合のMackerel上におけるのアラートの様子です。

f:id:setoazusa:20190726094153p:plain

*1:当日購入された方にもこの内容のペーパーをお渡しします。

*2:https://stackoverflow.com/a/54623180