はじめに
トラブった時のために、cronで実行するコマンドのログを取りたい場合があると思いますが、調べても別ファイルへリダイレクトするパターンしか出てこなかったため、rsyslog経由で出力する方法を備忘として記しておきます。
方向性としては、cronで実行したコマンドの出力をlogger
へ渡してあげます。出力先等はlogger
とrsyslog
のチューニングで制御します。
他のログと関連を対比したり、タイムスタンプを簡単に付与できることがメリットかと思います。
実行環境
raspberry pi OSをraspberry pi初代で実行しています。
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
cronのデフォルト仕様
実行結果を標準出力で出力するスクリプトtest.sh
を一分毎に実行させてみます。
* * * * * /bin/bash /home/qiita_user/test.sh
cronのデフォルトでは、標準出力はメールで送信する仕様になっているようです。(当環境ではメールソフトがないため、送信されずにエラーが記録されています)
Feb 11 21:54:02 raspberrypi CRON[3480]: (qiita_user) CMD (/bin/bash /home/qiita_user/test.sh)
Feb 11 21:54:02 raspberrypi CRON[3479]: (CRON) info (No MTA installed, discarding output)
rsyslogの設定
ログが意図したとおりにルーティングされるよう設定します。
今回は、/var/log/syslog
へ出力したいため、設定変更はせずデフォルトのままとしました。(*.*にマッチするようcron.infoをloggerで指定します)
#
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
#cron.* /var/log/cron.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
lpr.* -/var/log/lpr.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
#
# Logging for the mail system. Split it up so that
# it is easy to write scripts to parse these files.
#
mail.info -/var/log/mail.info
mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
#
# Some "catch-all" log files.
#
*.=debug;\
auth,authpriv.none;\
mail.none -/var/log/debug
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail.none -/var/log/messages
#
# Emergencies are sent to everybody logged in.
#
*.emerg :omusrmsg:*
rsyslog設定についてはオプションが多岐にわたるため、詳しくは下記文献を参照してください。
https://qiita.com/11ohina017/items/087b1b7c4411c3b3195a
https://milestone-of-se.nesuke.com/l7protocol/syslog/rsyslog-summary/
https://qiita.com/sugar_salt75/items/1d1980d5b66becc9f38f
loggerの設定
cronの設定で、スクリプトの標準出力をlogger
へパイプで渡します。
何も設定しない場合は/var/log/messages
に実行ユーザ名で記録されます。
* * * * * /bin/bash /home/qiita_user/test.sh | logger
Feb 12 00:23:38 raspberrypi qiita_user: test message
今回は、/var/log/syslog
へcronで実行されたスクリプトの出力と認識できる形にしたいため、下記のように設定しました。
* * * * * /bin/bash /home/qiita_user/test.sh 2>&1 | logger -p cron.info -t "CRON( test.sh )"
-pでファシリティを、-tでタグを指定しています。
Feb 12 00:18:01 raspberrypi CRON[5613]: (qiita_user) CMD (/bin/bash /home/qiita_user/test.sh 2>&1 | logger -p cron.info -t "CRON( test.sh )")
Feb 12 00:18:01 raspberrypi CRON( test.sh ): LTE SCRIPT DONE
loggerコマンドについてはオプションが多岐にわた(略
https://qiita.com/mykysyk@github/items/e5398bc8262d35f4a1b9
https://www.ibm.com/docs/ja/zos/2.3.0?topic=descriptions-logger-log-messages
パイプについては手技が多岐にわた(略
https://qiita.com/task4233/items/1f5ba68e8fed430f6f9f#%E3%83%91%E3%82%A4%E3%83%97%E3%82%92%E5%90%AB%E3%82%93%E3%81%A0%E4%BE%8B
https://atmarkit.itmedia.co.jp/ait/articles/1603/24/news018_4.html
別ファイルに出力する方法(番外編)
単純にリダイレクトするだけ(スクリプト内でリダイレクトしても○)
* * * * * /bin/bash /home/qiita_user/test.sh >> /var/log/script_log 2>&1 #追記
* * * * * /bin/bash /home/qiita_user/test.sh > /var/log/script_log 2>&1 #上書き
リダイレクトについては手技が多岐にわた(略
https://qiita.com/r18j21/items/0e7d0e48c02d14ed9893
https://qiita.com/laikuaut/items/e1cc312ffc7ec2c872fc
まとめ
とある処理が落ちてしまうという問題で、cronで実行させているスクリプトが悪さしている疑惑があり、関連性を確認しやすくするため、loggerを使用してrsyslogへのログ出力を試みました。
定期実行するスクリプトのログ出力といえば、exec等を駆使してタイムスタンプを付与した上で出力していましたが、rsyslogに新規ルールを追加して出力させたほうがスマートでは?と書いていて思いました。(関係性が複雑になる、可読性の低下等のデメリットは想定されますが....)