WebLogic Server ロギング サービスの使い方
|
|
|
WebLogic Server メッセージ カタログおよび NonCatalogLogger でメッセージが生成されるとき、それらのメッセージは java.util.logging.Logger オブジェクトに配信されます。Logger オブジェクトは、メッセージを説明する WLLogRecord オブジェクトを割り当て、Logger をサブスクライブしているすべてのメッセージ ハンドラにその WLLogRecord をパブリッシュします。
WebLogic Server は、ログ メッセージを受信して出力するメッセージ ハンドラをインスタンス化し、サブスクライブさせます。独自のメッセージ ハンドラを作成して、WebLogic Server Logger オブジェクトをサブスクライブするようにもできます (図 5-1 を参照)。
たとえば、アプリケーションがクライアント JVM で動作しており、そのアプリケーションがアプリケーションの生成するメッセージをリスンするようにしたい場合は、ハンドラを作成し、それにクライアント JVM の Logger オブジェクトをサブスクライブさせることができます。アプリケーションが特定サブシステムの障害を知らせるログ メッセージを受信した場合、そのアプリケーションは以下のようなアクションを実行できます。
以下の節では、メッセージ ハンドラの作成とサブスクライブについて説明されています。
WebLogic Server の Logger と Handler の詳細については、「メッセージの配信とフィルタ処理の概要」を参照してください。
作成し、Logger オブジェクトをサブスクライブさせたハンドラは、その Logger のレベルとフィルタ基準を満たすすべてのメッセージを受信します。ハンドラでは、Logger がパブリッシュする特定のメッセージだけに応答するように追加のレベルとフィルタ基準を指定することもできます。
ハンドラを作成してサブスクライブさせるには、次の手順に従います。
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.ErrorManager;
import weblogic.logging.WLLogRecord;
import weblogic.logging.WLLevel;
import weblogic.logging.WLErrorManager;
import weblogic.logging.LoggingHelper;
リソースと連係して機能するハンドラはすべて、flush メソッド (バッファされた出力をフラッシュするため) および close メソッド (開いているリソースを閉じるため) を実装する必要があります。
親 Logger オブジェクトが閉じると、すべてのハンドラで Handler.close メソッドが呼び出されます。close メソッドは、flush メソッドを呼び出してからそれ独自のロジックを実行します。
Handler オブジェクトが受信するメッセージのタイプを指定するフィルタ クラスを作成します。詳細については、「Logger と Handler のフィルタの設定」を参照してください。
この例では、JDBC データ ソースに接続し、メッセージをデータベース テーブルに挿入する SQL 文を発行するハンドラを作成します。この例では、以下のクラスを実装します。
Handler クラス。「例 : Handler クラスの実装」を参照してください。Filter クラス。「Logger と Handler のフィルタの設定」を参照してください。Logger クラスをサブスクライブさせるクラス。「例 : Logger クラスのサブスクライブ」を参照してください。 コード リスト 5-1 の Handler クラス例は、次のようにしてデータベースにメッセージを書き込みます:
javax.naming.InitialContext オブジェクトを作成し、Context.lookup メソッドを呼び出して myPoolDataSource というデータ ソースをルックアップします。エラー マネージャの詳細については、Sun API のドキュメントで java.util.logging.ErrorManager を参照してください。
WLLogRecord メソッドの詳細については、WLLogRecord の「Javadoc」を参照してください。
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Filter;
import java.util.logging.ErrorManager;
import weblogic.logging.WLLogRecord;
import weblogic.logging.WLLevel;
import weblogic.logging.WLErrorManager;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import weblogic.logging.LoggingHelper;
public class MyJDBCHandler extends Handler {
private Connection con = null;
public MyJDBCHandler() throws NamingException, SQLException {
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("myPoolDataSource");
con = ds.getConnection();
setErrorManager(new ErrorManager() {
public void error(String msg, Exception ex, int code) {
System.err.println("Error reported by MyJDBCHandler "
+ msg + ex.getMessage());
//このハンドラのインスタンスをすべて削除
LoggingHelper.getServerLogger().removeHandler(
MyJDBCHandler.this);
}
});
}
public void publish(LogRecord record) {
WLLogRecord rec = (WLLogRecord)record;
if (!isLoggable(rec)) return;
try {
PreparedStatement stmt = con.prepareStatement(
"INSERT INTO myserverLog VALUES (?, ?, ?,?)");
stmt.setEscapeProcessing(true);
stmt.setString(1, rec.getId());
stmt.setString(2, rec.getLevel().getLocalizedName());
stmt.setString(3, rec.getLoggerName());
stmt.setString(4, rec.getMessage());
stmt.executeUpdate();
flush();
} catch(SQLException sqex) {
reportError("Error publihsing to SQL", sqex,
ErrorManager.WRITE_FAILURE);
}
}
public void flush() {
try {
con.commit();
} catch(SQLException sqex) {
reportError("Error flushing connection of MyJDBCHandler",
sqex, ErrorManager.FLUSH_FAILURE);
}
}
public boolean isLoggable(LogRecord record) {
Filter filter = getFilter();
if (filter != null) {
return filter.isLoggable(record);
} else {
return true;
}
}
public void close() {
try {
con.close();
} catch(SQLException sqex) {
reportError("Error closing connection of MyJDBCHandler",
sqex, ErrorManager.CLOSE_FAILURE);
}
}
}
コード リスト 5-2 のクラス例は次のように機能します:
サーバが起動するたびにハンドラとフィルタがサーバの Logger オブジェクトをサブスクライブするようにしたい場合は、このクラスを WebLogic Server 起動クラスとしてデプロイします。起動クラスの詳細については、Administration Console オンライン ヘルプの「起動クラスと停止クラス」を参照してください。
コード リスト 5-2例 : Logger クラスのサブスクライブ
import java.util.logging.Logger;
import java.util.logging.Handler;
import java.util.logging.Filter;
import java.util.logging.LogRecord;
import weblogic.logging.LoggingHelper;
import weblogic.logging.FileStreamHandler;
import weblogic.logging.WLLogRecord;
import weblogic.logging.WLLevel;
import java.rmi.RemoteException;
import weblogic.jndi.Environment;
import javax.naming.Context;
public class LogConfigImpl {
public void configureLogger() throws RemoteException {
Logger logger = LoggingHelper.getServerLogger();
try {
Handler h = null;
h = new MyJDBCHandler();
logger.addHandler(h);
h.setFilter(new MyFilter());
} catch(Exception nmex) {
System.err.println("Error adding MyJDBCHandler to logger "
+ nmex.getMessage());
logger.removeHandler(h);
}
}
public static void main(String[] argv) throws Exception {
LogConfigImpl impl = new LogConfigImpl();
impl.configureLogger();
}
}
WebLogic Server 8.1 より前のリリースでは、WebLogic ロギング サービスからメッセージを受信する唯一の方法は、Java Management Extensions (JMX) リスナを作成して、それを LogBroadcasterRuntimeMBean に登録することでした。WebLogic Server 8.1 では、JDK 1.4 ハンドラを使用してログ メッセージを受信 (サブスクライブ) できます。
JDK 1.4 ハンドラでも JMX リスナでも同様の結果が得られますが、JDK 1.4 API には Formatter クラスがあり、Handler オブジェクトはこのクラスを使用して受信したメッセージをフォーマットできます。JMX では、メッセージをフォーマットするこのような API は提供されません。フォーマッタの詳細については、Sun API のドキュメントで、Formatter (http://java.sun.com/j2se/1.4/docs/api/java/util/logging/Formatter.html) を参照してください。
さらに、JDK 1.4 Handler API は JMX API よりも使いやすく、過程が直接的です。たとえば、次のコードは JDK 1.4 Logger オブジェクトを取得し、ハンドラにそのオブジェクトをサブスクライブさせます。
Logger logger = LoggingHelper.getServerLogger();
Handler h = null;
h = new MyJDBCHandler();
logger.addHandler(h)
JMX リスナを登録して同様の結果を得るには、コード リスト 5-3 のようなコードを使用する必要があります。そのコードは MBeanHome インタフェース、RemoteMBeanServer インタフェース、および LogBroadcasterRuntimeMBean をルックアップして、それからリスナを登録します。
JMX リスナの使い方については、『WebLogic JMX Service プログラマーズ ガイド』の「WebLogic Server MBean の通知とモニタの使い方」を参照してください。
MBeanHome home = null;
RemoteMBeanServer rmbs = null;
//ドメイン変数
String url = "t3://localhost:7001";
String serverName = "Server1";
String domainName= "mydomain"
String username = "weblogic";
String password = "weblogic";
//MBeanHome を使用して MBeanServer を取得
try {
Environment env = new Environment();
env.setProviderUrl(url);
env.setSecurityPrincipal(username);
env.setSecurityCredentials(password);
Context ctx = env.getInitialContext();
//管理 MBeanHome インタフェースを取得
home = (MBeanHome) ctx.lookup(MBeanHome.ADMIN_JNDI_NAME);
System.out.println("Got the Admin MBeanHome: " + home );
rmbs = home.getMBeanServer();
} catch (Exception e) {
System.out.println("Caught exception: " + e);
}
try {
//リスナ クラスをインスタンス化
MyListener listener = new MyListener();
MyFilter filter = new MyFilter();
//サーバのログ ブロードキャスタのWebLogicObjectName logBCOname = new
//WebLogicObjectName を作成
WebLogicObjectName("TheLogBroadcaster",
"LogBroadcasterRuntime", domainName, serverName);
//MBean の名前とリスナ クラスを MBeanServer の
//addNotificationListener メソッドに渡す
rmbs.addNotificationListener(logBCOname, listener, filter, null);
} catch(Exception e) {
System.out.println("Exception: " + e);
}
}
|
|
|
|