Oracle E-Business Suite開発者ガイド リリース12.2 E53035-01 | ![]() 目次 | ![]() 前へ | ![]() 次へ |
開発者は、コンポーネント全体にわたってロギングAPIを頻繁に利用することになります。ロギングは不具合がレポートされた場合に問題を局所化するのに役立ちます。ロギング・コールを配置する場所を慎重に選択し、理解しやすいコードを記述して、役に立つ必要な情報のみをログ・メッセージに挿入することをお薦めします。
ログ・メッセージ・テキスト、モジュール・ソースおよび重要度は、APIのコーディングを介して直接指定します。これらの3つのフィールドは、コード操作以外の方法では変更または修正できないため、情報は可能なかぎり有益で簡潔にすることを目指します。
開発者として理解しておく必要があるのは、いくつかのAPIと6つの重要度のみです。適切なAPIをコールして、次の3つのフィールドを渡します。
モジュール・ソース
重要度
メッセージ・テキスト
その他のフィールドはすべてAPIによって自動的に移入されます。
次のAPIを使用して、ログ・メッセージをデータベースに書き込みます。
FND_LOG PL/SQLパッケージ。
oracle.apps.fnd.common.AppsLog Javaクラス。
aflog(*) C API。
APIがデータベースに書き込む場合は、一般にパッケージFND_LOG_REPOSITORYと通信します。このパッケージは、メッセージを実際に書き込むパッケージです。中間層エッジ・ケースのデバックでは、ログ・メッセージをファイルに送信できます。
次のプロシージャを使用して、コードのエラーを処理します。
ステップ1: 内部エラー詳細(例: 例外スタック・トレース、関連する状態情報)を記録します。これらの詳細は、問題を診断するためにシステム管理者やサポート担当などによって使用されます。
ステップ2: 深刻なエラーの場合は、システム・アラートを発生させてシステム管理者に通知します。
ステップ3: エラーがエンド・ユーザーに影響する場合は、UIを介して(または、コンカレント・プログラムの場合は要求ログを介して)エンド・ユーザーにエラーを報告します。メッセージは、ユーザーが理解しやすい翻訳可能なメッセージを使用し、内部エラーの詳細は挿入しないようにします。
パフォーマンス上の理由で、メッセージの重要度に関するロギングが使用可能かどうかをチェックする必要があります。これは、オブジェクトの作成前、またはログ・メッセージを形成する文字列の連結前に実行します。整数の値をチェックするほうが、オブジェクトの割当や文字列の連結よりもコストは低くなります。ファンクションの引数は、ファンクション・コールの前に作成されることを思い出してください。つまり、文字列の連結は、ログのwrite*(..)コールの前に実行します。ロギングが使用可能かどうかを明示的にチェックして、ロギングが使用不可の場合は文字列の作成を回避してください。
if( AppsLog.isEnabled(Log.EVENT) )
AppsLog.write("fnd.common.WebAppsContext", str1 + str2, Log.EVENT);
if( FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ) then
FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
'fnd.plsql.MYSTUFF.FUNCTIONA.begin', 'Hello, world!' );
end if;
さらに、分岐の存続期間はコンテキスト・スイッチに影響されない、コードの密なループ内または分岐内では、ローカル変数を使用できます。これによって、ローカル変数より高コストなパッケージ・グローバル変数のアクセスを回避します。次の例を参照してください。
procedure process_rows ()
l_debug_level number:=FND_LOG.G_CURRENT_RUNTIME_LEVEL;
l_proc_level number:=FND_LOG.LEVEL_PROCEDURE;
begin
for loop
validation...
other calls...
if ( l_proc_level >= l_debug_level ) then
fnd_log....
end if;
end loop;
end;
可能な場合はJavaおよびCコードに対して同様の最適化を使用します。
注意: Oracle Application Object Libraryセッションが変わると(たとえば、職責の切替)、ログ・プロファイルの値が変更される可能性があります。このシナリオでは、Oracle Application Object LibraryによってFND_LOG.G_CURRENT_RUNTIME_LEVELが正しく更新され、さらにCおよびJavaの対応する値も更新されます。ただし、コードで値をキャッシュした場合、この変化は表示されない可能性があります。
モジュール・ソースは、特定のコード・ブロックに対する階層的な識別子です。モジュール・ソースには、主として次の目的があります。
メッセージのソースを一意に識別します。
システム管理者が、この階層に基づいて特定の領域でのロギングを使用可能にできます。
一貫性が確保されるように、すべてのモジュール名は、次の規則に従って作成する必要があります。モジュール名識別子の構文は、次のとおりです。
<application short name>.<directory>.<file>.<routine>.<label>
次に、各構文の構成要素について詳細に説明します。
コード・ブロックの所有者アプリケーションを示し、小文字で指定します。例: fnd、jtf、wf、sqlgl、inv。
ファイルが存在しているディレクトリまたはパッケージを示します。一般に、これは実際のファイル・システム・ディレクトリ名です。通常、ディレクトリには1つの構成要素のみが格納されますが、場合によっては、2つ以上の構成要素が格納されることがあります。Javaの場合、これは完全なパッケージ名です。次の表で、言語および書式とともに示した例を参照してください。
言語 | 書式 | 例 |
---|---|---|
Java | dir[.subdir] | commonfunctionSecurity.client |
C | <src>.dir | Src.flex |
ライブラリPL/SQL | Resource | Resource |
Forms PL/SQL | Forms | Forms |
Reports PL/SQL | Reports | Reports |
サーバーPL/SQL | Plsql | Plsql |
ローダー | Loaders | Loaders |
コードが含まれているパッチ適用可能エンティティ(ファイル)を示します。サーバーPL/SQLの場合、これはファイル名ではなくパッケージ名です。Javaの場合はクラス名です。次の表で、言語および書式とともに示した例を参照してください。
言語 | 書式 | 例 |
---|---|---|
Java | <ClassName> | WebAppsContext |
C | <filename> | Fndval |
ライブラリPL/SQL | <library name> | FNDSQF |
Forms PL/SQL | <form filename> | FNDSCAPP |
Reports PL/SQL | <report filename> | FNDMNMNU |
サーバーPL/SQL | <packagename> | FND_GLOBAL |
ローダー | <section> | Afsload |
コードのルーチン、プロシージャ、メソッドまたはファンクションを示します。ルーチン名がないOracle FormsまたはOracle Reportsのコードの場合は、トリガー名になります。次の表で、言語および書式とともに示した例を参照してください。
言語 | 書式 | 例 |
---|---|---|
Java | <method> | ValidateSession |
C | <function> | Fdfgvd |
ライブラリPL/SQL | <package.function> | FND_UTILITIES.OPEN_URL |
Forms PL/SQL | <package.function> | BLOCK_HANDLER.VALIDATE_NAME |
Forms PL/SQL | <function> | DETERMINE_NEXT_BLOCK |
Forms PL/SQL | <trigger> | PRE-FORM |
Reports PL/SQL | <function> | LOOKUP_DISPLAY_VALUE |
Reports PL/SQL | <trigger> | BEFORE_REPORT |
サーバーPL/SQL | <function> | INITIALIZE |
ローダー | <action>_<entity> | UPLOAD_FUNCTION |
ルーチン内の特定の部分に対する記述名です。ラベルを指定する主な理由は、厳密に1つのログ・コールをモジュール名で一意に識別するためです。これによって、アナリストまたはプログラマは、メッセージ(翻訳される可能性がある)を確認しなくても、メッセージを生成したコード部分を正確に把握できるようになります。したがって、各ログ文に対するラベルはルーチン内で一意にする必要があります。
自動的に使用可能または使用不可にできるように、様々なルーチンおよびファイルからの複数のログ・コールをグループ化する場合は、2つの部分で構成されるラベルが使用されます。最初の部分は機能グループ名で、2番目の部分は一意のコードの場所です。
たとえば、Oracle Application Object Library (FND)の付加フレックスフィールド検証コードには、次のようなラベルが指定された異なる場所に、様々なログ・コールがあります。
desc_flex_val.check_value
desc_flex_val.display_window
desc_flex_val.parse_code
これらがコード内の異なる場所にある場合も、モジュールを「fnd.%.desc_flex_val.%」と設定することで、すべてを使用可能にできます。
PROCEDUREレベルで記録されるメッセージでは、処理開始時に記録するメッセージに「begin」のラベルを使用し、処理終了時に記録するメッセージに「end」またはそれに類する内容(「end_exception」など)を使用します。例: begin、end、lookup_app_id、parse_sql_failed、myfeature.done_exec。
次のガイドラインを使用して、すべてのアプリケーションにわたって一意のモジュール名にする要件を満たすようにコードを記述します。
モジュール名階層のセパレータには、ドット(.)を使用する必要があります。
少なくとも、モジュール名には必須の構成要素(<application short name>.<directory>.<file>)を指定する必要があります。
モジュール名には空白やカンマを使用できません。空白およびカンマ文字は内部解析用に予約されています。具体的には、大文字小文字混合の英数字、アンダースコア、ダッシュおよびドット・セパレータ以外は使用できません。
モジュール名は大文字小文字に関係なく比較されるため、モジュール名が基づいているディレクトリ、ファイルおよびルーチンと同じ大文字、小文字または大文字小文字混合の書式を使用してください。本来、大文字または小文字でない構成要素(アプリケーション短縮名やラベル)には、小文字を使用します。
前述の階層スキーマを使用することで、システム管理者が様々なレベルでデバッグをオンに切り替えることができる点に注目してください。たとえば、ランタイム・ユーザーが次のいずれかのモジュールでロギングを使用可能にすると、fnd.plsql.FND_GLOBAL.APPS_INITIALIZE.init_profilesに対するデバッグ・ログ・コールが使用可能になります。
fnd
fnd.plsql
fnd.plsql.FND
fnd.plsql.FND_GLOBAL
fnd.plsql.FND_GLOBAL.APPS_INITIALIZE
fnd.plsql.FND_GLOBAL.APPS_INITIALIZE.init_profiles
fnd.common.WebAppsContext.validateSession.begin
fnd.common.WebAppsContext.validateSession.end
fnd.src.dict.afdict.afdget.lookup_shortname
fnd.flex.FlexTextField.getSegmentField.lookup_value
fnd.plsql.FND_GLOBAL.APPS_INITIALIZE.init_profiles
fnd.resource.FNDSQF.FND_UTILITIES.OPEN_URL.find_browser
fnd.loaders.afsload.DOWNLOAD_FORM.check_developer_k
fnd.forms.FNDSCSGN.FND_DATA_TABLE.GET_DB_WINDOW_SIZE.geometry
使用可能なログ重要度およびその使用方法を要約した表は、「AFLOG_LEVEL」の項を参照してください。
STATEMENTおよびPROCEDUREは、内部のOracle開発によるデバッグを目的としています。重要度がさらに高いEVENT、EXCEPTION、ERRORおよびUNEXPECTEDは幅広い利用者が存在します。ERRORおよびUNEXPECTEDのメッセージのモニターし、その解決を試みることをお薦めします。
内部エラーおよび外部エラーのすべてのメッセージをEXCEPTION、ERRORまたはUNEXPECTEDで記録します。ERRORおよびUNEXPECTEDのメッセージは、翻訳可能なメッセージ・ディクショナリのメッセージにします。
ログ・メッセージの挿入場所の判断は繰返しのプロセスになります。コードの使用方法を詳細に学習することで、ログ・メッセージの挿入場所についてさらに理解が深まり、エラーの根本原因の速やかな隔離に役立ちます。少なくとも、次の各項で説明するシナリオのメッセージを記録してください。
この重要度は、一般的にコードまたは環境の修正が必要な未処理の内部ソフトウェア・エラーを示します。
発生する回復不能なエラーをUNEXPECTEDとして記録します。UNEXPECTED重要度で記録されるメッセージは、システム・アラートとしてシステム管理者に自動的に伝播されるため、メッセージ・ディクショナリ・ベースのメッセージでこの重要度を使用する際は慎重に検討してください。ログ・メッセージはすべて簡潔で有意義なものである必要がありますが、UNEXPECTEDメッセージは、システム管理者がエラーを速やかに理解できるように、特に配慮して作成および確認してください。
この重要度は、一般的にエンド・ユーザーによる修正が必要な外部エンド・ユーザー・エラーを示します。
すべてのユーザー・エラー状況をERRORとして記録します。システム管理者は、ERRORメッセージのロギングを使用可能に選択し、ユーザーに提示されたエラーを確認できます。
ERRORメッセージはメッセージ・ディクショナリを使用して、FND_NEW_MESSAGESにシードされる必要があります。対応するエラーが実行時に発生した場合は、メッセージを記録し、適用可能な場合は適切に表示する必要があります。詳細は、「シード・メッセージ・ディクショナリ・メッセージの自動ロギングおよびアラート」の項を参照してください。
次のERRORおよびUNEXPECTEDメッセージには、次の内容を指定します。
原因: エラーの原因および適切な状態変数値を記述するメッセージ。例: 「無効なユーザー=」+ username
わかっている場合は修正情報または回避策。例: 「ユーザー名またはパスワード(あるいはその両方)を確認してください。」
この重要度は、一般的に修正が不要な処理済の内部ソフトウェア・エラーを示します。
Javaの例外は常に記録する必要があります。Java例外は通常のコード・フローの一部ではないため、無視しないでください。例外をコードで適切に処理し、デバッグ用に記録する必要があります。例外を発生させる場合は、最初に例外の原因を記録します。メッセージ・テキストではなく例外オブジェクトを渡す便利なログAPIが用意されています。重要度が渡されないと、Java例外はデフォルトでEXCEPTIONの重要度で記録されます。
製品が機能するのを妨げる深刻な例外は、UNEXPECTEDの重要度で記録します。たとえば、ユーザーによる新規発注時のSQLExceptionをUNEXPECTEDとして記録します。
この重要度は、高レベルの進捗レポートに使用されます。フロー内でのステップの完了、ビジネス・トランザクションの開始など、アプリケーションのマイルストンに適用されます。
アプリケーション・コードが構成可能な値を読み取るたびに、構成された値を記録する必要があります。値は、プロファイル、事前にわかっているオブジェクトの属性(例: 顧客のプライマリ住所)、デフォルト設定ルールなどから取得できます。ソース、名称および値を記録します。一貫性を保持するために、そのようなメッセージのモジュール・フィールド内のラベルには、「.config」を追加してください。例: fnd.common.MyClass.MyAPI.config
この重要度は、APIレベルの進捗レポートに使用されます。
主要なファンクションおよびAPIをPROCEDUREとして記録します。このようなメッセージのモジュール名には、ファンクション名またはAPI名、プロシージャの開始には「begin」、および終了には「end」を指定します。たとえば、validateSession(..) APIは主要なAPIで、APIの開始時に「fnd.common.WebAppsContext.validateSession.begin」、終了時に「fnd.common.WebAppsContext.validateSession.end」というモジュール名のメッセージを記録します。
基本クラスのメソッドを上書きする場合は、常に派生クラスの実装にメッセージを記録する必要があります。
メッセージ本文には、主要な入力値、状態値および戻り値を指定する必要があります。たとえば、コントローラのRequest、FormRequestおよびFormDataメソッドすべての入出力を記録します。
統合ポイントではメッセージを記録します(特に別のアプリケーションのAPIをコールする場合)。また、アプリケーション・レイヤーを超えてプロシージャをコールする場合もロギングを使用します。たとえば、JavaレイヤーからPL/SQL APIをコールする場合などが該当します。
この重要度は、低レベルの進捗レポートに使用されます。
SQL(動的SQL)を生成する場合は、それを記録する必要があります。
すべてのバインド変数を記録します。
ユーザー・インタフェースの選択またはユーザー・インタフェースの動的変更を記録する必要があります。たとえば、switcher Beanの使用、次のページへの移動などが該当します。
必要に応じて、関連する状態変数を含めます。
メッセージ添付APIを使用して、その他のコンテキスト情報をログ・メッセージまたはシステム・アラート(あるいはその両方)に追加できます。この機能には、大きい添付を記録するためのバッファリングされた効率的な書込みAPIが用意されています。このような添付用にシードされたメッセージ・テキストには、エラーの簡単な説明を指定し、添付には関連するコンテキスト詳細すべてを格納します。
現在、添付はデータベースLOBに保存されます。添付はOracle Applications Managerを介して表示できます。
oracle.apps.fnd.common.AppsLog:
getAttachmentWriter(String, Message, int); // For text data
getBinaryAttachmentWriter)String, Message, int, ...); // For binary data
例:
if(alog.isEnabled(Log.UNEXPECTED))
{
AttachmentWriter attachment = null;
Message Msg = new Message("FND", "LOGIN_ERROR");
Msg.setToken("ERRNO", sqle.getErrorCode(), false);
Msg.setToken("REASON", sqle.getMessage(), false);
try
{
// 'alog' is instance of AppsLog (not anonymous)
attachment = alog.getAttachmentWriter(
"fnd.security.LoginManager.authenticate", Msg, Log.UNEXPECTED);
if ( attachment != null )
{
// Write out your attachment
attachment.println("line1");
attachment.println("line2");
attachment.println("line3");
}
} catch (Exception e)
{
// Handle the error
} finally
{
// You must close the attachment!
if ( attachment != null )
try { attachment.close(); } catch (Exception e) { }
}
}
FND_LOG.MESSAGE_WITH_ATTACHMENT(..);
FND_LOG_ATTACHMENT.WRITE(..); // For text data
FND_LOG_ATTACHMENT.WRITE_RAW(..); // For binary data
例:
if( FND_LOG.LEVEL_UNEXPECTED >=
FND_LOG.G_CURRENT_RUNTIME_LEVEL) then
FND_MESSAGE.SET_NAME('FND', 'LOGIN_ERROR'); -- Seeded Message
-- Runtime Information
FND_MESSAGE.SET_TOKEN('ERRNO', sqlcode);
FND_MESSAGE.SET_TOKEN('REASON', sqlerrm);
ATTACHMENT_ID := ND_LOG.MESSAGE_WITH_ATTACHMENT(FND_LOG.LEVEL_UNEXPECTED, 'fnd.plsql.Login.validate', TRUE);
if ( ATTACHMENT_ID <> -1 ) then
FND_LOG_ATTACHMENT.WRITELN(ATTACHMENT_ID, "line1");
FND_LOG_ATTACHMENT.WRITELN(ATTACHMENT_ID, "line2");
FND_LOG_ATTACHMENT.WRITELN(ATTACHMENT_ID, "line3");
-- You must call CLOSE
FND_LOG_ATTACHMENT.CLOSE(ATTACHMENT_ID);
end if;
end if;
Oracle Application Object Libraryメッセージ・ディクショナリにシードされているメッセージは、対応するメッセージ・メタデータ属性を設定することで、自動ロギング対応および自動アラート対応にできます。
実行時に、メッセージを翻訳された形式で取得するために、Oracle Application Object Libraryメッセージ・ディクショナリAPIが起動されると、現在のログ構成で許可されている場合は、これらのAPIも内部的にログまたはアラートが適用されます。
自動的にロギングするには、シード・メッセージのログ重要度属性が、構成されているログ・レベル以上である必要があります。
自動的にアラートするには、シード・メッセージのアラート・カテゴリおよびアラート重要度の属性を定義して、少なくとも6-UNEXPECTEDレベルでログ構成を使用可能にする必要があります。
パスワードやクレジット・カード番号などの機密情報を暗号化していないプレーン・テキストで記録しないでください。
判読しやすいように、重要度を示すコールには整数の値(1、2、3など)をコード化しないでください。前述した適切な記述名を常に使用します。
AppsLogは、コア・ロギング機能を提供するクラスです。Oracle CRM Technology Foundationには、AppsLogの便利なラッパーAPIが用意されています。この項では、AppsLogの使用方法およびラッパーAPIについて説明します。
Javaでは、Oracle Application Object Library (FND)のコア・ロギング機能は、oracle.apps.fnd.common.AppsLogクラスで提供されます。多数の便利なラッパーを使用できます。
AppsLogは、複数のユーザーおよびスレッドがメッセージを同時に記録できるスレッドセーフ・クラスです。通常、AppsLogオブジェクトは、ユーザーのOracle Application Object Libraryセッションを初期化する際に、ユーザーのログ・プロファイル設定に基づいて作成および構成されます。AppsLogは、静的なシングルトン・クラスではないことに注意してください。様々なユーザーに異なるログ・プロファイルを設定でき、JVM内に複数のAppsLogオブジェクトが存在することになります。
同時に複数のスレッドおよびユーザーが存在できるため、正しいAppsLogインスタンスを使用するように注意してください。AppsLogインスタンスを取得するために、最初に現在のユーザーのAppsContextを使用して、そのgetLog()へのコールを試みます。現在のユーザーのログ・プロファイル設定とJavaシステム・プロパティに基づいて、AppsContextのAppsLogが完全に初期化されます。その構成に応じて、データベースまたはファイルに記録できます。完全に初期化されたこのAppsLogへの静的参照は作成しないでください。APIを使用して、毎回適切なAppsContextのAppsLogインスタンスを取得します。
エッジ・ケースのシナリオ(たとえば、Oracle Application Object Libraryセッションが完全に初期化される前で、使用可能なAppsContextがないなど)では、静的なAppsLog.getAnonymousLog()をコールしてスタンドアロンAppsLogを取得できますが、このスタンドアロンAppsLogは匿名で、Javaシステム・プロパティのみに基づいて初期化され、ファイルにのみログを記録できます。
public boolean authenticate(AppsContext ctx, String user, String passwd)
throws SQLException, NoSuchUserException {
AppsLog alog = (AppsLog) ctx.getLog();
if(alog.isEnabled(Log.PROCEDURE)) /*To avoid String Concat if not enabled */
alog.write("fnd.security.LoginManager.authenticate.begin",
"User=" + user, Log.PROCEDURE);
/* Never log plain-text security sensitive parameters like passwd! */
try {
validUser = checkinDB(user, passwd);
} catch(NoSuchUserException nsue) {
if(alog.isEnabled(Log.EXCEPTION))
alog.write("fnd.security.LoginManager.authenticate",nsue, Log.EXCEPTION);
throw nsue; // Allow the caller Handle it appropriately
} catch(SQLException sqle) {
if(alog.isEnabled(Log.UNEXPECTED)) {
alog.write("fnd.security.LoginManager.authenticate", sqle, Log.UNEXPECTED);
Message Msg = new Message("FND", "LOGIN_ERROR"); /* System Alert */
Msg.setToken("ERRNO", sqle.getErrorCode(), false);
Msg.setToken("REASON", sqle.getMessage(), false);
/* Message Dictionary messages should be logged using writeEncoded(..)
* or write(..Message..), and never using write(..String..) */
alog.write("fnd.security.LoginManager.authenticate", Msg, Log.UNEXPECTED);
}
throw sqle; // Allow the UI caller to handle it appropriately
} // End of catch(SQLException sqle)
if(alog.isEnabled(Log.PROCEDURE)) /* To avoid String Concat if not enabled */
alog.write("fnd.security.LoginManager.authenticate.end", "validUser=" + validUser, Log.PROCEDURE);
return success;
}
oracle.apps.fwk.util.OAPageContextクラスおよびoracle.apps.fwk.util.OADBTransactionクラスは、ログのコールをAppsLogクラスに委任します。UIコントローラでロギングをコールするには、OAPageContextを使用します。アプリケーション・モジュールからロギングをコールするには、OADBTransactionを使用します。
用意されている主要なロギングAPIは、次のとおりです。
指定のログ・レベルに対するロギングが使用可能な場合はtrueを返します。いずれの場合も、メッセージを作成してwriteDiagnosticsメソッドをコールする前に、ロギングが使用可能かどうかをテストします。
ログ・メッセージをデータベースに書き込みます。各ログ・メッセージにはログ順序、ユーザーID、セッションID、モジュール識別子、レベルおよびメッセージが含まれています。
oracle.apps.jtf.base.Loggerクラスは、ログのコールをAppsLogクラスに委任します。用意されている主要なロギングAPIは、次のとおりです。
このAPIを使用してメッセージを記録します。メッセージの長さは最大4000文字です。次に例を示します。
public class MyClass {
…
public boolean myAPI() {
…
if(Logger.isEnabled(Logger.STATEMENT)) // Important check for Performance!
Logger.out("My message", Logger.STATEMENT, MyClass.class);
}
}
クラスを使用できない場合(JSPの書込み時など)は、このAPIを使用して文字列で渡すことができます。メッセージの長さは最大4,000文字です。次に例を示します。
<% if(Logger.isEnabled(Logger.ERROR)) // Important check for Performance!
Logger.out("In JSP land use the JSP Name", Logger.ERROR,
"jtf.html.jtftest.jsp"); %>
このAPIを使用して例外を記録します。クラスを使用できない場合は、文字列オブジェクトで渡すことができます。例外の長さが4,000文字を超える場合、例外は複数の行に分割して記録されます。デフォルトでは、すべての例外がEXCEPTIONの重要度で記録されます。別の重要度で例外を記録する場合は、引数の1つとして重要度を取得する対応するAPIを使用できます。
For example:
Logger.out(Exception e, int severity, Class module);
注意: Logger APIのコールには整数値(1、2、3など)を指定しないでください。かわりに、適切な名称で重要度レベルを参照してください。
Logger.STATEMENT
Logger.PROCEDURE
Logger.EVENT
Logger.EXCEPTION
Logger.ERROR
Logger.UNEXPECTED
クライアント側デスクトップ・アプレットでロギングする場合は、fndctx.jarで使用できるFND AppletLogクラスを使用する必要があります。アプレットでのAppsLogの使用はサポートされていません。
AppletLogは、Javaコンソールに記録するSystem.outの単純なラッパーです。ロギングは、Javaコンソールで2つのJavaシステム・プロパティ(AFLOG_ENABLED、AFLOG_LEVEL)を設定することで制御できます。
これらの値は、アプレットを実行している特定のJREバージョンに対して構成する必要があります。「コントロール パネル」->「Java」->「Java」タブ->「Javaランタイム パラメータ」の順にナビゲートします(値を入力するにはテキスト領域をダブルクリックします)。アプレットの実行中にJavaアイコンを右クリックすることで、Windowsアイコン・トレイ(タスクバーにある)からJavaコンソールを起動することもできます。Javaアイコンをダブルクリックすると、JREバージョンを判断できます。
コード・サンプル:
import oracle.apps.fnd.common.logging.client.AppletLog;
...
...
AppletLog log = AppletLog.getAnonymousLog();
if (log.isEnabled(AppletLog.STATEMENT))
log.write(TreeViewer.class, "Rendering node=" + leaf, AppletLog.STATEMENT);
デフォルトでは、ロギングはUNEXPECTEDレベルで使用可能になります。
開発者向けの使用ガイドラインを読み、完全に理解して正しく標準に従っていることを確認します。中間層のロギングにはAppletLogを使用しないでください。
注意: AppletLogは、署名付きアプレット(E-Business Suiteの一部として正式にインストール/パッチされたすべてのアプレット)およびデフォルトのブラウザ・セキュリティ設定を使用して、正しく機能することがテストされました。署名のないアプレットまたはカスタム・ブラウザ・セキュリティ設定でAppletLogの使用を試みると、AppletLogが、それ自体を構成するJavaシステム・プロパティを読み取ろうとしたときにJavaセキュリティ例外が発生する可能性があります。ブラウザ・セキュリティ設定を調整すると、この状況の回避に役立つ可能性があります。(http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/default.mspx?mfr=trueで、「Microsoft IE Browser Java Security Settings」を参照してください)
PL/SQLのAPIはFND_LOGパッケージの一部です。これらのAPIでは、データベース・セッションのユーザー・セッション・プロパティを設定するために、適切なアプリケーション・ユーザー・セッション初期化API (たとえば、FND_GLOBAL.INITIALIZE(..))がすでに起動されていることを前提とします。これらのアプリケーション・ユーザー・セッションのプロパティ(UserId、RespId、AppId、SessionId)は、ログAPIに内部的に必要です。一般に、Oracle E-Business Suiteのすべてのフレームワークが、これらのセッション初期化APIを起動します。
プレーン・テキスト・メッセージを記録するには、FND_LOG.STRING(..)を使用します。
PACKAGE FND_LOG IS
LEVEL_UNEXPECTED CONSTANT NUMBER := 6;
LEVEL_ERROR CONSTANT NUMBER := 5;
LEVEL_EXCEPTION CONSTANT NUMBER := 4;
LEVEL_EVENT CONSTANT NUMBER := 3;
LEVEL_PROCEDURE CONSTANT NUMBER := 2;
LEVEL_STATEMENT CONSTANT NUMBER := 1;
/*
** Writes the message to the log file for the specified
** level and module
** if logging is enabled for this level and module
*/
PROCEDURE STRING(LOG_LEVEL IN NUMBER,
MODULE IN VARCHAR2,
MESSAGE IN VARCHAR2);
/*
** Writes a message to the log file if this level and module
** are enabled.
** The message gets set previously with FND_MESSAGE.SET_NAME,
** SET_TOKEN, etc.
** The message is popped off the message dictionary stack,
** if POP_MESSAGE is TRUE.
** Pass FALSE for POP_MESSAGE if the message will also be
** displayed to the user later.
** Example usage:
** FND_MESSAGE.SET_NAME(...); -- Set message
** FND_MESSAGE.SET_TOKEN(...); -- Set token in message
** FND_LOG.MESSAGE(..., FALSE); -- Log message
** FND_MESSAGE.RAISE_ERROR; -- Display message
*/
PROCEDURE MESSAGE(LOG_LEVEL IN NUMBER,
MODULE IN VARCHAR2,
POP_MESSAGE IN BOOLEAN DEFAULT NULL);
/*
** Tests whether logging is enabled for this level and module,
** to avoid the performance penalty of building long debug
** message strings unnecessarily.
*/
FUNCTION TEST(LOG_LEVEL IN NUMBER, MODULE IN VARCHAR2)
RETURN BOOLEAN;
Oracle Application Object Libraryセッションの初期化が発生し、ロギングが使用可能な場合は、次のコールによってメッセージが記録されます。
begin
/* Here is where you would call a routine that logs messages */
/* Important performance check, see if logging is enabled */
if( FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ) then
FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
'fnd.plsql.MYSTUFF.FUNCTIONA.begin', 'Hello, world!' );
end if;
/
FND_LOG.G_CURRENT_RUNTIME_LEVELグローバル変数によって、コール元は、ログ・メッセージが現在のレベルに対するものでない場合に、ファンクション・コールを回避できます。これは、FND_LOG_REPOSITORYパッケージによって自動的に作成されます。
if( FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ) then
dbg_msg := create_lengthy_debug_message(...);
FND_LOG.STRING(FND_LOG.LEVEL_EXCEPTION,
'fnd.form.ABCDEFGH.PACKAGEA.FUNCTIONB.firstlabel', dbg_msg);
end if;
FormsクライアントPL/SQLの場合、APIは同じです。ただし、ロギングが使用可能かどうかを確認するために、FND_LOG.TEST(..)をコールしてください。
たとえば、メッセージ・ディクショナリのメッセージを記録する場合は、次のようにします。
if( FND_LOG.LEVEL_UNEXPECTED >=
FND_LOG.G_CURRENT_RUNTIME_LEVEL) then
FND_MESSAGE.SET_NAME('FND', 'LOGIN_ERROR'); -- Seeded Message
-- Runtime Information
FND_MESSAGE.SET_TOKEN('ERRNO', sqlcode);
FND_MESSAGE.SET_TOKEN('REASON', sqlerrm);
FND_LOG.MESSAGE(FND_LOG.LEVEL_UNEXPECTED, 'fnd.plsql.Login.validate', TRUE);
end if;
次のAPIを使用して、Cからログを記録します。
#define AFLOG_UNEXPECTED 6
#define AFLOG_ERROR 5
#define AFLOG_EXCEPTION 4
#define AFLOG_EVENT 3
#define AFLOG_PROCEDURE 2
#define AFLOG_STATEMENT 1
/*
** Writes a message to the log file if this level and module is
** enabled
*/
void aflogstr(/*_ sb4 level, text *module, text* message _*/);
/*
** Writes a message to the log file if this level and module is
** enabled.
** If pop_message=TRUE, the message is popped off the message
** Dictionary stack where it was set with afdstring() afdtoken(),
** etc. The stack is not cleared (so messages below will still be
** there in any case).
*/
void aflogmsg(/*_ sb4 level, text *module, boolean pop_message _*/);
/*
** Tests whether logging is enabled for this level and module, to
** avoid the performance penalty of building long debug message
** strings
*/
boolean aflogtest(/*_ sb4 level, text *module _*/);
/*
** Internal
** This routine initializes the logging system from the profiles.
** It will also set up the current session and username in its state */
void afloginit();
次の各項では、コンカレント・プログラムでロギングを使用する方法について説明します。
コンカレント・プログラム要求ログは、エンド・ユーザーを対象としたメッセージにのみ使用します。デバッグ情報およびエラー詳細(システム管理者およびサポート担当を対象)をFND_LOGに記録します。
コンカレント・プログラムとアプリケーション・コードの両方で起動される可能性があるPL/SQL、JavaまたはCコードには、Oracle Application Object Library (FND)のログAPIのみを使用します。必要な場合は、ラッパー・コンカレント・プログラムで、進捗レポートを作成するために要求ログに適したバッチ処理とロギングを実行する必要があります。
メッセージ相関の場合、コンカレント・プログラム要求ログAPIは、EVENT重要度(ロギングがEVENTまたはその下のレベルで使用可能になっている場合のみ)で要求ログおよびFNDログの両方に対するメッセージを記録します。
Javaコンカレント・プロフラムでは、デバッグおよびエラー・ロギングに対してAppsLogを使用します。AppsLogインスタンスは、getLog()をコールすることでCpContextオブジェクトから取得できます。
注意: システム管理者またはOracleサポート(あるいはその両方)を対象としたデバッグ・メッセージまたは内部エラー・メッセージには、要求ログを使用しないでください。このようなメッセージは、FND_LOGにのみ記録してください。
要求ログは、コンカレント・プログラム(CP)のエンド・ユーザーUIです。CPコードを記述する場合は、翻訳可能なエンド・ユーザー向けメッセージのみを要求ログに記録してください。
たとえば、エンド・ユーザーが間違ったパラメータをCPに入力した場合は、ユーザーが修正処理を実行できるように、エラー・メッセージを要求ログに記録します。
-- Seeded Message for End-User
FND_MESSAGE.SET_NAME('FND', 'INVALID_PARAMETER');
-- Runtime Parameter Information
FND_MESSAGE.SET_TOKEN('PARAM_NAME', pName);
FND_MESSAGE.SET_TOKEN('PARAM_VALUE', pValue);
-- Useful for Auto-Logging Errors
FND_MESSAGE.SET_MODULE('fnd.plsql.mypackage.myfuntionA');
fnd_file.put_line( FND_FILE.LOG, FND_MESSAGE.GET );
ただし、内部ソフトウェア・エラーに起因してCPが失敗となった場合は、詳細なエラー・メッセージをFND_LOGに記録する必要があります。また、「内部エラーのために要求を完了できませんでした」などの高レベルな汎用メッセージも要求ログに記録して、エンド・ユーザーにエラーを知らせます。
注意: システム管理者またはOracleサポート(あるいはその両方)を対象としたデバッグ・メッセージまたは内部エラー・メッセージには、出力ファイルを使用しないでください。このようなメッセージは、FND_LOGにのみ記録してください。
出力ファイルは、CPによって生成された書式設定済のファイルで、プリンタに送信されたり、UIウィンドウに表示されます。たとえば、請求書は出力ファイルの一例です。
fnd_file.put_line( FND_FILE.OUTPUT, \******** XYZ Invoice ********' );
システム・アラートを呼び出して、システム管理者に深刻な問題または深刻な問題の可能性を通知します。システム・アラートは、Oracle Applications Managerコンソールに転送され、予約された管理者にもワークフロー通知で送信されます。次のいずれかに該当する場合は、これらのメッセージを使用してください。
処理を実行する必要があるのは、問題に直面したエンド・ユーザーではありません。
問題はシステム・プロセスによって発生し、そこにエンド・ユーザーはいません。
システム・アラートが転送されると、様々なコンテキスト情報が自動的に収集されます。これには、エンド・ユーザー、職責、製品、コンポーネント、OSプロセス、データベース・セッションなどの情報が含まれます。ユーザーはOracle Applications Managerを使用して、システム・アラート・メッセージからドリルダウンして、収集されたコンテキスト情報、関連するデバッグ・ログ・メッセージ、可能性がある他の関連情報を表示できます。
また、Oracle Applications Managerは、重複する通知が送信されないように、同じアラート・メッセージの複数回の発生を追跡します。
システム管理者職責で、メッセージ・フォームを使用して、すべてのシステム・アラート・メッセージをメッセージ・ディクショナリに定義する必要があります。
メッセージは、UNEXPECTED重要度で記録する必要があります。
メッセージは、エンコードされたメッセージ・ディクショナリ・メッセージである必要があります。
通知のルーティングを円滑化するために、メッセージには、メッセージ・ディクショナリの2つの属性を設定する必要があります。
Category: System、Product、SecurityまたはUser。
Severity: Critical、ErrorまたはWarning。
...
Exception
when others then
if( FND_LOG.LEVEL_UNEXPECTED >=
FND_LOG.G_CURRENT_RUNTIME_LEVEL) then
-- To be alertable, seeded message must have
-- Alert Category & Serverity defined
FND_MESSAGE.SET_NAME('FND', 'LOGIN_ERROR'); -- Seeded Message
-- Runtime Information
FND_MESSAGE.SET_TOKEN('ERRNO', sqlcode);
FND_MESSAGE.SET_TOKEN('REASON', sqlerrm);
FND_LOG.MESSAGE(FND_LOG.LEVEL_UNEXPECTED, 'fnd.plsql.Login.validate', TRUE);
end if;
...
if(alog.isEnabled(Log.UNEXPECTED)) {
// To be alertable, seeded Message MUST have Alert
// Category & Severity defined.
Message Msg = new Message("FND", "LOGIN_ERROR");
Msg.setToken("ERRNO", sqle.getErrorCode(), false);
Msg.setToken("REASON", sqle.getMessage(), false);
alog.write("fnd.security.LoginManager.authenticate", Msg, Log.UNEXPECTED);
}
システム・アラート・メッセージは短く簡潔にします。システム・アラートは問題を要約し、レポートおよび通知に使用され、関連する詳細へのリンクを順番に提供します。
コンテキスト情報トークンは、システム・アラート・メッセージに挿入しないでください。たとえば、コンカレント・プログラム名、フォーム名、時間、ルーチン、ユーザー、職責などは、システム・アラート・メッセージに含めません。このようなコンテキスト情報は、ロギングAPIによって自動的に収集されるため、システム・アラート・メッセージ内で重複することになります。また、アラート・メッセージは重複する通知のフィルタ処理に使用されます。システム・アラート・メッセージにコンテキスト情報を挿入すると、このフィルタ・メカニズムが無駄になります。
Category属性には値を設定する必要があります。この属性を使用して、アラートを分類し、通知を適切な予約にルーティングします。有効な値は、次のとおりです。
System
Systemカテゴリのアラート・メッセージは通常、テクノロジ・スタックを保守するシステム管理者やDBAなどの技術ユーザーにルーティングされます。
Product
Productカテゴリのアラート・メッセージは通常、製品の設定および保守を担当する機能管理者または製品スーパーユーザーにルーティングされます。
Security
Securityカテゴリのアラート・メッセージは、Oracle E-Business Suiteのセキュリティ上の問題について管理者に警告します。
User
Userカテゴリのアラート・メッセージは、Oracle E-Business Suiteのエンド・ユーザーによって報告された問題について管理者に警告します。
Severity属性には値を設定する必要があります。Oracle Applications Managerでは、この属性を使用してソートおよびフィルタを処理します。また、ユーザーは、この属性に基づいてアラート・メッセージの通知を予約できます。有効な値はCritical、ErrorおよびWarningです。Criticalは、深刻なエラーによって重要なビジネス・プロセスの進行が完全に阻害される場合や、大規模なユーザー・コミュニティに影響する場合に使用します。Errorは、Criticalほど深刻でない孤立したエラーに使用します。Warningは、ユーザーまたはビジネス・プロセスに対して、エラーによる負の影響が明確でない場合に使用します。
システム・アラートの詳細は、Oracle Applications Managerのオンライン・ヘルプを参照してください。
Copyright © 1995, 2013, Oracle and/or its affiliates. All rights reserved.