Apache HttpClientの通信内容をダンプ

アプリやミドルウェの動作の正常性確認や問題発生時の問題切り分けのために、HTTPリクエストやレスポンスのヘッダやボディを確認したい場合がある。Java系のアプリではApacheのHttpClientが使用されることが多いため、ここではApacheのHttpClientによる通信をダンプ(ロギング)する方法を説明します。
(ここではApache HttpClient 4.5を前提として説明します。HttpClientの場合、バージョンが変わるとAPI等が大きく変わる場合があるので、ここでの説明と異なる動作をする場合があります。)

HttpClientのロギング

ログ出力内容の種類

大きく分けて次の3種類のログを出力できます。
後述のログ出力例の設定例のように、使用するログ名を指定することで出力内容を変更できます。これらのログ名を全て含むorg.apache.httpを使うと全てのログを出力できます。

種類説明ログ名
Context Logging
(各クラスの内部動作)
HttpClientに含まれる各クラスの動作をログ出力します。ログを出力したいクラスの完全修飾クラス名を指定します。例えば、DefaultHttpClientのログを出力したい場合、org.apache.http.impl.client.DefaultHttpClientを指定します。HttpClientのクラスは慣例的にorg.apache.http.impl.clientというログ名を含んでいるので、このログ名を指定すれば全てのクラスのログを出力できます。org.apache.http.impl.client
Wire Logging
(通信内容全て)
HTTPリクエスト/HTTPレスポンスのヘッダとボディを出力します。1回の通信毎に大量のログが出力されるので、ログの肥大化や性能劣化に注意が必要です。org.apache.http.wire
HTTP header Logging
(HTTPヘッダのみ)
HTTPリクエスト/HTTPレスポンスのヘッダのみを出力します。org.apache.http.headers

ログ出力先

HttpClientはログ出力にCommons Loggingを使用しており、Log4jやjava.util.Loggingへの出力の他に、Commons Loggingに含まれるSimpleLogを使ってログを出力できます。
SimpleLogは簡単に使用できるので、以降ではこのSimpleLogを使用する前提で説明します。
Log4j, java.util.Loggingを使用する場合は、HttpClientのリファレンスを参照のこと。

設定方法

SimpleLogを使ってログ出力する場合、システムプロパティ(Java起動時の-Dオプション)としてパラメータを指定するか、クラスパス上に配置された”simplelog.properties”ファイルで指定します。使用できるプロパティは次の通りです。
詳細はjavadocを参照のこと。

プロパティ名(*1)説明既定値
defaultlog既定のログレベル(*2)
log.xxxxxで個別の指定がない限り、ここで指定したログレベル以上のログが出力されます。
info
log.xxxxxログ名xxxxxに対するログレベル(*2)
例えばlog.Xyz=traceと指定した場合、defaultLogの設定に関わらず、Xyzからのログはtrace以上を出力します。
(既定のログレベル)
showlognameログ名を出力するかを指定
下記showShortLognameの値によって出力形式が異なる。
false
showShortLognameログ名を出力する際、短縮表示するかを指定
trueの場合は”RequestAuthCache”、falseの場合は”org….protocol.RequestAuthCache”のように完全なログ名が出力される。
true
showdatetime日時を出力するかを指定
出力形式は下記dateTimeFormatで指定する。
false
dateTimeFormat日時出力時の書式を指定
(SimpleDateFormat書式)
yyyy/MM/dd HH:mm:ss:SSS zzz
*1: 先頭に”org.apache.commons.logging.simplelog.“を付ける前提です。
*2: ログレベルは”trace”, “debug”, “info”, “warn”, “error”, “fatal”のいずれか。

(参考)
eclipseでアプリケーションとして実行時にシステムプロパティとしてパラメータを指定する場合は、実行対象のクラスファイルを右クリックし、[実行]-[実行の構成]で実行構成ウインドウを表示します。[Javaアプリケーション]を選択して必須事項を入力し、[引数]タブでシステムプロパティを指定します。

出力例

  • HTTP POSTを行うサンプルプログラムを例題とし、ログ出力にはSimpleLogを使用する前提で、システムプロパティの設定例とログ出力例を記載します。
  • 下記の設定例では、本来は”2019/07/14 22:52:49:716 JST [DEBUG]…”等の日時項目が出力されますが、便宜上記載を割愛しています。
  • HTTPリクエスト(クライアント->サーバ)は”>>“、HTTPレスポンス(クライアント<-サーバ)は"<<“で表現されています。

出力例1:ヘッダ+コンテキスト

データ量が比較的多いボディ部を除外して全てのログを出力します。リファレンスにも記載がありますが、デバッグに最適なログ出力設定です。
  • プロパティ設定:
    -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog-Dorg.apache.commons.logging.simplelog.showdatetime=true-Dorg.apache.commons.logging.simplelog.log.org.apache.http=DEBUG-Dorg.apache.commons.logging.simplelog.log.org.apache.http.wire=ERROR
    補足: org.apache.http=DEBUGは「全て出力」、org.apache.http.wire=ERRORは「ボディ部は除外」
  • ログ出力例:

出力例2:通信内容(ヘッダのみ)

  • プロパティ設定:
    -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog-Dorg.apache.commons.logging.simplelog.showdatetime=true-Dorg.apache.commons.logging.simplelog.log.org.apache.http.headers=DEBUG
  • ログ出力例:

出力例3:通信内容(ヘッダ+ボディ)

ヘッダとボディ内容を確認したい場合の例です。
org.apache.http.headersと併せて使用するとヘッダが重複して出てしまいます。

  • プロパティ設定:
    -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog-Dorg.apache.commons.logging.simplelog.showdatetime=true-Dorg.apache.commons.logging.simplelog.log.org.apache.http.wire=DEBUG
  • ログ出力例:

参考:サンプルプログラム

HttpClientを使ってHTTP POSTするサンプルプログラムです。
使用するHttpClientはmavenで取得する前提であるため、pom.xmlで宣言します。
実行する場合はソースコード上のURLを適宜修正してください。