ヘッダーをスキップ
Oracle® Database JDBC開発者ガイド
12cリリース1 (12.1)
B71308-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

32 JDBCの診断機能

Oracle Database 12cリリース1 (12.1)の診断機能を使用すると、Oracle JDBCドライバを使用するアプリケーションの問題や、ドライバ自体の問題を診断できます。また、Oracle JDBCドライバを使用してOracle DatabaseインスタンスにアクセスするJavaアプリケーションを開発、保守するために必要な労力を低減できます。

Oracle JDBCドライバには、ユーザーがJDBCアプリケーションの問題を識別および修正することを可能にする次の診断機能が用意されています。


注意:

JDBCドライバの診断機能は、標準のjava.util.loggingフレームワークおよびjavax.management MBeanフレームワークに基づいています。これらの標準フレームワークについての情報はこの文書では扱いません。これらの標準フレームワークの詳細は、次を参照してください。
http://www.oracle.com/technetwork/java/index.html

ロギング

JDBCドライバのコードが実行されるときに発生するイベントの情報を記録します。イベントには、SQL例外などユーザーの目に触れるイベントも、内部JDBCメソッドの出入りなどの詳細JDBC内部イベントも含めることができます。ユーザーがこの機能を有効にすると、特定のイベントまたはすべてのイベントを記録することができます。

Oracle Database 11gより前は、JDBCドライバは、J2SE 2.0と3.0をサポートしていました。J2SEのこれらのバージョンには、java.util.loggingが含まれませんでした。このため、Oracle Database 11gより前のJDBCドライバ・リリースによって提供されるロギング機能は、java.util.loggingフレームワークと異なります。

Oracle Database 11g以降、JDBCドライバではJ2SE 2.0と3.0はもうサポートされません。このため、JDBCドライバのロギング機能は、標準java.util.loggingパッケージをフル活用します。強化されたロギング・システムではログ・レベルが有効利用され、ユーザーはログ出力を関心のものに制限できます。特定のクラスの情報がより一貫して記録されるため、ログ・ファイルがわかりやすくなりました。

この機能では新しいAPIや構成ファイルは導入されません。既存の標準java.util.logging構成ファイルに新しいパラメータが追加されたのみです。これらのパラメータはjava.util.loggingの使用に不可欠なもので、既存のパラメータと同様に使用されます。


注意:

生成されたログの内容の正確性は保証されません。ログの内容は大部分、実装の詳細に依存します。実装の細部はリリースのたびに変更されるため、ログの正確な内容もリリースごとに変更される傾向があります。

JDBCロギングの有効化と使用

Javaアプリケーションのデバッグを開始する前に、JDBCロギングを有効にして、構成する必要があります。この項では、JDBCロギングを有効にして使用するために実行する必要がある手順を説明します。内容は次のとおりです。

CLASSPATHの構成

JDBCドライバのそれぞれのバージョンに対応するいくつかのJARファイルが付属しています。最適化されたJARファイルにはロギング・コードが含まれていないため、使用時にログ出力が生成されません。ログ出力を取得するには、デバッグJARファイル(ojdbc6_g.jarojdbc7_g.jarのようにファイル名に_gが付いています)を使用する必要があります。デバッグJARファイルはCLASSPATHに含まれている必要があります。


注意:

デバッグJARファイル、たとえばojdbc6_g.jarojdbc7_g.jarCLASSPATH内の唯一のOracle JDBC JARファイルであることを確認してください。

ロギングの有効化

ロギングを有効化する方法には次のようなものがあります。

  • Javaシステム・プロパティの設定

    oracle.jdbc.Traceシステム・プロパティを設定することによってロギングを有効にできます。

    java -Doracle.jdbc.Trace=true ...
    

    システム・プロパティの設定によりグローバル・ロギングを有効にできます。ロギングがアプリケーション全体に対して有効になります。アプリケーション全体をデバッグする場合、またはアプリケーションのソース・コードを変更しないか変更できない場合は、グローバル・ロギングを使用できます。

  • プログラムによる有効化

    ロギングをプログラム的に有効または無効にするには、次のようにします。

    最初に、Diagnosability MBeanのObjectNameを取得します。ObjectNameは次のようになります。

    com.oracle.jdbc:type=diagnosability,name=<loader>
    

    loaderは、Oracle JDBCドライバをロードしたクラス・ローダー・インスタンスに基づいた一意の名前です。


    注意:

    ドライバは、1つの仮想マシンに複数回ロードできます。したがって、それぞれ一意の名前を持つ複数のMBeanが存在することになります。

    次のとおりにコードを作成します。

    ClassLoader l = oracle.jdbc.OracleDriver.getClassLoader();
    String loader = l.getName() + "@" + l.hashCode();
    // compute the ObjectName
    javax.management.ObjectName name = new javax.management.ObjectName("com.oracle.jdbc:type=diagnosability,
    name="+loader);
    
    // 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(name, "LoggingEnabled"));
    
    // enable logging
    mbs.setAttribute(name, new javax.management.Attribute("LoggingEnabled", true));
    
    // disable logging
    mbs.setAttribute(name, new javax.management.Attribute("LoggingEnabled", false));
    

    注意:

    • 同じクラス・ローダーでJDBCドライバが複数回数をロードすると、一意の名前を作成するために、MBeanが追加されるたびにl.hashCode()メソッドの値が増加します。どのMBeanがどのJDBCドライバ・インスタンスに関連付けられているかを識別することが難しくなる可能性があります。

    • ロードされているJDBCドライバのインスタンスが1つしかない場合は、名前を*に設定します。


プログラムでロギングを有効および無効にすると、ログ出力の生成に必要なアプリケーションの部分を変更しやすくなります。


注意:

上のいずれかの方法を使用してロギングを有効にしても、重大なエラーの最小限のログが生成されるだけです。通常、それではあまり役に立ちません。より有用で詳細なログを生成するには、java.util.loggingを構成する必要があります。

ロギングの構成

有用で詳細なログを生成するには、java.util.loggingを構成する必要があります。これには、構成ファイルを使用する方法と、プログラム的に行う方法があります。

JDBCをインストールすると、サンプル構成ファイル、OracleLog.propertiesdemoディレクトリに配置されます。そこにはjava.util.loggingの構成方法に関する基本情報や、最初に使用できるいくつかの初期設定が含まれています。このサンプル・ファイルをそのまま使用することも、ファイルを編集して使用することも、ファイルの名前を変更して使用することも、任意の名前を持つ完全に新しいファイルを作成することも可能です。

構成ファイルを使用するには、Javaランタイムにそれを認識させる必要があります。それには、システム・プロパティを設定します。たとえば、次のようになります。

java -Djava.util.logging.config.file=/jdbc/demo/OracleLog.properties.

ファイルはjava.util.loggingシステムによって読み取られます。このファイルはどこに配置してもかまいません。

java.util.logging.config.fileoracle.jdbc.Traceは同時に使用できます。

java -Djava.util.logging.config.file=/jdbc/demo/OracleLog.properties -Doracle.jdbc.Trace=true

デフォルトのOracleLog.propertiesファイルを使用できます。希望する出力が得られる場合も、得られない場合もあります。独自の構成ファイルを作成して使用することもできます。次の手順に従ってください。

  1. myConfig.propertiesという名前のファイルを作成します。どのような名前を使用してもかまいません。

  2. そのファイルに次の行のテキストを挿入します。

    .level=SEVERE
    oracle.jdbc.level=INFO
    oracle.jdbc.handlers=java.util.logging.ConsoleHandler
    java.util.logging.ConsoleHandler.level=INFO
    java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
    
  3. ファイルを保存します。

  4. この構成ファイルを使用するようにシステム・プロパティを設定します。

    java -Djava.util.logging.config.file=<filepath>/myConfig.properties ...
    

    filepathは、myConfig.propertiesファイルを保存したフォルダのパスです。

また、java.util.loggingを構成して、ログ出力をファイルにダンプすることができます。そうする場合は、構成ファイルを次のように変更します。

.level=SEVERE
oracle.jdbc.level=INFO
oracle.jdbc.handlers=java.util.logging.FileHandler
java.util.logging.FileHandler.level=INFO
java.util.logging.FileHandler.pattern=jdbc.log
java.util.logging.FileHandler.count=1
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter

これにより、正確に同じログ出力が生成され、現在のディレクトリにjdbc.logという名前のファイルで保存されます。

レベル設定を変更することで、詳細度を制御することができます。定義されているレベルは、最も詳細度の低いものから最も高いものまで、次のようになります。

  • OFF

    ロギングをオフにします。

  • SEVERE

    SQLExceptionと内部エラーを記録します。

  • WARNING

    SQLWarningと、好ましくないが致命的ではない内部の状況を記録します。

  • INFO

    まれではあるが重要なイベントおよびエラーを記録します。生成されるログ・メッセージは比較的小量です。

  • CONFIG

    実行されるSQL文字列を記録します。

  • FINE

    すべてのパブリック・メソッドへの出入りが記録されるため、JDBC操作を詳細にトレースできます。生成されるログ・メッセージはかなり大量です。

  • FINER

    内部メソッドのコールを記録します。

  • FINEST

    大量の内部メソッドのコールを記録します。

  • ALL

    詳細をすべて記録します。ロギング詳細度が最も高いレベルです。


注意:

詳細度がFINEを超えるレベルでは、非常に大量のログが生成されます。

上で示された例で詳細の出力量を削減するには、java.util.logging.FileHandler.level設定をALLからINFOに変更します。

java.util.logging.FileHandler.level=INFO

oracle.jdbcログ出力のレベルを変更することは可能ですが、必要ありません。FileHandlerレベルを設定することで、ログ・ファイルにダンプされるログ・メッセージを制御できます。

ログ出力の使用

レベルを設定すると、JDBCからのすべてのロギング出力が減少します。しかし、コードのある部分からの出力は大量に必要ですが、他の部分からはほとんど必要ない場合があります。そうするには、ログ出力に関する深い理解が必要です。

ログ出力は、名前で定義されたツリー構造をなしています。ルート・ログ出力の名前は「」(空の文字列)です。構成ファイルの最初の行には、.level=SEVEREと記述されています。これは、ルート・ログ出力のレベル設定です。次の行はoracle.jdbc.level=INFOです。これは、oracle.jdbcという名前のログ出力のレベルを設定しています。oracle.jdbcログ出力は、ログ出力ツリーのメンバーです。その親はoracleという名前です。oracleログ出力の親がルート・ログ出力(空の文字列)です。

ロギング・メッセージは、特定のログ出力(たとえば、oracle.jdbc)に送信されます。メッセージがそのレベルのレベル・チェックに合格すると、メッセージは、そのレベルのハンドラ(存在する場合)と親ログ出力に渡されます。このため、ずっと見ていくと、oracle.logに送信されるログ・メッセージはそのログ出力のレベル、INFOに対して比較されます。レベルが同じか低い(詳細度が低い)場合、FileHandlerと親ログ出力(oracle)に送信されます。この場合も、レベルに対して確認されます。この例のような場合は、レベルが設定されていないため、親レベル(SEVERE)が使用されます。メッセージ・レベルが同じか低い場合は、ハンドラに渡され(存在しません)、親に送信されます。この場合は、ルート・ログ出力の親です。このようなツリー構造は、出力の量を減らす役には立ちませんでした。役に立つのは、JDBCドライバがいくつかのサブ・ログ出力を使用するということです。ログ・メッセージをいずれかのサブ・ログ出力に制限すると、出力が大幅に少なくなります。Oracle JDBCドライバによって使用されるログ出力は、次のとおりです。

  • oracle.jdbc

  • oracle.jdbc.pool

  • oracle.jdbc.rowset

  • oracle.jdbc.xa

  • oracle.sql


注意:

ドライバが使用するログ出力は、リリースによって異なることがあります。

oracle.sqlコンポーネントで発生していることを追跡し、残りのドライバに関する基本情報の一部を取得する場合を考えます。これは、ロギングのより複雑な使用方法です。configファイルのエントリを次に示します。

     # 
     # set levels 
     # 
.level=SEVERE
oracle.level=INFO
oracle.jdbc.driver.level=INFO
oracle.jdbc.pool.level=OFF
oracle.jdbc.util.level=OFF
oracle.sql.level=INFO
     # 
     # configure handlers
     # 
oracle.handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

構成ファイルのそれぞれの行で行われている処理を検討します。

.level=SEVERE

ルート・ログ出力のロギング・レベルをSEVEREに設定します。深刻な障害の場合を除き、他の、Oracleのものでないコンポーネントからのロギングを確認する必要はありません。このため、すべてのログ出力のデフォルト・レベルをSEVEREに設定します。明示的に設定された場合を除いて、各ログ出力はレベルを親から継承します。ルート・ログ出力のレベルをSEVEREに設定すると、あらためて設定したログ出力を除いて、他のすべてのログ出力が確実にそのレベルを継承するようにできます。

oracle.level=INFO

oracle.sqloracle.jdbc.driverログ出力の両方からログを出力します。共通の祖先はoracleです。このため、oracleログ出力のレベルをINFOに設定します。より低いレベルでは詳細度をより明示的に制御します。

oracle.jdbc.driver.level=INFO

ここでは、oracle.jdbc.driverからのSQL実行の表示のみが必要です。このため、レベルをINFOに設定します。これはかなり小量のレベルですが、このテストの処理内容を追跡するためには役立ちます。

oracle.jdbc.pool.level=OFF

このテストではDataSourceを使用しており、そのロギングすべてを表示する必要はありません。したがって、OFFにします。

oracle.jdbc.util.level=OFF

oracle.jdbc.utilパッケージからのロギングを表示する必要はありません。XAまたはRowsetを使用していた場合、それもオフにします。

oracle.sql.level=INFO

oracle.sqlで発生していることを表示します。このため、レベルをINFOに設定します。これにより、大量の詳細が出力されるのを回避しながら、パブリック・メソッドのコールについて多くの情報が得られます。

oracle.handlers=java.util.logging.ConsoleHandler

stderrに全内容をダンプします。テストを実行する場合、stderrをファイルにリダイレクトします。

java.util.logging.ConsoleHandler.level=INFO

System.errであるコンソールに全内容をダンプします。この場合、ハンドラでなくログ出力でフィルタリングしています。

java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

簡単でほぼ判読可能な形式を使用します。

この構成ファイルでテストを実行すると、oracle.sqlパッケージからは適度に詳細な情報を取得し、コア・ドライバ・コードからは少量の情報を取得します。他のコードからは何も取得しません。

XMLFormatterを使用して、Oracleサポートにログを送信することもできます。

カスタムjava.util.logging.Filterを実装および使用して、ログに書き込まれたデータをより詳細に制御できます。これは標準java.util.logging機能で、JSEのJavaDocに記述されています。カスタム・フィルタを使用すると、次のことが可能になります。

  • マルチスレッド・アプリケーションのスレッドの取得(1つのみ)

  • 長時間実行中のアプリケーションの断続的なエラーの取得

パフォーマンス、スケーラビリティおよびセキュリティに関する問題点

ロギング機能を使用すると、アプリケーションの追跡やデバッグ、および詳細ログ出力の生成が可能になりますが、パフォーマンス、スケーラビリティおよびセキュリティに関する問題が多少あります。

パフォーマンスとスケーラビリティの問題

ロギングは、パフォーマンスにかなり影響します。ただし、JDBCロギングは一般に本番システムでは有効ではありません。ロギングが無効の場合、パフォーマンスへの影響はありません。

スケーラビリティにも悪影響があります。ロギングには、多くの共有リソースへの保護アクセスが伴うため、結果として、スケーラビリティが大幅に低下します。これはjava.util.loggingフレームワークの問題です。ただし、通常の本番システムではJDBCロギングが有効ではないため、スケーラビリティへの影響はありません。

セキュリティ上の問題

フル・ロギングが有効な場合、すべての機密情報がほぼ確実にログ・ファイルに公開されてしまいます。これはロギング機能の内在的問題です。ただし、特定のJDBC JARファイルにのみ、JDBCロギング機能が含まれます。次のJARファイルにはフル・ロギングが含まれるため、機密を扱う環境での使用はお薦めしません。

  • ojdbc6_g.jar

  • ojdbc6dms_g.jar

  • ojdbc7_g.jar

  • ojdbc7dms_g.jar

次のJARファイルには、限定されたロギング機能が含まれます。

  • ojdbc6dms.jar

  • ojdbc7dms.jar


注意:

データベースのユーザー名とパスワードは、これらのJARファイルによって作成されたログ・ファイルには表示されません。ただし、SQL文、定義された値またはバインド値の一部である機密ユーザー・データは、これらのJARファイルのいずれかを使用して作成されたログに表示されます。

診断能力管理

JDBC診断能力管理機能には、MBean、oracle.jdbc.driver.OracleDiagnosabilityMBeanが導入されています。このMBeanを使用して、JDBCロギングの有効化および無効化が可能です。


関連項目:

OracleDiagnosabilityMBean APIの詳細は、JDBC Javadocを参照してください。

将来のリリースでは、このMBeanはJDBC内部関数に関する他の統計情報を提供するように拡張されます。

セキュリティ上の問題

この機能により、JDBCロギングを有効にできます。JDBCロギングを有効にするには、特別な権限は必要ありません。ただし、ロギングが有効になると、ログ出力を生成するために標準のJava権限LoggingPermissionが必要になります。この権限がない場合、ログを生成するすべてのJDBC処理でセキュリティ例外がスローされます。これは標準のJavaメカニズムです。