40 JDBCの診断機能

このリリースでは、JDBCの診断機能が、よりわかりやすくなるように拡張されています。

オンプレミス・ユーザーと異なりクラウド・ユーザーにはシステムへの絶対的なアクセス権がないため、この拡張により、Oracle Cloud Infrastructure (OCI)環境でのJDBCドライバの使用も容易になります。拡張された診断機能により、クラウド環境でアクセス可能で構成可能な診断機能が提供されます。

40.1 JDBC診断機能の概要

JDBC診断機能はクライアント専用の機能です。以前のリリースと同様に、Javaユーティリティ・ロギング・フレームワークを使用します。サーバー側のThinドライバやサーバー側の内部ドライバでは動作しません。

以前のリリースでは、デバッグJARファイルはロギング目的で使用されます。これらのファイルは、ojdbc8_g.jarojdbc11_g.jarなどのファイル名で_gで示され、CLASSPATHに含まれている必要があります。Database 23aiリリースで拡張された診断機能により、デバッグJARファイルを使用する必要がなくなり、通常のJARファイルとデバッグJARファイルを切り替える必要もなくなりました。現在、通常のJARファイルにはロギング機能が含まれており、次のプロパティで有効にできます。

oracle.jdbc.diagnostic.enableLogging=true

このプロパティは、Javaシステム・プロパティ(-Dオプションを使用)またはDataSourceプロパティを介して設定できます。

ロギング構成ファイルは次の方法で構成できます。

-Djava.util.logging.config.file=./logging.config

たとえば、次のロギング構成ファイルでは、OracleSimpleFormatterを使用してコンソールでJDBCロギングをオンに切り替えます:

handlers = java.util.logging.ConsoleHandler
oracle.jdbc.level = ALL
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = oracle.jdbc.diagnostics.OracleSimpleFormatter

ロギングは、com.oracle.jdbc.diagnosability JDBC MBeanを介して動的に有効にできます。このMBeanには、enableLoggingdisableLoggingenableLoggingByConnectionIdPrefixなどの複数の操作を定義します。これらの操作はすべて、関連する操作を呼び出すことによってプログラムでコールすることもできます。たとえば:

void enableLogging(boolean enable) {
  try {
    Object loader = oracle.jdbc.driver.OracleDriver.class.getClassLoader();
    String loaderName =
            (loader == null ? "nullLoader" : loader.getClass().getName());
    String name = loaderName + "@" +
                      Integer.toHexString(
                              (loader == null ? 0 : loader.hashCode())
                      // If the same class loader loads the JDBC drivers multiple times, then each
                      // subsequent MBean increments the value of the loader.hashCode() method, so as to
                      // create a unique name. It may be problematic to identify which MBean is
                      // associated with which JDBC driver instance.
                      );
    javax.management.ObjectName diagnosticMBeanObjectName = new javax.management.ObjectName("com.oracle.jdbc:type=diagnosability,name=" + name);

    // get the MBean server
    javax.management.MBeanServer mbs = java.lang.management.ManagementFactory.getPlatformMBeanServer();

    // find out if logging is enabled or not
    System.out.println("LoggingEnabled = " + mbs.getAttribute(diagnosticMBeanObjectName, "LoggingEnabled"));

    // enable logging
    if(enable)
      mbs.invoke(diagnosticMBeanObjectName, "enableLogging", null, null);
    else
      mbs.invoke(diagnosticMBeanObjectName, "disableLogging", null, null);
  } catch (Exception e) {
    e.printStackTrace();
  }
}

JDBC診断機能

改善されたJDBC診断機能は、Oracle Databaseの次の機能に基づいて構築されます。

  • 可観測性: Java開発者は、JDBCの実行およびパフォーマンスに関するサマリー情報にアクセスできます。
  • 診断可能性: 障害が発生した場合にクリティカルな実行状態を記録します。このような状態は、最初に発生した障害を診断し、障害の原因となる問題を解決するのに十分です。記録された状態情報の量と、その状態を記録したコストのバランスを取る必要があります。
  • 実行トレース: 実行順序の詳細を記録します。実行トレースにはかなりのコストがかかるため、限定されたコンテキストでのみ有効にする必要があります。

各診断機能には、パブリックと機密の2つのモードがあります。パブリック・モードでは、これらの機能は機密情報の記録や永続化を実行しません。これにより、取得される情報の量が大幅に制限され、診断機能の有効性が低下します。機密モードでは、これらの機能は機密情報を記録し、永続化します。機密モードを許可するには、特権ユーザーである必要があります。

機密モードは2つのスイッチによって制御され、1つは有効化用、もう1つは許可用です。各診断機能に対する機密モードは、適切なJavaコマンドライン・スイッチを設定することで許可されます。JavaコマンドラインでJavaシステム・プロパティとしてpermitスイッチが設定されていない場合は、機密モードを有効にできません。機密モードを許可したら、次の例に示すように有効にする必要があります。

-Doracle.jdbc.diagnostic.permitSensitiveDiagnostics=true
-Doracle.jdbc.diagnostic.enableSensitiveDiagnostics=true

ノート:

  • 機密モードを許可しても、自動的に有効になりません。機密モードを有効にしようとすると、許可されていない場合、リカバリ不能なエラーが発生します。
  • ロギングの有効化と同様に、機密モードの有効化もMBeanを介して動的に実行できます。
  • 機密モードが有効な場合、SQLテキストはログに表示されますが、パラメータ・データは表示されません。

次のコード・スニペットは、ロギング構成ファイルを構成する方法を示しています。

例40-1 ロギング・ファイルの構成

handlers = java.util.logging.ConsoleHandler
oracle.jdbc.level = FINEST
java.util.logging.ConsoleHandler.level = FINEST
java.util.logging.ConsoleHandler.formatter = oracle.jdbc.diagnostics.OracleSimpleFormatter

例40-2 ロギング・ファイルの構成(詳細)

handlers=java.util.logging.FileHandler
java.util.logging.FileHandler.level = FINEST
java.util.logging.FileHandler.formatter = oracle.jdbc.diagnostics.OracleSimpleFormatter
java.util.logging.FileHandler.pattern = client.log
java.util.logging.FileHandler.limit = 1000000000
java.util.logging.FileHandler.count = 1000
oracle.ucp.level=FINEST
oracle.jdbc.level=FINEST

40.2 初期障害の診断機能

拡張された主な診断機能の1つは、初期障害の診断機能です。

この機能を有効にすると、最初に発生した障害が診断され、最もクリティカルなトレース情報がメモリーに取得されます。そのメモリーが一杯になると、最も古いトレース・レコードは上書きされ、その後、通知されたときにjava.util.loggingにダンプされます。次のいずれかによって、トレース・レコードのダンプが通知される場合があります。

  • 接続でのエラーの発生
  • クライアント・アプリケーション・コードによるAPIのコール
  • MBean

この機能では、最もクリティカルな情報、つまり、最も可能性の高い問題を十分診断できる見込みがあるほどの情報のみを取得します。パブリック・モードでは、この情報は厳しく制限されているため、機密情報はすべて省略されます。機密モードでは、この情報にはネットワークの対話全体が含まれます。

この機能は、デフォルトでは有効化されています。CONNECTION_PROPERTY_ENABLE_DIAGNOSE_FIRST_FAILUREプロパティをFALSEに設定するか、DiagnosticMBeansインタフェースを使用して無効にできます。