MAP | PTLog ドキュメント > チュートリアル > PTLog Basic > クライアントコードの記述 | << | >> |
本節では、 ログ要求を発行するクライアントコードの記述方法を説明します。
デモンストレーション実装のbasic.client パッケージに属するクラス群も参照してください。
本チュートリアルでは、 クラスは全てクラス名のみで表記されています。 完全な名称は以下の通りです。
表記 | 完全名 |
---|---|
Log | jp.ne.dti.lares.foozy.ptlog.Log |
LogBuffer | jp.ne.dti.lares.foozy.ptlog.LogBuffer |
LogTap | jp.ne.dti.lares.foozy.ptlog.LogTap |
WriterProvider | jp.ne.dti.lares.foozy.ptlog.writer.WriterProvider |
LogTap
の生成利便性の上から、
はじめに
LogTap
を生成する必要があります。
public class Client { .... final static public LogTap TAP = new LogTap(Client.class, WriterProvider.STDOUT); }
LogTap
は
JDK ログ API(ないし Apache Log4j)における Logger
とほぼ同等のものです。
コンストラクタパラメータの前者は、 ログ要求の「主体(subject)」を意味します。 これはログ要求の発行者を識別するために使用されます。
後者のパラメータは、
基礎となるログフレームワークを指定します。
この例における
"WriterProvider.STDOUT
" の場合は、
初期状態ではログ要求が標準出力に書き出されることを意味します。
後者のパラメータに関する詳細は "ログフレームワークへの接続" をご覧ください。
Log
経由での要求発行以上で、
LogTap
から取得した
Log
経由でログ要求を発行できます。
例えば:
public void doSomething(){ Log log = TAP.getLog("doSomething"); log.info("INFO 型によるログ"); log.dump("DUMP 型によるログ"); try{ .... .... } catch(Exception e){ log.error("ERROR 型によるログ", e); } }
LogTap#getLog()
のパラメータは、
ログ要求の発行元となるメソッドの名前です。
Log
は、
ログ要求を受け付ける幾つかの「型(type)」を持っています。
型 | 対応する level/method | ||
---|---|---|---|
JDK logging API | Apache Log4j | JCL(*1) | |
fatal | SEVERE(1000) | FATAL(50000) | fatal |
error | SEVERE(1000) | ERROR(40000) | error |
warn | WARNING(900) | WARN(30000) | warn |
info | INFO(800) | INFO(20000) | info |
config | CONFIG(700) | INFO(20000) | info |
dump | FINE(500) | DEBUG(10000) | debug |
trace | FINER(400) | TRACE(5000)(*2) | trace(*3) |
---(*4) | FINEST(300) | --- | --- |
(*1) は、このチュートリアルにおいて "Jakarta Common Loggings" の略称として使用されます。
(*2) は、Log4j 1.2.12 からサポートされています。
(*3) は、 JCL 1.0.x では、"DEBUG" (Log4j 環境)ないし "FINEST"(JDK Logging API 環境)を使用しています。
(*4) に対応する出力は、型変換により可能になります。
Log
クラスは、
各「型」ごとに3つのシグネチャバリエーションを持っています。
public void <type>(String message, Throwable throwable); public void <type>(Object data); public boolean enables<Type>();
最初の形式は、
他のログフレームワーク(例えば JDK logging API、Log4j ないし JCL)
と同様の一般的なものです。
message
および(ないし) throwable
には、
"null" を指定しても構いません。
2つ目の形式は、
Throwable
を含む任意のデータのログ要求の際に使用されます。
String
か Throwable
のいずれかのみを記録したい場合に有用です。
3つ目の形式は、 指定した「型」のログ要求の可否を判定するのに使用されます。 例えば:
public void doSomething(){
Log log = TAP.getLog("doSomething");
if(log.enablesDump()){
log.dump("DUMP 型によるログ");
}
}
"log.enablesDump()
" 条件下のブロックは、
"dump" によるログが可能である場合にのみ実行されます。
このような条件は、実行中に動的に変化する可能性があります。
このような確認は、 常に情報収集を実施することが非常に高価である場合に有用です。
"trace" 型には、 これらに加えて3つの追加バリエーションがあります。
public void doSomething(){ Log log = TAP.getLog("doSomething"); log.enter(); // メソッド開始を意味します .... log.pass("initialize phase - 1"); .... log.pass("initialize phase - 2"); .... log.pass("initialize phase - 3"); .... .... log.exit(); // メソッド終了を意味します }
上記例におけるそれぞれのメソッドは
"Log#trace
" メソッドで置き換え可能ですが、
これらのメソッドは "trace" ログの統一された要求(およびフォーマット)
方式を提供します。
それに、メソッド起動コードが短いのは重要ですよね?
LogBuffer
経由での要求発行経験上、 パラメータの出力はログの主要な目的の一つであり、 ログ要求には2つのスタイルがあります。
1つ目は「結合」スタイルです。
public void doSomething(int p1, int p2, int p3, ....){ Log log = TAP.getLog("doSomething"); log.dump("p1=" + p1 + "/p2=" + p2 + "/p3=" + p3 + .....); }
もう1つは「分離」スタイルです。
public void doSomething(int p1, int p2, int p3, ....){ Log log = TAP.getLog("doSomething"); log.dump("p1=" + p1); log.dump("p2=" + p2); log.dump("p3=" + p3); .... }
「結合」スタイルでは、 1つのログレコード中にパラメータ出力を得ることができますが、 ログ要求を行うクライアントコードは優雅ではありません。
「分離」スタイルでは、 パラメータ出力が複数のログレコードに分割されるため、 ログ出力から情報を収集しなければなりません。
PTLog は LogBuffer
によってこの問題を解決します。
public void doSomething(int p1, int p2, int p3, ....){ Log log = TAP.getLog("doSomething"); LogBuffer dump = log.forDump(); dump.add("p1", p1); dump.add("p2", p2); dump.add("p3", p3); .... dump.flush(); // ログ要求発行 }
上記例では、
ログ要求は
LogBuffer#flush()
起動時に「dump」型で発行されます。
LogBuffer
はパラメータの名前と値を結合します。
対応する「型」のログ記録が可能でない場合、
Log#for<Type>()
メソッドは、
いずれのメソッド発行に対しても何も行わない実装の
LogBuffer
を返します。
そのため、
Object#toString
の実行コストの高価なものが含まれるか、
パラメータ数が極めて多い場合以外は、
性能劣化防止に備えた
Log#enables<Type>()
による確認は不要です。
MAP | PTLog ドキュメント > チュートリアル > PTLog Basic > クライアントコードの記述 | << | >> |