よっしー
こんにちは。よっしーです(^^)
今日は、bashにおけるlogging(ロギング)についてご紹介します。
背景
bashにおけるlogging(ロギング)について調査する機会があったので、そのときの内容を備忘として残しました。
この記事のソースは下記のサイトにアップしています。
実行環境について
実行環境は下記の記事を参考にお願いします。
概要
本記事のロギングは、デバッグとエラーで使い分けるようにしました。
作成ファイル一覧
下記のファイルを作成しました。
new file: local/work/09_logging/09_logging.sh
09_logging.sh
#!/usr/bin/env bash
set -euCo pipefail
readonly LOG_OUT=./stdout.log
readonly LOG_ERR=./stderr.log
exec 1> >(tee -a "$LOG_OUT")
exec 2> >(tee -a "$LOG_ERR")
function log_debug() {
log 'DEBUG' "$*"
}
function log_err() {
log 'ERROR' "$*"
}
function log() {
printf "%s\t[%5s]\t%s\n" "$(date '+%Y/%m/%d %H:%M:%S.%3N')" "$1" "$2"
}
function trap_err() {
error_status=$?
msg=$(printf "エラー発生 \$?=%d %s %s:%d" ${error_status} "${BASH_SOURCE[0]}" "${FUNCNAME[1]}" ${BASH_LINENO[0]})
log_err "${msg}"
}
trap trap_err ERR
log_debug "$(which bash)"
log_debug "$(bash --version)"
# 標準エラーへの出力確認用
ls dummy.txt
echo "ここは表示されない"
動作確認
下記のコマンドを実行します。
make build
make up
make login
cd 09_logging
chmod +x 09_logging.sh
./09_logging.sh
strout.logにも同様のエラー文言が出力されている想定です。
root@47ba55e738ee:/work/09_logging# ./09_logging.sh
2023/12/10 08:22:31.297 [DEBUG] /usr/bin/bash
2023/12/10 08:22:31.302 [DEBUG] GNU bash, version 5.2.15(1)-release (aarch64-unknown-linux-gnu)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
ls: cannot access 'dummy.txt': No such file or directory
2023/12/10 08:22:31.317 [ERROR] エラー発生 $?=2 ./09_logging.sh main:36
解説
09_logging.sh
このスクリプトは、ログ出力機能とエラーハンドリングを組み合わせた Bash スクリプトです。以下に各部分の解説を示します:
#!/usr/bin/env bash
: スクリプトが Bash シェルで実行されることを指定しています。set -euCo pipefail
: スクリプトの設定を変更しています。
-e
: エラーが発生したら即座にスクリプトを終了します。-u
: 未定義の変数を使用しようとするとエラーを発生させます。-C
: コマンドの返り値が0以外の場合、そのコマンドが非零であることを示します。-o pipefail
: パイプの途中でエラーが発生した場合、パイプ全体をエラーとして扱います。
readonly LOG_OUT=./stdout.log
: 標準出力を記録するログファイルのパスを指定します。readonly LOG_ERR=./stderr.log
: 標準エラーを記録するログファイルのパスを指定します。exec 1> >(tee -a "$LOG_OUT")
: 標準出力をファイルにリダイレクトし、同時にその内容を標準出力にも表示します。リダイレクト先は$LOG_OUT
となります。exec 2> >(tee -a "$LOG_ERR")
: 標準エラーをファイルにリダイレクトし、同時にその内容を標準エラーにも表示します。リダイレクト先は$LOG_ERR
となります。function log_debug() { ... }
:log_debug
というデバッグ用のログを記録する関数を定義しています。log
関数を呼び出して、ログの種類を “DEBUG” としています。function log_err() { ... }
:log_err
というエラーログを記録する関数を定義しています。log
関数を呼び出して、ログの種類を “ERROR” としています。function log() { ... }
:log
という共通のログを記録する関数を定義しています。日付、ログの種類、メッセージを整形して表示します。function trap_err() { ... }
:trap_err
というエラーが発生した際に呼び出される関数を定義しています。エラーのステータスや発生箇所の情報を取得し、log_err
関数を呼び出してエラーログを記録します。trap trap_err ERR
:ERR
シグナルに対して、trap_err
関数が呼び出されるように設定します。log_debug "$(which bash)"
: インストールされている Bash の実行ファイルのパスをデバッグログに記録します。log_debug "$(bash --version)"
: Bash のバージョン情報をデバッグログに記録します。ls dummy.txt
: 標準エラーへの出力確認用に、存在しないファイルdummy.txt
をls
コマンドでリストします。この部分でエラーが発生し、trap_err
関数が呼び出されてエラーログが記録されます。echo "ここは表示されない"
: 上記のls dummy.txt
でエラーが発生した場合、この行は実行されません。スクリプトはエラーが発生した時点で終了するため、この行は実行されません。
このスクリプトはログ出力やエラーハンドリングを組み込んでおり、デバッグや問題解決を助けるための情報を詳細に収集しています。
おわりに
今日は、bashにおけるlogging(ロギング)についてご紹介しました。
よっしー
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント