2011年12月14日水曜日

そのログ、色つきでtailしたくないですか?

tailは便利だけど、白黒で見るのはすごく疲れます。
なので、色を付けてみたいと思います。
色をつけるにはANSI エスケープシーケンスを使えばよいらしい。


1、ANSI エスケープシーケンスとは。



ディスプレイに文字を表示する際のエスケープ。
つまり、今自分が使っているターミナルが、
受け取った文字列を表示する際の制御文字みたいなものらしい。

ANSI エスケープシーケンスを使うと、色を変えるだけでなく、
コマンドラインの表示をいろいろカスタムできるらしい。
ANSIエスケープシーケンスを使って端末に時計を表示するとか。

2、ANSIエスケープの書き方。


こんな感じ。
# karinoを赤色で標準出力
echo -e "\033[0;31mkarino\033[0m"

# karinoの背景を緑色で標準出力
echo -e "\033[42mkarino\033[0m"

# karinoにアンダーラインをつけて標準出力
echo -e "\033[4mkarino\033[0m"

複雑に見えるが、形式を把握できれば大丈夫。

5. ANSI エスケープシーケンス: 色とカーソル操作

色を変えるときの形式は、以下。
ESC[色m

bashでは以下のように書く。
「ESC」 → 「 \e 」or「 \033 」
「 [ 」 → 「 \[ 」

「色」の部分は、以下。
文字の色、背景の色、どちらもこのIDで指定する。
色ではないが下線とか点滅もできる。
【文字色】
Black 0;30
Blue 0;34
Green 0;32
Cyan 0;36
Red 0;31
Purple 0;35
Brown 0;33
Light Gray 0;37
Dark Gray 1;30
Light Blue 1;34
Light Green 1;32
Light Cyan 1;36
Light Red 1;31
Light Purple 1;35
Yellow 1;33
White 1;37

【背景色】
Black 40
Blue 44
Cyan 46
Red 41
Purple 45
Brown 43
Light Gray 47

【その他】
下線 4
点滅 5
色の逆転 7
非表示 8


3、マッチした部分を置き換える方法



標準出力されるログをハイライトさせる方法として、
以下のようなのがあった。
tail -f messages | perl -pe 's/[Ee]rror/¥e[1;31;43m$&¥e[0m/g' 
標準出力のキーワードをハイライト

これと同じ方法を使わせてもらう。


4、色を変えるスクリプト



loghighlight() {
    
    # ANSIエスケープシーケンスの定義
    RED_WORD="\e[0;31m"
    BLUE_WORD="\e[0;34m"
    GREEN_WORD="\e[0;32m"
    CYAN_WORD="\e[0;36m"
    PURPLE_WORD="\e[0;35m"
    YELLOW_WORD="\e[1;33m"
    GRAY_WORD="\e[0;37m"
    UNDER_LINE="\e[4m"
    DEFO="\e[0m"
    
    # 置換 
    while read line;do
    echo $line | /usr/bin/perl -pe "s/\[[Ee]rror\]/${RED_WORD}$&${DEFO}/g"    \
               | /usr/bin/perl -pe "s/\[client.*\]/${GREEN_WORD}$&${DEFO}/g"  \
               | /usr/bin/perl -pe "s/\[debug\]/${GREEN_WORD}$&${DEFO}/g"     \
               | /usr/bin/perl -pe "s/\[emerg\]/${GREEN_WORD}$&${DEFO}/g"     \
               | /usr/bin/perl -pe "s/\/(.*\/)(.*)/${PURPLE_WORD}$&${DEFO}/g" \
               | /usr/bin/perl -pe "s/\/(.*\/)(.*)/${UNDER_LINE}$&${DEFO}/g"  \
               | /usr/bin/perl -pe "s/PHP Fatal error:/${RED_WORD}$&${DEFO}/g"
    done
}

使い方は以下のとおり。
$ tail -f error.log | loghighlight
正規表現にマッチしたものを指定した色に変更して出力する。


5、問題点



遅い。
sedとか、awk getline使ったほうが速いかも。
whileとawk
全部perlで組んだほうがいいんじゃないだろうか。


その他、参考になったページ



Linux上でシェルが実行される仕組みを,体系的に理解しよう (bash 中級者への道)

ANSI Escape sequences


使っているうちに、いくつか問題が見つかった。
・tailの対象ファイルが2つ以上の場合、最初のファイル以外が出力されない。
・tailコマンドの前で、grep等をパイプで渡したものをloghighlightの対象とすると、ひとつも表示されない。
やっぱりwhile read以外でやりたいな。

その後、標準出力に色つけるコマンド作った。
「標準出力に色をつけたい!」と思ったときは、このコマンド使ったらいいと思う。

0 件のコメント:

コメントを投稿