WebLogic 診断フレームワークのコンフィグレーションと使い方

     前  次    新しいウィンドウで目次を開く     
ここから内容の開始

データ アクセサを使用した診断データへのアクセス

WebLogic 診断フレームワーク (WLDF) のデータ アクセサ コンポーネントを使用すると、ログ レコード、データ イベント、収集されたメトリックなどのさまざまなソースから得られた診断データにアクセスできます。

データ アクセサを使用すると、型、コンポーネント、属性を基準としてデータをルックアップできます。時間ベースのフィルタ処理を実行でき、イベントにアクセスする際には重大度、ソース、コンテンツを基準としたフィルタ処理が可能です。また、表形式の診断データにアクセスすることもできます。

以下の節では、データ アクセサについて説明し、オンライン (サーバが実行中の状態) およびオフライン (サーバが実行中でない状態) でデータ アクセサを使用する方法について示します。

 


データ アクセサのアクセス対象のデータ ストア

データ アクセサでは、他の WLDF コンポーネントから診断情報を取得します。キャプチャされた情報は、診断データの種類別に分かれた複数の論理データ ストア内に分類されます。たとえば、サーバ ログ、HTTP ログ、収集されたメトリックは、それぞれ別のデータ ストアにキャプチャされます。

WLDF では、診断データがサーバ単位で管理されます。そのため、データ アクセサでは個々のサーバのデータ ストアにアクセスできます。

データ ストアは表形式を取ることがあります。表の各レコードが 1 つの項目を表し、その項目の特性が複数のカラムで説明されます。さまざまなデータ ストアに多様なカラムがありますが、データ項目が収集された時間などほとんどのデータ ストアで共有されるカラムもあります。

データ アクセサでは、サーバの WLDF で使用されるデータ ストアについて以下のような情報を取得できます。

WLDFAccessRuntimeMBean を使用すると、このようなデータ ストアを検索したり、データ ストアにあるデータの性質を判断したりできます。また、クエリを使用してそうしたデータに選択的にアクセスすることもできます。

WebLogic のログの詳細については、『ログ ファイルのコンフィグレーションとログ メッセージのフィルタ処理』を参照してください。

 


診断データへのオンライン アクセス

実行中のサーバの診断データには、Administration Console、JMX API 群、または WebLogic Scripting Tool (WLST) を使用してアクセスします。

Administration Console を使用してデータにアクセスする

Administration Console では、明示的にデータ アクセサを使用することはありませんが、アクセサで収集された情報は Administration Console に表示されます。たとえば、[ログ ファイルの概要] ページなどがそれに該当します。Administration Console オンライン ヘルプの「ログの表示とコンフィグレーション」を参照してください。

実行時 MBean を使用してプログラム的にデータにアクセスする

データ アクセサには、データ ストアの検索とデータ ストアからのデータ取得のために以下の実行時 MBean が用意されています。

WLST を使用してオンラインで診断データにアクセスする

WLST の exportDiagnosticDataFromServer コマンドを使用すると、実行中のサーバの診断データにアクセスできます。このコマンドの構文とサンプルについては、「WLST コマンドおよび変数リファレンス」の「診断コマンド」を参照してください。

データ アクセサで WLDF クエリ言語を使用する

データ ストアのデータを問い合わせるには、WLDF クエリ言語を使用します。データ アクセサのクエリ言語の構文については、「WLDF クエリ言語」を参照してください。

 


診断データへのオフライン アクセス

WLST の exportDiagnosticData コマンドを使用すると、オフライン状態にあるサーバの診断データの履歴にアクセスできます。このコマンドの構文とサンプルについては、「WLST コマンドおよび変数リファレンス」の「診断コマンド」を参照してください。

注意 : アーカイブされたデータについては、そのデータの永続化を行ったマシンに置かれている場合にのみ exportDiagnosticData を使用してアクセスできます。
注意 : データ アクセサのオフライン モードでは、データ ストア インスタンスの検索はできません。インスタンスについてはあらかじめ認識しておく必要があります。

 


診断データへのプログラム的なアクセス

コード リスト 12-1 では、アクセサを使用してさまざまなアーカイブ データ ストアに問い合わせるユーティリティの Java ソース コードを示します。

コード リスト 12-1 WLDF アクセサを使用するサンプル コード

 * WLAccessor.java
 *
 * WLDF アクセサを介してさまざまなアーカイブ データ ストアに問合せできる
 * ユーティリティを例示
 *
 */
 
 import javax.naming.Context;
 import weblogic.jndi.Environment;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.Properties;
 import weblogic.management.ManagementException;
 import weblogic.management.runtime.WLDFAccessRuntimeMBean;
 import weblogic.management.runtime.WLDFDataAccessRuntimeMBean;
 import weblogic.diagnostics.accessor.ColumnInfo;
 import weblogic.diagnostics.accessor.DataRecord;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 
 import javax.management.MBeanServerConnection;
 import javax.management.remote.JMXConnector;
 import javax.management.remote.JMXConnectorFactory;
 import javax.management.remote.JMXServiceURL;
 import javax.management.ObjectName;
 import weblogic.management.mbeanservers.runtime.RuntimeServiceMBean;
 import weblogic.management.runtime.ServerRuntimeMBean;
 import weblogic.management.jmx.MBeanServerInvocationHandler;
 import weblogic.management.configuration.ServerMBean;
 
 /**
  * WLDF アクセサを介してさまざまなアーカイブ データ ストアに問合せできる
  * ユーティリティを例示。このクラスは適切なアクセサをルック アップし、
  * 指定されたクエリ パラメータでクエリを実行する
  *
  * 使用方法についての情報を参照するには、このファイルをコンパイルして以下を実行
  *
  * java WLAccessor usage
  */
public class WLAccessor {
 
  /** WLAccessor の新しいインスタンスを作成する */
  public WLAccessor(Properties p) {
  initialize(p);
  }
 
  /**
  * クエリを行うために、指定された WLDFDataAccessRuntimeMBean インスタンスを取得する
  */
  public WLDFDataAccessRuntimeMBean getAccessor(String accessorType)
  throws Throwable
  {
  // 実行時 MBeanServerConnection を取得する
  MBeanServerConnection runtimeMBS = this.getRuntimeMBeanServerConnection();
 
  // 接続したサーバの実行時サービスをルックアップする
  ObjectName rtSvcObjName = new ObjectName(RuntimeServiceMBean.OBJECT_NAME);
  RuntimeServiceMBean rtService = null;
 
    rtService = (RuntimeServiceMBean)
      MBeanServerInvocationHandler.newProxyInstance(
        runtimeMBS, rtSvcObjName
        );

    // 必要なアクセサ インスタンスまで実行時ツリーを移動する
    ServerRuntimeMBean srt = rtService.getServerRuntime();

    WLDFDataAccessRuntimeMBean ddar =
      srt.getWLDFRuntime().getWLDFAccessRuntime().
      lookupWLDFDataAccessRuntime(accessorType);

    return ddar;
  }
 
 /**
   * 指定されたパラメータを使用してクエリを実行し、フォーマットされた
   * レコードを返す
   */
  public void queryEventData() throws Throwable
  {
    String logicalName = "EventsDataArchive";
    WLDFDataAccessRuntimeMBean accessor = getAccessor(accessorType);

    ColumnInfo[] colinfo = accessor.getColumns();
    inform("Query string: " + queryString);

    int recordsFound = 0;
    Iterator actualIt =
      accessor.retrieveDataRecords(beginTime, endTime, queryString);
    while (actualIt.hasNext()) {
      DataRecord rec = (DataRecord)actualIt.next();
      inform("Record[" + recordsFound + "]: {");
      Object[] values = rec.getValues();
      for (int colno=0; colno < values.length; colno++) {
        inform("[" + colno + "] "
               + colinfo[colno].getColumnName() +
               " (" + colinfo[colno].getColumnTypeName() + "): " +
                values[colno]);
      }
      inform("}");
      inform("");
      recordsFound++;
    }
    inform("Found " + recordsFound + " results");
  }

  /**
   * ツールを実装する main メソッド
   * @param args コマンドライン引数
   */
  public static void main(String[] args) {
    try {
      WLAccessor acsr = new WLAccessor(handleArgs(args));
      acsr.queryEventData();
    } catch (UsageException uex) {
      usage();
    } catch (Throwable t) {
      inform("Caught exception, " + t.getMessage(), t);
      inform("");
      usage();
    }
  }

  public static class UsageException extends Exception {}

  /**
   * 名前/値ペアとして指定されるコマンドライン引数を処理する
  */
  public static Properties handleArgs(String[] args) throws Exception
  {
    Properties p = checkForDefaults();
    for (int i = 0; i < args.length; i++) {
      if (args[i].equalsIgnoreCase("usage"))
        throw new UsageException();

      String[] nvpair = new String[2];
      int token = args[i].indexOf('=');
      if (token < 0)
        throw new Exception("Invalid argument, " + args[i]);
      nvpair[0] = args[i].substring(0,token);
      nvpair[1] = args[i].substring(token+1);
      p.put(nvpair[0], nvpair[1]);
    }
    return p;
  }
  
  /**
   * デフォルト プロパティ ファイルを検索する
   */
  public static Properties checkForDefaults() throws IOException {
    Properties defaults = new Properties();
    try {
      File defaultprops = new File("accessor-defaults.properties");
      FileInputStream defaultsIS = new FileInputStream(defaultprops);
      //inform("loading options from accessor-defaults.properties");
      defaults.load(defaultsIS);
      } catch (FileNotFoundException fnfex) {
      //inform("No accessor-defaults.properties found");
    }
    return defaults;
  }
  public static void inform(String s) {
    System.out.println(s);
  }
  public static void inform(String s, Throwable t) {
    System.out.println(s);
    t.printStackTrace();
  }

  private MBeanServerConnection getRuntimeMBeanServerConnection()
    throws IOException
  {
    // jmx サービス url を作成する
    
    // "service:jmx:[url]/jndi/[mbeanserver-jndi-name]"
    JMXServiceURL serviceURL =
      new JMXServiceURL(
        "service:jmx:" + getServerUrl() +
        "/jndi/" + RuntimeServiceMBean.MBEANSERVER_JNDI_NAME
        );

    // ユーザとパスワードを指定する。weblogic 提供のパッケージも指定する
    inform("user name [" + username + "]");
    inform("password [" + password + "]");
    Hashtable h = new Hashtable();
    h.put(Context.SECURITY_PRINCIPAL, username);
    h.put(Context.SECURITY_CREDENTIALS, password);
    h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
          "weblogic.management.remote");
    // jmx コネクタを取得する
    JMXConnector connector = JMXConnectorFactory.connect(serviceURL, h);

    inform("Using JMX Connector to connect to " + serviceURL);
    return connector.getMBeanServerConnection();
  }

  private void initialize(Properties p) {
    serverUrl = p.getProperty("url","t3://localhost:7001");
    username = p.getProperty("user","weblogic");
    password = p.getProperty("pass","weblogic");
    queryString = p.getProperty("query","SEVERITY IN
('Error','Warning','Critical','Emergency')");
    accessorType = p.getProperty("type","ServerLog");

    try {
      beginTime = Long.parseLong(p.getProperty("begin","0"));

      String end = p.getProperty("end");
      endTime = (end==null) ? Long.MAX_VALUE : Long.parseLong(end);
    } catch (NumberFormatException nfex) {
      throw new RuntimeException("Error formatting time bounds", nfex);
    }
  }

  private static void usage() {
    inform("");
    inform("");
    inform("Usage: ");
    inform("");
    inform(" java WLAccessor [options]");
    inform("");
    inform("where [options] can be any combination of the following: ");
    inform("");
    inform(" usage Prints this text and exits");
    inform(" url=<url> default: 't3://localhost:7001'");
    inform(" user=<username> default: 'weblogic'");
    inform(" pass=<password> default: 'weblogic'");
    inform(" begin=<begin-timestamp> default: 0");
    inform(" end=<end-timestamp> default: Long.MAX_VALUE");
    inform(" query=<query-string> default: \"SEVERITY IN ('Error','Warning','Critical','Emergency')\"");
    inform(" type=<accessor-type> default: 'ServerLog'");
    inform("");
    inform("Example:");
    inform("");
    inform(" java WLAccessor user=system pass=gumby1234 url=http://myhost:8000 \\");
    inform(" query=\"SEVERITY = 'Error'\" begin=1088011734496 type=ServerLog");
    inform("");
    inform("");
    inform("");
    inform("All properties (except \"usage\") can all be specified in a file ");
    inform("in the current working directory. The file must be named: ");
    inform("");
    inform(" \"accessor-defaults.properties\"");
    inform("");
    inform("Each property specified in the defaults file can still be ");
    inform("overridden on the command-line as shown above");
    inform("");
  }

  /** プロパティ serverUrl のゲッター
   * @return プロパティ serverUrl の値
   *
   */
  public java.lang.String getServerUrl() {
    return serverUrl;
  }
  
  /** プロパティ serverUrl のセッター
   * @param serverUrl プロパティ serverUrl の新しい値
   *
   */
  public void setServerUrl(java.lang.String serverUrl) {
    this.serverUrl = serverUrl;
  }
  
  protected String serverName = null;
  protected String username = null;
  protected String password = null;
  protected String queryString = "";
  private String serverUrl = "t3://localhost:7001";
  private String accessorType = null;

  private long endTime = Long.MAX_VALUE;
  private long beginTime = 0;

  private WLDFAccessRuntimeMBean dar = null;

}

 


システム クロックをリセットすることによるデータのアーカイブおよび取得に対する影響

診断データが WLDF アーカイブまたはログに書き込まれている間にシステム クロックをより前の時間にリセットすると、タイムスタンプに基づいてデータを問い合わせる際に、予期しない結果が生じる可能性があります。たとえば、イベントのシーケンスが次のような場合を考えます。

  1. 2:00 PM に、診断イベントが RECORD_200 としてアーカイブされる (200 はタイムスタンプが 2:00:00 PM という意味)。
  2. 2:30 PM に、診断イベントが RECORD_230 としてアーカイブされる (230 はタイムスタンプが 2:30:00 PM という意味)。
  3. 3:00 PM に、システム クロックを 2:00 PM にリセットする。
  4. 2:15 PM (システム クロックのリセット後) に、診断イベントが RECORD_215 としてアーカイブされる (215 はタイムスタンプが 2:15:00 PM という意味)。
  5. クエリを発行して 2:00 PM ~ 2:20 PM に生成されたレコードを取得する。

クエリでは RECORD_215 は取得されません。タイムスタンプが 2:30:00 PM である RECORD_230 によってクエリが終了するからです。


  ページの先頭       前  次