Hitachi

Cosminexus V11 アプリケーションサーバ 機能解説 拡張編


8.8.3 アプリケーションのユーザログ出力例

ここでは,具体的な例を示して,J2EEアプリケーションのユーザログを出力するための設定について説明します。

〈この項の構成〉

(1) ユーザログ出力で使用する例

次に示す例を使用して,J2EEアプリケーションのユーザログ出力の設定について説明します。使用する例の概要を次の図に示します。

図8‒4 J2EEアプリケーションのユーザログ出力例

[図データ]

A社では,ロガーの機能を使用して,業務履歴としてJ2EEアプリケーションの動作履歴をログファイルに出力します。A社のJ2EEアプリケーションのうち,動作履歴を出力したいJ2EEアプリケーションは「Application1」と「Application2」の2種類です。J2EEアプリケーションごとに,別々のファイルに異なるメッセージレベルのログを出力します。また,J2EEアプリケーション名のディレクトリを作成して,それぞれのログファイルを格納します。

(a) 「Application1」の特徴

「Application1」のロガー名称は「com.example.userlogger1」とします。

「Application1」は,複雑で規模の大きいJ2EEアプリケーションです。「SEVERE」レベルの重大なエラーが起こったときに,原因の切り分けを素早く行うために,JavaのExceptionのトレース情報を含むメッセージを「logfileA」に残しておきます。また,動作のトレースログとして「INFO」レベル以下のメッセージを「logfileB」に出力します。「com.example.userlogger1」からは,ログの出力レベルおよび出力内容に応じて2種類のログファイルを出力するために,「conf1」と「conf2」という2種類のCJMessageFileHandlerハンドラを作成しています。

「logfileA」の詳細
  • トレース情報を取得するため,「logfileA」への出力フォーマッタとして,「CJSimpleFormatter」を使用します。

  • 「logfileA」は,「SEVERE」レベルのメッセージだけが出力されるため,それほど多くのファイル容量を必要としません。しかし,トレース情報を出力するので,1メッセージ当たりのレコードは大きく(最大約4,096バイト),10,000レコードを蓄積できるようにするためには約40メガバイトの容量が必要となります。このため,サイズは10メガバイト,面数は4とします。

  • 「Application1」が出力したメッセージであることを判別するために,J2EEアプリケーション名を「my_app1」とします。

「logfileB」の詳細
  • 「logfileB」は,「INFO」レベル以下のすべてのメッセージが出力されるため,多くのファイル容量を必要とします。1日当たりのメッセージ量と保存期間から算出したログディスク容量は約256メガバイトです。また,ファイルの最大面数は16であるため,サイズは16メガバイト,面数は16とします。

  • 「Application1」が出力したメッセージであることを判別するために,J2EEアプリケーション名を「my_app1」とします。

(b) 「Application2」の特徴

「Application2」のロガー名称は「com.example.userlogger2」とします。

「Application2」は,ログメッセージの作り込み品質が高く,規模が小さいJ2EEアプリケーションです。必要最小限のメッセージだけをログに出力するため,「WARNING」レベル以上のメッセージを「logfileC」に残します。「com.example.userlogger2」からは1種類のログファイルを出力するため,「conf3」というCJMessageFileHandlerハンドラを作成しています。

「logfileC」の詳細
  • 「WARNING」レベルのメッセージだけが出力されます。また,1メッセージ当たりの最大長が約200バイトであるので,10,000レコードを蓄積するためには約2メガバイトの容量が必要となります。このため,サイズは1メガバイト,面数は2とします。

  • 「Application2」が出力したメッセージであることを判別するために,J2EEアプリケーション名を「my_app2」とします。

(c) デバッグ用の設定

開発中のデバッグ用の設定もしておきます。「com.example.userlogger1」と「com.example.userlogger2」へ送信されてきたすべてのメッセージの内容を表示するために,ロガー名称「com.example」のロガーへ,java.util.loggingの「ConsoleHandler」を接続しておきます。このロガーでは,子のロガーから伝播されるすべてのメッセージの内容を表示したいので,ロガーおよびハンドラのログ取得レベルは「ALL」とします。

(2) ユーザログ出力の設定例

「(1) ユーザログ出力で使用する例」で示した例でユーザログを出力する場合の設定例を次に示します。

(a) 簡易構築定義ファイルの設定例

簡易構築定義ファイルの設定例(物理ティアの定義の場合)を次に示します。

<configuration>
  <logical-server-type>j2ee-server</logical-server-type>
<!-- ロガーに渡されたログレコードを,親ロガーが使用しているハンドラに -->
<!-- 伝播させないようにします(ルートロガーがデフォルトで存在するため)。-->
  <param>
    <param-name>ejbserver.application.userlog.Logger.com.example.useParentHandlers</param-name>
    <param-value>false</param-value>
  </param>
<!-- 「logfileA」のJ2EEアプリケーション名,出力先,サイズ,面数,ログ取得レベル, -->
<!-- 使用するフォーマッタ名を指定します。 -->
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf1.appname</param-name>
    <param-value>my_app1</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf1.path</param-name>
    <param-value>application1/logfileA</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf1.limit</param-name>
    <param-value>10485760</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf1.count</param-name>
    <param-value>4</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf1.level</param-name>
    <param-value>SEVERE</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf1.formatter</param-name>
    <param-value>com.hitachi.software.ejb.application.userlog.CJSimpleFormatter</param-value>
  </param>
 
<!-- 「logfileB」のJ2EEアプリケーション名,出力先,サイズ,面数,ログ取得レベルを指定します。 -->
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf2.appname</param-name>
    <param-value>my_app1</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf2.path</param-name>
    <param-value>application1/logfileB</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf2.limit</param-name>
    <param-value>16777216</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf2.count</param-name>
    <param-value>16</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf2.level</param-name>
    <param-value>INFO</param-value>
  </param>
 
<!-- 「com.example.userlogger1」の使用するハンドラ名称「conf1」「conf2」の設定を使用して,-->
<!-- ファイルハンドラ(CJMessageFileHandler)を初期化して接続します。-->
<!-- ここで,ロガーとハンドラが作成されます。-->
  <param>
    <param-name>ejbserver.application.userlog.Logger.com.example.userlogger1.handlers</param-name>
    <param-value>com.hitachi.software.ejb.application.userlog.CJMessageFileHandler;conf1,com.hitachi.software.ejb.application.userlog.CJMessageFileHandler;conf2</param-value>
  </param>
 
<!-- 「com.example.userlogger1」のログ取得レベルを指定します。-->
<!-- 「conf1」「conf2」のレベルの高い方に合わせて,「INFO」とします。-->
  <param>
    <param-name>ejbserver.application.userlog.Logger.com.example.userlogger1.level</param-name>
    <param-value>INFO</param-value>
  </param>
 
<!-- 「logfileC」の出力先,ログ取得レベルを指定します。-->
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf3.appname</param-name>
    <param-value>my_app2</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf3.path</param-name>
    <param-value>application2/logfileC</param-value>
  </param>
  <param>
    <param-name>ejbserver.application.userlog.CJLogHandler.conf3.level</param-name>
    <param-value>WARNING</param-value>
  </param>
 
<!-- 「com.example.userlogger2」の使用するハンドラ名称「conf3」の設定を使用して,-->
<!-- ファイルハンドラ(CJMessageFileHandler)を初期化して接続します。-->
<!-- ここで,ロガーとハンドラが作成されます。-->
  <param>
    <param-name>ejbserver.application.userlog.Logger.com.example.userlogger2.handlers</param-name>
    <param-value>com.hitachi.software.ejb.application.userlog.CJMessageFileHandler;conf3</param-value>
  </param>
 
<!-- 「com.example.userlogger2」のログ取得レベルを指定します。-->
  <param>
    <param-name>ejbserver.application.userlog.Logger.com.example.userlogger2.level</param-name>
    <param-value>WARNING</param-value>
  </param>
 
<!-- デバッグ用の設定をします************************************************-->
<!-- 「ConsoleHandler」のログ取得レベルを指定します。-->
  <param>
    <param-name>java.util.logging.ConsoleHandler.level</param-name>
    <param-value>INFO</param-value>
  </param>
 
<!-- 「com.example」のロガーで使用するハンドラ名称「ConsoleHandler」を指定して,-->
<!-- ハンドラに接続します。ここで,ロガーとハンドラが作成されます。-->
  <param>
    <param-name>ejbserver.application.userlog.Logger.com.example.handlers</param-name>
    <param-value>java.util.logging.ConsoleHandler</param-value>
  </param>
 
<!-- 「com.example」のロガーのログ取得レベルを指定します。-->
  <param>
    <param-name>ejbserver.application.userlog.Logger.com.example.level</param-name>
    <param-value>ALL</param-value>
  </param>
 
<!-- デバッグが不要になった場合は,親のロガーへの伝播の設定を解除します。-->
<!--
  <param>
    <param-name>ejbserver.application.userlog.Logger.com.example.userlogger1.useParentHandlers</param-name>
    <param-value>false</param-value>
  </param>
-->
<!--
  <param>
    <param-name>ejbserver.application.userlog.Logger.com.example.userlogger2.useParentHandlers</param-name>
    <param-value>false</param-value>
  </param>
-->
<!-- デバッグが不要になった場合は,「com.example」の作成を解除します。-->
<!--
  <param>
    <param-name>ejbserver.application.userlog.loggers</param-name>
    <param-value>com.example.userlogger1, com.example.userlogger2</param-value>
  </param>
-->
<!-- *************************************************************************-->
 
<!-- ロガーの使用を宣言します。-->
  <param>
    <param-name>ejbserver.application.userlog.loggers</param-name>
    <param-value>com.example,com.example.userlogger1,com.example.userlogger2</param-value>
  </param>
</configuration>

(b) 「Application1」の設定例

「Application1」のソースコード例を次に示します。

import java.util.logging.*;
import com.hitachi.software.ejb.application.userlog.*;
 
public class application1{
 
    static Logger logger = Logger.getLogger("com.example.userlogger1");
 
    public static void exec(){
 
        logger.log(
                   CJLogRecord.create(Level.INFO,
                   "application1 start.","AP1_10000-I"));
 
        try{
 
            throw new Exception("Exception1!");
 
        }
        catch(Exception ex){
 
            logger.log(
                       CJLogRecord.create(Level.SEVERE,
                       "Catch an exception!", ex, "AP1_10100-E"));
 
        }
 
        logger.log(
                   CJLogRecord.create(Level.INFO,
                   "application1 end.","AP1_10001-I"));
 
    }
 
}

application1/logfileA1.logの出力例を次に示します。

     yyyy/mm/dd hh:mm:ss.sss            pid      tid      message-id  message(LANG=ja)
0047 2003/12/06 19:51:32.265  my_app1   00EB7859 012A54F9 AP1_10100-E 2003/12/06 
19:51:32|application1|exec|致命的|Catch an exception!|java.lang.Exception: 
Exception1!|application1.exec(application1.java.18)|application1.main(application1.java.64)

application1/logfileB1.logの出力例を次に示します。

     yyyy/mm/dd hh:mm:ss.sss           pid      tid      message-id   message(LANG=ja)
0046 2003/12/06 19:51:32.250  my_app1  00EB7859 012A54F9 AP1_10000-I  application1 start.
0048 2003/12/06 19:51:32.265  my_app1  00EB7859 012A54F9 AP1_10100-E  Catch an exception!
0049 2003/12/06 19:51:32.265  my_app1  00EB7859 012A54F9 AP1_10001-I  application1 end.

コンソール画面の出力例を次に示します。

情報: application1 start.
2003/12/06 19:51:32 application1 exec
致命的: Catch an exception!
java.lang.Exception: Exception1!
        at application1.exec(application1.java:18)
        at application1.main(application1.java:64)
2003/12/06 19:51:32 application1 exec
情報: application1 end.

(c) 「Application2」の設定例

「Application2」のソースコード例を次に示します。

import java.util.logging.*;
import com.hitachi.software.ejb.application.userlog.*;
 
public class application2{
 
    static Logger logger = Logger.getLogger("com.example.userlogger2");
 
    public static void exec(){
 
        logger.log(
                   CJLogRecord.create(Level.INFO,
                   "application2 start.","AP2_20000-I"));
 
        try{
 
            throw new Exception("Exception2!");
 
        }
        catch(Exception ex){
 
            logger.log(
                        CJLogRecord.create(Level.SEVERE,
                       "Catch an exception!", ex, "AP2_20100-E"));
 
        }
 
        logger.log(
                   CJLogRecord.create(Level.INFO,
                   "application2 end.","AP2_20001-I"));
 
    }
 
}

application2/logfileC1.logの出力例を次に示します。

     yyyy/mm/dd hh:mm:ss.sss           pid      tid      message-id   message(LANG=ja)
0048 2003/12/06 19:51:32.265  my_app2  00EB7859 012A54F9 AP2_20100-E  Catch an exception!

(d) 「Application3」の設定例

さらに,「Application3」というJ2EEアプリケーションのログを「Application1」と同じログファイルに出力する場合の例を説明します。この場合,「Application3」は「Application1」と同じプロセス内(スレッドは異なっていてもよい)で同じロガー名称を使用してロガーを取得する必要があります。

「Application3」のソースコード例を次に示します。

import java.util.logging.*;
import com.hitachi.software.ejb.application.userlog.*;
 
public class application1{
 
    static Logger logger = Logger.getLogger("com.example.userlogger1");
 
    public static void exec(){
 
        logger.log(,
                   CJLogRecord.create(Level.INFO,
                   "application3 start.","my_app3","AP3_30000-I"));
 
        try{
 
            throw new Exception("Exception3!");
 
        }
        catch(Exception ex){
 
            logger.log(,
                       CJLogRecord.create(Level.SEVERE,
                       "Catch an exception!", ex, "my_app3","AP3_30100-E"));
 
        }
 
        logger.log(
                   CJLogRecord.create(Level.INFO,
                   "application3 end.","my_app3","AP3_30001-I"));
 
    }
 
}

application1/logfileB1.logの出力例を次に示します。

     yyyy/mm/dd hh:mm:ss.sss           pid      tid      message-id   message(LANG=ja)
0046 2003/12/06 19:51:32.250  my_app1  00EB7859 012A54F9 AP1_10000-I  application1 start.
0093 2003/12/06 19:51:32.265  my_app3  00EB7859 010CB027 AP3_30000-I  application3 start.
0095 2003/12/06 19:51:32.265  my_app1  00EB7859 012A54F9 AP1_10100-E  Catch an exception!