GNU/Linux >> Linux の 問題 >  >> Linux

シェルスクリプト内でログの冗長性を管理するにはどうすればよいですか?

@Fred のアイデアをもう少し改良すると、この方法で小さなロギング ライブラリを構築できます。

declare -A _log_levels=([FATAL]=0 [ERROR]=1 [WARN]=2 [INFO]=3 [DEBUG]=4 [VERBOSE]=5)
declare -i _log_level=3
set_log_level() {
  level="${1:-INFO}"
  _log_level="${_log_levels[$level]}"
}

log_execute() {
  level=${1:-INFO}
  if (( $1 >= ${_log_levels[$level]} )); then
    "${@:2}" >/dev/null
  else
    "${@:2}"
  fi
}

log_fatal()   { (( _log_level >= ${_log_levels[FATAL]} ))   && echo "$(date) FATAL  $*";  }
log_error()   { (( _log_level >= ${_log_levels[ERROR]} ))   && echo "$(date) ERROR  $*";  }
log_warning() { (( _log_level >= ${_log_levels[WARNING]} )) && echo "$(date) WARNING  $*";  }
log_info()    { (( _log_level >= ${_log_levels[INFO]} ))    && echo "$(date) INFO   $*";  }
log_debug()   { (( _log_level >= ${_log_levels[DEBUG]} ))   && echo "$(date) DEBUG  $*";  }
log_verbose() { (( _log_level >= ${_log_levels[VERBOSE]} )) && echo "$(date) VERBOSE $*"; }

# functions for logging command output
log_debug_file()   { (( _log_level >= ${_log_levels[DEBUG]} ))   && [[ -f $1 ]] && echo "=== command output start ===" && cat "$1" && echo "=== command output end ==="; }
log_verbose_file() { (( _log_level >= ${_log_levels[VERBOSE]} )) && [[ -f $1 ]] && echo "=== command output start ===" && cat "$1" && echo "=== command output end ==="; }

上記のソースが logging_lib.sh という名前のライブラリ ファイルにあるとしましょう。これを通常のシェル スクリプトで次のように使用できます。

#!/bin/bash

source /path/to/lib/logging_lib.sh

set_log_level DEBUG

log_info  "Starting the script..."

# method 1 of controlling a command's output based on log level
log_execute INFO date

# method 2 of controlling the output based on log level
date &> date.out
log_debug_file date.out

log_debug "This is a debug statement"
...
log_error "This is an error"
...
log_warning "This is a warning"
...
log_fatal "This is a fatal error"
...
log_verbose "This is a verbose log!"

この出力は次のようになります:

Fri Feb 24 06:48:18 UTC 2017 INFO    Starting the script...
Fri Feb 24 06:48:18 UTC 2017
=== command output start ===
Fri Feb 24 06:48:18 UTC 2017
=== command output end ===
Fri Feb 24 06:48:18 UTC 2017 DEBUG   This is a debug statement
Fri Feb 24 06:48:18 UTC 2017 ERROR   This is an error
Fri Feb 24 06:48:18 UTC 2017 ERROR   This is a warning
Fri Feb 24 06:48:18 UTC 2017 FATAL   This is a fatal error

ご覧のとおり、log_verbose ログ レベルが VERBOSE の 1 レベル下の DEBUG であるため、出力は生成されませんでした。ただし、log_debug_file date.out 出力を生成し、log_execute INFO も生成しました 、ログ レベルが DEBUG に設定されているため、>=INFO.

これをベースとして使用して、さらに微調整が必​​要な場合は、コマンド ラッパーを作成することもできます。

git_wrapper() {
  # run git command and print the output based on log level
}

これらを配置すると、引数 --log-level level を取るようにスクリプトを拡張できます。 実行すべきログの詳細度を決定できます。

以下は、複数のロガーを備えた豊富な Bash のロギングの完全な実装です:

https://github.com/codeforester/base/blob/master/lib/stdlib.sh

上記のコードで一部の変数の名前が先頭にアンダースコアが付いている理由に興味がある人は、次の投稿を参照してください:

  • Bash とシェル スクリプトの変数の大文字と小文字を正しくする

あなたの質問で最もクリーンなアイデア(ラッパー関数)と思われるものはすでにありますが、それは面倒だと思うようです。再考することをお勧めします。次のようになります (必ずしも完全な解決策ではありません。基本的な考え方を示すためです):

#!/bin/bash

# Argument 1 : Logging level for that command
# Arguments 2... : Command to execute
# Output suppressed if command level >= current logging level 
log()
{
if
  (($1 >= logging_level))
then
  "${@:2}" >/dev/null 2>&1
else
  "${@:2}"
fi
}

logging_level=2

log 1 command1 and its args
log 2 command2 and its args
log 3 command4 and its args

必要なリダイレクト (必要に応じてファイル記述子を使用) をラッパー関数で処理するように調整できます。これにより、スクリプトの残りの部分は引き続き読み取り可能であり、選択したログ レベルに応じてリダイレクトや条件から解放されます。


解決策 1.追加のファイル記述子の使用を検討します。選択した詳細度に応じて、必要なファイル記述子を STDOUT または /dev/null にリダイレクトします。スクリプト内のすべてのステートメントの出力を、その重要性に対応するファイル記述子にリダイレクトします。https:// をご覧ください。 unix.stackexchange.com/a/218355 .


Linux
  1. シェルスクリプトで一時ファイルを作成するにはどうすればよいですか?

  2. 起動時にシェルスクリプトを実行する方法

  3. シェルスクリプトを使用して各行のタブ数を数える方法は?

  1. LinuxでLogrotateを使用してログファイルを管理する方法

  2. コマンドの出力をシェル変数に割り当てる方法は?

  3. シェル スクリプトでの複数行出力のインデント

  1. シェルスクリプトでスイッチを処理する方法は?

  2. Awk内のBashスクリプトでBash関数を呼び出す方法は?

  3. コマンドまたはシェルスクリプトの出力がStdoutまたはStderrであるかどうかを確認する方法は?