Identity Manager は、トレース機能を使用すると、アダプタコンポーネント (リソースアダプタ) でアダプタのトレースポイントがあるコードを計測できるようになります。ここでは、トレースポイントを使用し続けてアダプタ問題を評価し、解決に役立つガイドラインをいくつか説明します。
トレースポイントがあるコードを測定するためのガイドラインの方針は、次のとおりです。
関連情報を表示して、本稼働環境と開発環境の両方で、トレースポイントをトラブルシューティングにできる限り役立つようにする。
重要なメソッドごとに、1 つのエントリポイントと 1 つの終了ポイント、または例外トレースポイントを作成する。
通常の処理中、および次の操作によってトレースが有効になっているときに、トレースポイントをできる限り効果的に活用する。
トレースレベルのチェック数を最小限におさえる。
トレースが有効に設定されているときにオブジェクトの作成を最小限に抑える。
表示する情報量を制御するには、トレースポイントのトレースレベルを指定します。次の表は、com.sun.idm.logging.TraceManager インタフェースで定義される各トレースレベルを説明したものです。
表 5–2 定義されているトレースレベル
トレースレベル |
トレース変数 |
使用状況 |
---|---|---|
1 |
Trace.LEVEL1 |
リソースアダプタインタフェースの Public メソッドのエントリポイントと終了ポイント |
2 |
Trace.LEVEL2 |
Public メソッド以外または Identity Manager コンポーネント外部インタフェースに含まれているメソッドのメソッドのエントリポイントと終了ポイント |
3 |
Trace.LEVEL3 |
決定点または重要変数 |
4 |
Trace.LEVEL4 |
ループ内の重要変数など、極めて詳細な情報 |
n/a |
Trace.ALWAYS |
トレースレベルのチェックを行わない 注意: このオプションは、すでにトレースレベルを条件に指定している場合に使用してください。 |
循環的に依存しないようにするには、com.sun.idm.logging.TraceManager インタフェースを実装する com.sun.idm.logging パッケージに、com.sun.idm.logging.Trace クラスを使用します。
トレースポイントをコードに追加するときは、次の点に注意してください。
メソッドへのトレース引数、およびメソッドからの戻り値。
引数が「print large」の場合、テキスト表現が短くなければ、そのオブジェクトを null かどか指定してください。引数または戻り値が配列かリストで、その値の印刷が大きい場合は、配列サイズかリストサイズを指定すれば十分です。null 値を避けるには、com.waveset.util.Util.length() ユーティリティーメソッドが使用できます。
トレース情報をフォーマットするか有意義にトレース情報を与えるオブジェクトを作成するには、指定トレースレベルが有効にならない限り Identity Manager がトレースポイントデータを整列化しないように、Trace.getLevel メソッドと isLogging(level) メソッドを使用してトレース文の周りに if 文を配備します。
この構文を使用するときは、条件内のトレースポイントに Trace.ALWAYS トレースレベルを指定してください。条件内でチェックがすでに行われていれば、このトレースレベルがトレースレベルに不要なチェックを防いでくれます。
obj.getName() などの印刷可能表現を取得するのにメソッドの呼び出しを必要とするオブジェクト値をトレースする場合は、トレースが有効になった場合に NullPointerException が発生しないように null オブジェクトを避けてください。
通常は、単純な getter や setter メソッドなどの簡易メソッドにトレースポイントを使用しないでください。
WSUser オブジェクトをトレースするときは、 toString() メソッドを getName() メソッドの代わりに使用して、オブジェクトの値を表示します。toString()) メソッドの方が、getName() よりも堅牢性があり、有用な情報を印刷します。user.getName() のトレースの代わりに、toString() を暗黙に呼び出す user をトレースしてください。
メソッドまたはコンストラクタが単なるラッパーの場合、つまりメソッドまたはコンストラクタが別のメソッドやコンストラクタを、同名だが異なる署名で呼び出すだけでまったく重要でない場合は、トレースポイントを行き先メソッドやコンスタラクタに直接配備します。
パフォーマンスが不可欠で、そのメソッドが何度も呼び出される場合は、エラーを示すように情報トレースポイントを使用します。そのメソッドには、エントリや終了トレースポイントを付けないでください。このオプションは慎重に使用してください。
トレースポイントを付ける前に、フィールドの問題を見つけるのにそのトレースポイントから有用な情報が得られるかどうか確認してください。
次のセクションでは、各トレースレベルをより詳細に説明していき、コードでのトレースポイントの使用例を紹介していきます。
使用するコードにエントリおよび終了トレースポイントを追加する前に、これらのガイドラインをお読みください。
すべての Identity Manager コンポーネントの外部インタフェースメソッドには、リソースアダプタインタフェースで宣言されている public メソッドの Trace.Level1 エントリまたは終了トレースポイントを使用します。
コンストラクタや静的メソッドや Identity Manager コンポーネントの外部インタフェースに含まれていないメソッドなど、重要な public メソッド以外には、Trace.Level2 エントリまたは終了トレースポイントを使用します。
トレースポイントの中に引数を指定します。
その引数が基本型または java.lang.String でなく、各種オブジェクトの作成やメソッドの呼び出しを必要とする引数の場合は、エントリトレースポイントを条件付きにして、トレースが有効な場合のみフォーマット処理が行われるようにします。
終了トレースポイントを指定する際には、そのメソッドが基本型か java.lang.String の場合、戻り値を表示してください。戻り値に何らかのフォーマットが必要な場合は、このガイドラインに説明したとおりにオブジェクトのフォーマットを条件付きにしてください。以下を使用します。
int getLevel() int getLevel (Method) boolean isLogging(level,method) boolean level1 (method) boolean level2 (method) boolean level31 (method) boolean level4 (method) |
複数の java.lang.String を一緒に付与する必要がある情報をトレースする場合は、java.lang.String の代わりに java.lang.StringBuffer を使用します。java.lang.StringBuffer を使用するよりも、付与した方が早く済みます。また、前述の箇条書き項目のとおりに条件付きにしてください。
重要なコンストラクタにエントリまたは終了トレースポイントを追加する際は、コンストラクタ内の this() や super() メソッド呼び出しの前にトレースポイントを配備することはできません。this() や super() メソッド呼び出しの直後に、エントリトレースポイントを配備してください。
例外条件をトレースするには、終了トレースポイントを使用しないでください。メソッドが例外をスローする場合は、例外がスローされる直前に、エントリまたは終了トレースポイントと同じトレースレベルで、例外トレースポイントを使用します。詳細は、「例外トレースポイントの使用方法」を参照してください。
メソッドにエントリトレースポイントが含まれている場合は、そのメソッドに throwing メソッド、caught メソッド、または終了のいずれかを実行するコードパスも含めてください。
次に、簡易エントリと終了トレース文の例を示します。この例では、次の CLASS 変数が各文に宣言されているものとします。
private static final String CLASS = "com.waveset.adapter.MyResourceAdapter"; protected static Trace _trace = Trace.getTrace();
final String METHOD = methodName; _trace.entry(_trace.LEVEL1, CLASS, METHOD); _trace.entry(_trace.LEVEL1, CLASS, METHOD, user); if (_trace.level1(CLASS, METHOD)) { _trace.entry(_trace.ALWAYS, CLASS, METHOD, user= + user); } // Show the size of an array argument // ASSUME: password is an argument to the method // Note the use of the Util.length() method. It is // a convenience method that guards against null. if (_trace.level1(CLASS, METHOD)) { StringBuffer sb = new StringBuffer(32); sb.append(password length=); ab.append(Util.length(password)); _trace.entry(_trace.ALWAYS, CLASS, METHOD, sb.toString()); }
_trace.exit(_trace.LEVEL1, CLASS, METHOD); _trace.exit(_trace.LEVEL1, CLASS, METHOD, returnValue); if (_trace.level1(CLASS, METHOD)) { _trace.exit(_trace.ALWAYS, CLASS, METHOD, returnValue != null ? returnValue.getName() : returnValue); } // Show the size of an array String[] accounts = ... if (_trace.level1(CLASS, METHOD)) { StringBuffer sb = new StringBuffer(32) sb.append(accounts length=); ab.append(accounts.length); _trace.exit(_trace.ALWAYS, CLASS, METHOD, sb.toString()); }
使用するコードに情報トレースポイントを追加する前に、これらのガイドラインをお読みください。
情報データトレースポイント、変数データトレースポイント、およびデータトレースポイントには通常、Trace.Level3 または Trace.Level4 を使用します。トレースレベルは、表示された情報の重要度、工数および詳細度によって決まります。
重要な条件、分岐、コードパスで発生する情報などをトレースするには、Trace.Level3 と Trace.Level4 の情報と変数トレースポイントを使用します。
変数トレースポイントは情報トレースポイントと同様に便利なメソッドですが、変数トレースポイントが引数値をプリントするだけでなく variable=<variable> をプリントアウトします。さらにこのメソッドは、引数に指定したトレースレベルが一致しない限りは情報をフォーマットしません。
メソッドに例外条件があってもその例外を再スローしない場合は、情報トレースポイントを使用しないでください。caught メソッドを使用してください。たとえば、「例外トレースポイントの使用方法」を参照してください。
バイト配列で情報を表示するには、Trace.Level3 と Trace.Level4 データトレースポイントを使用します。その情報がそのトレースレベルに合っており短い場合は、下位のトレースレベルを使用してもかまいません。
重要だが短い情報をトレースするには、Trace.Level1 と Trace.Level2 情報トレースポイント、変数トレースポイント、およびデータトレースポイントが使用できます。ただし、このレベルのトレースポイントはほとんど使用しないでください。
次に、簡易情報トレース文の例を示します。この例では、次の CLASS 変数が宣言されているものとします。
private static final String CLASS = "com.waveset.adapter.MyResourceAdapter"; protected static Trace _trace = Trace.getTrace();
_trace.info(_trace.LEVEL3, CLASS, METHOD, Some Message); WavesetResult result = new WavesetResult(); try { someMethod(); } catch(Exception e) { String msg = Some Error Message; WavesetException we = new Waveset(msg, e); _trace.caught(_trace.LEVEL3, CLASS, METHOD, e); result.addException(we); }
使用するコードに例外トレースポイントを追加する前に、これらのガイドラインをお読みください。
エントリまたは終了トレースポイントが指定されているすべてのメソッドにトレースポイントを使用します。また、例外を取得して再スローするメソッドにトレースポイントを使用します。Identity Manager は、新しい例外が元の例外をラップしている例外をスローすることがあります。エントリと終了トレースポイントで使用しているものと同じトレースレベルを使用してください。
現メソッドから例外が作成されてスローされる場合は、例外トレースポイントを使用します。
例外が取得されて処理される場合は、例外トレースポイント caught メソッドを使用します。たとえば、現メソッドから例外がスローされない場合などです。この状況は、Identity Manager が例外を取得して処理する際、後から調査しようと WavesetResult などのコンテナにそれを配備したときによく起こります。
現メソッドからスローされた例外が、java.lang.RuntimeException または java.lang.Error を拡張する例外の checked 例外でなければ、ほかの措置が講じられるまでこのメソッドの終了ポイントはトレースされません。この状況で例外トレースポイントを設定するには、try/catch ブロックをそのメソッドの重大域の周りに使用して、発生する例外を再スローする方法があります。つまり、メソッドが成功したか失敗したかを調べることが欠かせないときは、通常 Trace.Level3 以上の使用が必要になります。
次に、簡易例外トレース文の例を示します。この例では、次の CLASS 変数が宣言されているものとします。
private static final String CLASS = "com.waveset.adapter.MyResourceAdapter"; protected static Trace _trace = Trace.getTrace();
try { someMethod(); } catch(Exception e) { _trace.throwing(_trace.ALWAYS, CLASS, METHOD, e); throw e; } try { someMethod(); } catch(Exception e) { _trace.throwing(_trace.ALWAYS, CLASS, METHOD, e); WavesetException we = new WavesetException(Some Message, e); throw we; } if (error) { WavesetException e = new WavesetException(Some Error Message.; _trace.throwing(_trace.LEVEL3, CLASS, METHOD, e); throw e; } try { someMethod(); } catch(Exception e) { _trace.caught(_trace.LEVEL1, CLASS, METHOD, e); } // execution continues. someOtherMethod();
トレースポイントのテンプレートを使用すると、Identity Manager リソースアダプタに一貫した有用なトレースポイントを作成できるようになります。Identity Manager には、次の場所に Eclipse テンプレートが用意されています。
src/wps/doc/eclipse-trace-templates.xml
これらのテンプレートを Eclipse にインポートするには、「ウィンドウ」>「環境設定」>「Java」>「エディタ」>「テンプレート」の順に選択します。
Emacs または IDEA を使用している場合は、同様のテンプレートが作成できます。