ログは色付けしたほうが見やすいけど、grep --colour は使いやすくないと思う
ログファイルをコンソールやターミナルで読むのは案外めんどくさいと思いませんか? たとえばこんなふうにログを表示した時に文字が全部同じ色だから見づらいと思うのですよ。これは TeraTerm を使っているので URL だけは着色されていますが、それ以外の情報を流し見で把握することは難しく、多少なりとも「読む」努力が必要です。
かといって grep --colour すると、指定したキーワードが色付けされるものの、キーワードが出現する行だけが抜き出されてしまいます。
しかし自分にとって色分けしたい状況は、tail -f でログをリアルタイムに流しつつ、その中で注意が必要と思われる箇所を労せずに認識したい、などの状況が多いのです。そうすると、出力はキーワードを含む行だけではなく、すべてを出して欲しいのです。
また複数のキーワードを着色しつつも色分けしたい。ここで最近の開発ツールやエディタを考えてみると、コードシンタックスに合わせて色付けしてくれるのが普通の動作ですが、それにくらべるとログの閲覧は微妙にイケてないです。
そこで、以下の要件で動作するスクリプトをサクッと作ってみました。
- 標準入力から与えられた文字列を対象にして、マッチした文字列部分に着色する。
- 文字列は複数指定可能とする。
- キーワードごとにそれぞれの色を変えて表示する。
- マッチしなかった行はそのまま素通しする。
この実装で実際に NONE や DIRECT の文字だけを着色したのがこちらのスクリーンショットです。
実装
perl で 20 行程度のカンタンな実装です。本質的な部分は10行程度。
#!/usr/bin/perl
#
# 標準入力から渡された文字列の中に、
# このスクリプトへの引数で渡された文字列が含まれる場合は
# 着色して出力するスクリプト
$| = 1;
if ( $#ARGV > 5 ) {
print "Please use within 6 keywords. abort.\n";
exit 1;
}
while( <STDIN> ) {
for ( my $i = 0 ; $i <= $#ARGV ; $i ++ ) {
my $color=sprintf "%dm", $i + 31;
s/$ARGV[$i]/\033\[1;$color$&\033\[0m/gi
}
} continue {
print $_;
}
exit 0;
gist にも上げました。
使用例
着色したい文字列は6つまで指定可能
引数で6つまでの文字列を指定可能です。7つ以上の指定はエラーになります。
6つに制限しているのは、エスケープシーケンスの基本色8色のうち、黒と白を除外した6色で出し分けているからです。また、色は引数の位置によって自動的に決まります。ここらへんの仕様上の制限は最小限の実装で済ませるためなのですが、逆にキーワード毎に色を明示できないという不便さを伴っています。これは気が向いたらそのうち仕様を変えるかも。(たとえば TCP_MISS:red のような指定ができるようにするとか。)
正規表現も使えます
マッチングしたい文字列には正規表現が使えます。たとえばこんなふうに。
そして正規表現が使えることににより、複数のキーワードを "キーワード1|キーワード2" のように指定することもできます。こうすると複数の文字列を同色でまとめられますから、7つ以上のキーワードに色を付けることもできます。
しかし "[0-9]" みたいな指定を2つめ以降のキーワードに指定すると出力が壊れます。これはエスケープシーケンスによる色指定の追加を行単位て個々の引数について実施していることが原因です。すでにエスケープシーケンスが設定済みの箇所に対して "[0-9]" にマッチした部分に更なる着色を行うと、そりゃ壊れて当然ですよねー。
ただし、どうしてもこういう指定を行いたい場合は最初のパラメータに記述すれば大丈夫です。
このようにログのフォーマットによらず文字列のパターンマッチで着色するフィルタを利用すれば、ログを読む努力をせずに色だけで流し見できます。ログの視認性が向上しますから、いろいろ捗ると思います。