Archive for 2009/7/9
Flexのlogging機能はログの書き出し命令と、実際の書き出し実装を分けられる仕組みです。
ログを書き込むときには
package com.coltware.fxmail.pop3
{
import mx.logging.ILogger;
import mx.logging.Log;
public class POP3Client extends UIComponent{
private static var log:ILogger = Log.getLogger("com.coltware.fxmail.pop3.POP3Client");
public function POP3Client() {
log.debug("instance created ..");
}
}
}
のようにでき、また、ログの実際の書き出しをどのようにやるかは、
var logTarget:TraceTarget = new TraceTarget(); logTarget.level = LogEventLevel.DEBUG; logTarget.includeCategory = true; logTarget.includeDate = true; logTarget.includeTime = true; logTarget.includeLevel = true; Log.addTarget(logTarget);
のようにできます。
複数指定する場合には、同様に必要なLogTargetクラスをnewして、addTargetしてやればOKです。
(ただし、ログの書き出しはアプリケーションの初期化処理など初めする必要があります。)
このlogging機能の良いところは、ログの書き出し命令と、実際の書き出し処理が分離されているので、
各プログラムを書いている人は、ログをどこにいつ出すのか?ということを気にして実装する必要がないのです。
(現実問題としては多少はあるでしょうが・・・・)
この辺りを図にすると以下のような感じになるのではないでしょうか?

また、命令と書き出し処理が分かれていることに付随してもうひとついいところが、書き出し命令1つに付き、書き出し処理を1つにする必要がないのです。
たとえば、通常の動作ログはファイルに書き出し、重大なエラーが発生したときにネットワークで、エラー収集サーバにとばすなどということもできますし、
開発時には、デバッグ情報をtrace関数で表示するが、実際の運用時には表示しない(つまり、書き出し処理を使わない)ということもできます。
さて、このように書き出し命令と書き出し処理がわかれているといいことだらけのようですが、ひとつ問題となることがあります。
意図しないログも書き出されてしまうという問題です。
たとえば、ライブラリ開発者はデバッグなどの情報をログに書き出すようにプログラムを作っていることが多々あります。
しかし、これを使ったプログラマがデバッグ情報を出力すると、ライブラリのログも表示されてしまうという問題です。
ただし、この問題を回避するためにFlexのlogging機能にはfilterという概念があります。
ログを書き出すときに
Log.getLogger("xxxx.yyyy.zzzz.ABC");
のように書いた部分を使ってフィルタがかけられるのです。
logTarget.filters=["xxxx.yyyy.zzzz.*"];
ってな感じです。
というよう、かなり使える機能です。
しかーし、残念ながら、Flexで標準で用意されている書き出し実装はtrace出力のみなのです。
もうひとつ残念なこととして、ログレベルを1つ1つ指定できないのです。つまり、debugだけ書き出すということ。
ログレベルが上だったら出力されてしまいます。
でも、TraceTargetのソースを見るとすごーく単純なのがわかると思います。
override mx_internal function internalLog(message:String):void
{
trace(message);
}
実装はこれしかありません。
ここで、traceの部分でメッセージを出力しているで、その部分をファイルに書き出すなり、ネットワークなりに飛ばすなりを書けばOKです。
私はFileに書き出す処理と、ブログでは紹介していませんがsyslogサーバ(実際はsyslog-ng)に飛ばすようなものを使っています。
単に、syslogに飛ばしているのはLinux上のほうがtailなどでメッセージを見やすいという理由と、syslogサーバでさらにこのログをどのように扱うかを指定できるからです。
(といってもこのあたりからは運用テクに入るので記述しませんが・・・・・)

