こんにちは、Japan Developer Support Core チームの近澤です。
今回は、Java アプリケーションで Microsoft JDBC Driver for SQL Server を使用する際のトレース取得方法についてご案内します。接続のトラブルシューティングを行う際には、JDBC ドライバーのトレースが非常に有用な情報となります。また、SSL/TLS 関連のエラーが発生した場合には、より深いレベルでのデバッグが必要となる場合もあります。
JDBC Driver のトレース取得方法
SQL Server JDBC Driver は Java 標準機能の Logger に対応しています。プログラムの実装を変更することなく Logger を使ってトレースを取得することができます。
詳細については、以下の公式ドキュメントもご参照ください。
手順 1: 構成ファイルの準備
まず、logging.properties という構成ファイルを準備します。以下は設定例です。
1 | ############################## |
手順 2: トレース採取の有効化
アプリケーション実行時のコマンド ラインで、以下のようにトレース採取を有効化します。
1 | java -Djava.util.logging.config.file=C:\work\logging.properties app01 |
このコマンドの各部分の説明:
-Djava.util.logging.config.file=C:\work\logging.properties: Logger の構成ファイルを指定app01: 実行する Java アプリケーション
ログレベルについて
JDBC Driver のログは、Java Util Logging (JUL) に従いますが、ほとんどが下記のレベルに分類されます。
- FINEST - 最も詳細なデバッグ情報(すべてのトレース)
- FINER - より詳細なデバッグ情報
- FINE - デバッグ情報(概要レベル)
ログレベルの詳細については、ドライバー操作のトレース(ログ) - ログ記録のレベルをご参照ください。
トラブルシューティングに必要なレベル
下記のような接続エラーメッセージを記録したい場合は、少なくとも FINE レベルに設定する必要があります。
FINE: *** SQLException:ConnectionID:1 ClientConnectionId: d5adaa76-d1e6-4ecf-9e18-c9f751efdb7b com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption.
FINE: *** SQLException: com.microsoft.sqlserver.jdbc.SQLServerException: Failed to authenticate the user username@yourdomain.com in Active Directory (Authentication=ActiveDirectoryIntegrated).
FINE: *** SQLException: com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'username'. Reason: Azure Active Directory only authentication is enabled. Please contact your system administrator.
SSL/TLS デバッグの有効化
JDBC ドライバーから呼び出される Java の下位レイヤーで SSL/TLS のエラーが発生する場合、ドライバーのトレースだけでは調査に十分ではないケースがあります。このような場合には、javax.net.debug オプションを使用します。
詳細については、Java Secure Socket Extension (JSSE) Reference Guide をご参照ください。
方法 1: コマンドライン オプションでの指定
1 | java -Djava.util.logging.config.file=logging.properties -Djavax.net.debug=all app01 |
デフォルトでは標準出力に出力されます。ファイルに出力したい場合は、リダイレクトを使用します。
1 | java -Djava.util.logging.config.file=logging.properties -Djavax.net.debug=all app01 > SSLlog.log 2>&1 |
このコマンドの各部分の説明:
-Djava.util.logging.config.file=logging.properties: JDBC ドライバーのトレースを有効化(前の章の設定)-Djavax.net.debug=all: SSL/TLS の詳細なデバッグ情報を有効化app01: 実行する Java アプリケーション> SSLlog.log: 標準出力を SSLlog.log ファイルにリダイレクト2>&1: 標準エラー出力も標準出力と同じファイルにリダイレクト(これにより、すべての出力が SSLlog.log に記録されます)
方法 2: 環境変数での指定
java.exe を直接実行していない場合(アプリケーションサーバー経由での実行など)は、環境変数 JDK_JAVA_OPTIONS に追加指定できます。
1 | set JDK_JAVA_OPTIONS=%JDK_JAVA_OPTIONS% -Djavax.net.debug=all |
この設定により、実行時に -D のオプション指定をせずともデバッグログが標準出力に表示されるようになります。
出力例
以下のような詳細なデバッグログが出力されます。
javax.net.ssl|DEBUG|10|main|2023-08-18 17:53:50.966 JST|SSLSocketInputRecord.java:247|READ: TLSv1.2 application_data, length = 249
javax.net.ssl|DEBUG|10|main|2023-08-18 17:53:50.967 JST|SSLCipher.java:1675|Plaintext after DECRYPTION (
0000: 04 01 00 E1 00 49 01 00 81 02 00 00 00 00 00 00 .....I..........
0010: 00 08 00 38 02 49 00 64 00 00 00 00 00 08 00 E7 ...8.I.d........
0020: 64 00 09 04 D0 00 34 04 4E 00 61 00 6D 00 65 00 d.....4.N.a.m.e.
...
)
なお、基本的に、本番環境では -Djavax.net.debug は使用すべきではありません。 すべての SSL/TLS 通信で詳細なログが生成され、I/O オーバーヘッドが発生し、パフォーマンスに影響する可能性があります。 トラブルシューティング時の一時的な使用に限定してください。
プログラムから有効にする方法
前述の「JDBC Driver のトレース取得方法」と「SSL/TLS デバッグの有効化」では、コマンドラインオプションや環境変数を使用してトレースを有効化する方法を説明しました。ここでは、これらの設定をプログラムコード内から動的に有効化する方法をご紹介します。詳細については、ドライバー操作のトレース(ログ) - プログラムによるトレースの有効化もご参照ください。
この方法は、以下のようなケースで有用です:
- アプリケーションの起動パラメータを変更できない環境
- 特定の条件下でのみトレースを有効化したい場合
以下に示す LoggerManager クラスは、JDBC ドライバーのトレースと SSL/TLS デバッグの両方をプログラムから設定できるユーティリティクラスのサンプルです。
LoggerManager クラス
このクラスは、Java Util Logging の設定と SSL/TLS デバッグ出力のリダイレクトを管理します。
1 | package org.example; |
使用例
アプリケーションの Main クラスで、以下のように LoggerManager を使用してトレースを有効化します。
1 | // JDBC ドライバーのトレースを FINEST レベルで有効化 |
注意点
initializeSslDebugLogging()を呼び出すと、標準出力と標準エラー出力がファイルにリダイレクトされ、コンソールには出力されなくなります。- アプリケーションの起動時、データベース接続処理の前に呼び出すことをお勧めします。
サードパーティー製品での設定について
Java アプリケーションは WebLogic、WebSphere、Tomcat などのサードパーティー製品を介して実行されているケースが多くあります。その場合には、それぞれの製品上に Logger を有効化するための設定があります。各製品のドキュメントを参照して設定を行ってください。
まとめ
本記事では、Microsoft JDBC Driver for SQL Server のトレース取得方法について説明しました。
JDBC ドライバーのトレース取得
- logging.properties ファイルを作成し、
-Djava.util.logging.config.fileオプションで指定 - 接続エラーの調査には、少なくとも FINE レベルの設定が必要
SSL/TLS デバッグ
- より深いレベルの調査には
-Djavax.net.debugオプションを使用 - 環境変数
JDK_JAVA_OPTIONSでの指定も可能
プログラムからの設定
- LoggerManager クラスを使用することで、コマンドラインオプションを変更せずにプログラム内からトレースを有効化可能
- アプリケーションの起動パラメータを変更できない環境や、特定の条件下でのみトレースを有効化したい場合に有用
注意点
- WebLogic、WebSphere、Tomcat などのアプリケーションサーバーを使用している場合は、各製品固有の Logger 設定方法を確認してください
- トラブルシューティング時は適切なログレベルを設定し、問題解決後は必要に応じてログレベルを下げることをお勧めします
今回はここまでとなります。JDBC ドライバーのトラブルシューティングの際にぜひご活用ください。
本ブログの内容は弊社の公式見解として保証されるものではなく、開発・運用時の参考情報としてご活用いただくことを目的としています。もし公式な見解が必要な場合は、弊社ドキュメント (https://learn.microsoft.com や https://support.microsoft.com) をご参照いただくか、もしくは私共サポートまでお問い合わせください。