ヘッダーをスキップ

Oracle E-Business Suite開発者ガイド
リリース12.2
E53035-01
目次へ
目次
前のページへ
前へ
次のページへ
次へ

開発者向けロギング・ガイドライン

概要

開発者は、コンポーネント全体にわたってロギングAPIを頻繁に利用することになります。ロギングは不具合がレポートされた場合に問題を局所化するのに役立ちます。ロギング・コールを配置する場所を慎重に選択し、理解しやすいコードを記述して、役に立つ必要な情報のみをログ・メッセージに挿入することをお薦めします。

ログ・メッセージ・テキスト、モジュール・ソースおよび重要度は、APIのコーディングを介して直接指定します。これらの3つのフィールドは、コード操作以外の方法では変更または修正できないため、情報は可能なかぎり有益で簡潔にすることを目指します。

開発者として理解しておく必要があるのは、いくつかのAPIと6つの重要度のみです。適切なAPIをコールして、次の3つのフィールドを渡します。

その他のフィールドはすべてAPIによって自動的に移入されます。

API

次のAPIを使用して、ログ・メッセージをデータベースに書き込みます。

APIがデータベースに書き込む場合は、一般にパッケージFND_LOG_REPOSITORYと通信します。このパッケージは、メッセージを実際に書き込むパッケージです。中間層エッジ・ケースのデバックでは、ログ・メッセージをファイルに送信できます。

エラーの処理

次のプロシージャを使用して、コードのエラーを処理します。

ステップ1: 内部エラー詳細(例: 例外スタック・トレース、関連する状態情報)を記録します。これらの詳細は、問題を診断するためにシステム管理者やサポート担当などによって使用されます。

ステップ2: 深刻なエラーの場合は、システム・アラートを発生させてシステム管理者に通知します。

ステップ3: エラーがエンド・ユーザーに影響する場合は、UIを介して(または、コンカレント・プログラムの場合は要求ログを介して)エンド・ユーザーにエラーを報告します。メッセージは、ユーザーが理解しやすい翻訳可能なメッセージを使用し、内部エラーの詳細は挿入しないようにします。

パフォーマンス標準

パフォーマンス上の理由で、メッセージの重要度に関するロギングが使用可能かどうかをチェックする必要があります。これは、オブジェクトの作成前、またはログ・メッセージを形成する文字列の連結前に実行します。整数の値をチェックするほうが、オブジェクトの割当や文字列の連結よりもコストは低くなります。ファンクションの引数は、ファンクション・コールの前に作成されることを思い出してください。つまり、文字列の連結は、ログのwrite*(..)コールの前に実行します。ロギングが使用可能かどうかを明示的にチェックして、ロギングが使用不可の場合は文字列の作成を回避してください。

サンプルJavaコード

if( AppsLog.isEnabled(Log.EVENT) )
AppsLog.write("fnd.common.WebAppsContext", str1 + str2, Log.EVENT);  

サンプルPL/SQLコード

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>

次に、各構文の構成要素について詳細に説明します。

<application short name>

コード・ブロックの所有者アプリケーションを示し、小文字で指定します。例: fnd、jtf、wf、sqlgl、inv。

<directory> | <package>

ファイルが存在しているディレクトリまたはパッケージを示します。一般に、これは実際のファイル・システム・ディレクトリ名です。通常、ディレクトリには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

<file> | <Class>

コードが含まれているパッチ適用可能エンティティ(ファイル)を示します。サーバー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

<routine>

コードのルーチン、プロシージャ、メソッドまたはファンクションを示します。ルーチン名がない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

<label>

ルーチン内の特定の部分に対する記述名です。ラベルを指定する主な理由は、厳密に1つのログ・コールをモジュール名で一意に識別するためです。これによって、アナリストまたはプログラマは、メッセージ(翻訳される可能性がある)を確認しなくても、メッセージを生成したコード部分を正確に把握できるようになります。したがって、各ログ文に対するラベルはルーチン内で一意にする必要があります。

自動的に使用可能または使用不可にできるように、様々なルーチンおよびファイルからの複数のログ・コールをグループ化する場合は、2つの部分で構成されるラベルが使用されます。最初の部分は機能グループ名で、2番目の部分は一意のコードの場所です。

たとえば、Oracle Application Object Library (FND)の付加フレックスフィールド検証コードには、次のようなラベルが指定された異なる場所に、様々なログ・コールがあります。

これらがコード内の異なる場所にある場合も、モジュールを「fnd.%.desc_flex_val.%」と設定することで、すべてを使用可能にできます。

PROCEDUREレベルで記録されるメッセージでは、処理開始時に記録するメッセージに「begin」のラベルを使用し、処理終了時に記録するメッセージに「end」またはそれに類する内容(「end_exception」など)を使用します。例: begin、end、lookup_app_id、parse_sql_failed、myfeature.done_exec。

モジュール名標準

次のガイドラインを使用して、すべてのアプリケーションにわたって一意のモジュール名にする要件を満たすようにコードを記述します。

モジュール名の例

重要度

使用可能なログ重要度およびその使用方法を要約した表は、「AFLOG_LEVEL」の項を参照してください。

STATEMENTおよびPROCEDUREは、内部のOracle開発によるデバッグを目的としています。重要度がさらに高いEVENT、EXCEPTION、ERRORおよびUNEXPECTEDは幅広い利用者が存在します。ERRORおよびUNEXPECTEDのメッセージのモニターし、その解決を試みることをお薦めします。

内部エラーおよび外部エラーのすべてのメッセージをEXCEPTION、ERRORまたはUNEXPECTEDで記録します。ERRORおよびUNEXPECTEDのメッセージは、翻訳可能なメッセージ・ディクショナリのメッセージにします。

ログ・メッセージの挿入場所の判断は繰返しのプロセスになります。コードの使用方法を詳細に学習することで、ログ・メッセージの挿入場所についてさらに理解が深まり、エラーの根本原因の速やかな隔離に役立ちます。少なくとも、次の各項で説明するシナリオのメッセージを記録してください。

UNEXPECTED

この重要度は、一般的にコードまたは環境の修正が必要な未処理の内部ソフトウェア・エラーを示します。

発生する回復不能なエラーをUNEXPECTEDとして記録します。UNEXPECTED重要度で記録されるメッセージは、システム・アラートとしてシステム管理者に自動的に伝播されるため、メッセージ・ディクショナリ・ベースのメッセージでこの重要度を使用する際は慎重に検討してください。ログ・メッセージはすべて簡潔で有意義なものである必要がありますが、UNEXPECTEDメッセージは、システム管理者がエラーを速やかに理解できるように、特に配慮して作成および確認してください。

ERROR

この重要度は、一般的にエンド・ユーザーによる修正が必要な外部エンド・ユーザー・エラーを示します。

すべてのユーザー・エラー状況をERRORとして記録します。システム管理者は、ERRORメッセージのロギングを使用可能に選択し、ユーザーに提示されたエラーを確認できます。

ERRORメッセージはメッセージ・ディクショナリを使用して、FND_NEW_MESSAGESにシードされる必要があります。対応するエラーが実行時に発生した場合は、メッセージを記録し、適用可能な場合は適切に表示する必要があります。詳細は、「シード・メッセージ・ディクショナリ・メッセージの自動ロギングおよびアラート」の項を参照してください。

次のERRORおよびUNEXPECTEDメッセージには、次の内容を指定します。

EXCEPTION

この重要度は、一般的に修正が不要な処理済の内部ソフトウェア・エラーを示します。

Javaの例外は常に記録する必要があります。Java例外は通常のコード・フローの一部ではないため、無視しないでください。例外をコードで適切に処理し、デバッグ用に記録する必要があります。例外を発生させる場合は、最初に例外の原因を記録します。メッセージ・テキストではなく例外オブジェクトを渡す便利なログAPIが用意されています。重要度が渡されないと、Java例外はデフォルトでEXCEPTIONの重要度で記録されます。

製品が機能するのを妨げる深刻な例外は、UNEXPECTEDの重要度で記録します。たとえば、ユーザーによる新規発注時のSQLExceptionをUNEXPECTEDとして記録します。

EVENT

この重要度は、高レベルの進捗レポートに使用されます。フロー内でのステップの完了、ビジネス・トランザクションの開始など、アプリケーションのマイルストンに適用されます。

アプリケーション・コードが構成可能な値を読み取るたびに、構成された値を記録する必要があります。値は、プロファイル、事前にわかっているオブジェクトの属性(例: 顧客のプライマリ住所)、デフォルト設定ルールなどから取得できます。ソース、名称および値を記録します。一貫性を保持するために、そのようなメッセージのモジュール・フィールド内のラベルには、「.config」を追加してください。例: fnd.common.MyClass.MyAPI.config

PROCEDURE

この重要度は、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をコールする場合などが該当します。

STATEMENT

この重要度は、低レベルの進捗レポートに使用されます。

SQL(動的SQL)を生成する場合は、それを記録する必要があります。

すべてのバインド変数を記録します。

ユーザー・インタフェースの選択またはユーザー・インタフェースの動的変更を記録する必要があります。たとえば、switcher Beanの使用、次のページへの移動などが該当します。

必要に応じて、関連する状態変数を含めます。

大きいテキストおよびバイナリ・メッセージの添付

メッセージ添付APIを使用して、その他のコンテキスト情報をログ・メッセージまたはシステム・アラート(あるいはその両方)に追加できます。この機能には、大きい添付を記録するためのバッファリングされた効率的な書込みAPIが用意されています。このような添付用にシードされたメッセージ・テキストには、エラーの簡単な説明を指定し、添付には関連するコンテキスト詳細すべてを格納します。

現在、添付はデータベースLOBに保存されます。添付はOracle Applications Managerを介して表示できます。

Javaコード

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) { }
} 
}

PL/SQLコード

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レベルでログ構成を使用可能にする必要があります。

一般ロギング・ヒント

Javaからログを記録する方法

AppsLogは、コア・ロギング機能を提供するクラスです。Oracle CRM Technology Foundationには、AppsLogの便利なラッパーAPIが用意されています。この項では、AppsLogの使用方法およびラッパーAPIについて説明します。

コアAppsLog

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;
}

OAPageContextおよびOADBTransaction API

oracle.apps.fwk.util.OAPageContextクラスおよびoracle.apps.fwk.util.OADBTransactionクラスは、ログのコールをAppsLogクラスに委任します。UIコントローラでロギングをコールするには、OAPageContextを使用します。アプリケーション・モジュールからロギングをコールするには、OADBTransactionを使用します。

用意されている主要なロギングAPIは、次のとおりです。

isLoggingEnabled(int logLevel)

指定のログ・レベルに対するロギングが使用可能な場合はtrueを返します。いずれの場合も、メッセージを作成してwriteDiagnosticsメソッドをコールする前に、ロギングが使用可能かどうかをテストします。

writeDiagnostics(Object module, String messageText, int logLevel)

ログ・メッセージをデータベースに書き込みます。各ログ・メッセージにはログ順序、ユーザーID、セッションID、モジュール識別子、レベルおよびメッセージが含まれています。

CRM Technology FoundationのAPI

oracle.apps.jtf.base.Loggerクラスは、ログのコールをAppsLogクラスに委任します。用意されている主要なロギングAPIは、次のとおりです。

Logger.out(String message, int severity, Class module);

この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);
}
}

Logger.out(String message, int severity, Object module);

クラスを使用できない場合(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"); %>

Logger.out(Exception e, Class module);

この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

AppletLog (アプレット・クライアント・デスクトップ)のロギング

クライアント側デスクトップ・アプレットでロギングする場合は、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からログを記録する方法

PL/SQLのAPIはFND_LOGパッケージの一部です。これらのAPIでは、データベース・セッションのユーザー・セッション・プロパティを設定するために、適切なアプリケーション・ユーザー・セッション初期化API (たとえば、FND_GLOBAL.INITIALIZE(..))がすでに起動されていることを前提とします。これらのアプリケーション・ユーザー・セッションのプロパティ(UserId、RespId、AppId、SessionId)は、ログAPIに内部的に必要です。一般に、Oracle E-Business Suiteのすべてのフレームワークが、これらのセッション初期化APIを起動します。

プレーン・テキスト・メッセージを記録するには、FND_LOG.STRING(..)を使用します。

APIの説明

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;

Cからログを記録する方法

次の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は、重複する通知が送信されないように、同じアラート・メッセージの複数回の発生を追跡します。

システム管理者職責で、メッセージ・フォームを使用して、すべてのシステム・アラート・メッセージをメッセージ・ディクショナリに定義する必要があります。

システム・アラートの呼出し

PL/SQLコード・サンプル

...
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;
...

Javaコード・サンプル

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);
}

システム・アラートの定義のガイドライン