web-dev-qa-db-ja.com

Javaアプリケーションのすべてのネットワーク相互作用をログに記録します

私は巨大なJavaアプリ(あまり知られていないアプリケーションサーバーGNUEnterpriseのクライアント)とそのソースを持っています。これらに変更を加えた後、コンパイルできます。アプリはネットワークを多用しているので、 Wiresharkなどのスニファを使用することもできますが、アプリケーションはSSLを介してサーバーで動作するため、SSL証明書の秘密キーを知らないため、スニファされたトラフィックはほとんど役に立ちません。

すべての要求と応答をアプリケーション自体からログに記録するにはどうすればよいですか?送受信されたすべてのヘッダーを確認する必要があります。ネットワークの相互作用に関与するすべてのコードを変更したくありません。私が欲しいのは次のようなコードを置くことです

_Network.setDefaultLogger(myCustomLoggerInstance);
_

アプリの開始近くのどこか、次にmyCustomLoggerInstanceで、必要なすべてのロギングを実行します。

また、すべてのネットワーク操作がURLConnectionsで行われている場合、con.getHeaderFields()で応答ヘッダーを取得し、con.getRequestProperties()で要求ヘッダーを取得できます。しかし、なぜCookieがないのですか?送信および受信したCookieを同じ方法でダンプする方法は?

[〜#〜] edit [〜#〜]:私が到達しようとしているのは、RPCアプリケーションとそのサーバーとのSSL経由の通信を模倣することです。たとえば、curlを使用します。このため、アプリのネットワークトラフィックの詳細なログを取得する必要があります。

21
Hnatt

ロギングプロキシサーバーを使用できませんか。 http://www.charlesproxy.com/ または http://fiddler2.com/ ? Charles ProxyはAMFリクエストもデコードできます。FiddlerはSSLインターセプトのチャンピオンです。

IIRCでは、システムプロパティhttp.proxyHostおよびhttp.proxyPortを127.0.0.1および8888に設定できます。Java URLConnectionsは、ロギングプロキシサーバーを介して自動的に接続し、HTTPの適切なビューを取得しますトラフィック。

または、通信を再生できるようにする場合は、JMeter HTTPプロキシを使用します。これは、再生に適した形式で記録されます。また、Cookie処理のサポートが組み込まれています。

アプリケーションがNice Webサービスを使用する場合、SoapUIには、WSDLをインポートしたWebサービス呼び出しをインターセプトする監視プロキシもあります。

17
GreyFairer

すべてのSSLトラフィックをログに記録する簡単な方法は、次のように起動することですJava with:

-Djavax.net.debug=all

または、システムプロパティとして設定します。

System.setProperty("javax.net.debug","all");

あなた自身を支えます。これを行うと、標準出力でノイズが発生します。

(*注:SSLトラフィックとSSLデバッグ情報(ハンドシェイクなど)のみがログに記録されます。通常のソケットはログに記録されません。)

22
Julius Musseau

さらに少し掘り下げたところ、どうやらHttpURLConnectionにはデフォルトでJava.util.loggingが有効になっています。

関連する質問を参照してください: Java:送信前にHttpURLConnectionのリクエストを表示 および Java HttpURLConnectionトラフィックのワイヤーロギングを有効にする方法

Java.util.loggingは、Java 1.4でログプロバイダーを標準化しようとしたSunの(失敗した)試みでした。システムプロパティの微調整を避けたい場合は、jul-to-slf4jモジュールを介してSLF4Jにブリッジできます。 。

しかし、私はまだFiddlerまたはJMeterプロキシを好みます:-)

3
GreyFairer

最初から使用できるコードのスニペットを投稿したいだけです。私には「グローバル」ロガーはありませんが、既存のコードを少し変更するだけで、目標を達成できます。問題は2つの部分に分けられるため、標準出力に「ログ」を記録します。UrlConnectionから情報を取得し、後で参照できるように保存します。

このコードはリクエストを記録します:

public class URLConnectionReader {

  public static void main(String[] args) throws Exception {
  URL Oracle = new URL("http://www.google.com/");
  URLConnection yc = Oracle.openConnection();

  String headerName = null;
  for (int i = 1; (headerName = yc.getHeaderFieldKey(i)) != null; i++) {
    if (headerName.equals("Set-Cookie")) {
      String cookie = yc.getHeaderField(i);
      System.out.println("Cookie  ::  " + cookie);
    } else {
      System.out.println("Header: "+ yc.getHeaderField(i));
    }
  }

  BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
  String inputLine;
  while ((inputLine = in.readLine()) != null)
    System.out.println(inputLine);
  in.close();
}

}

このすべてのデータを1つ以上のファイルに保存することは難しくありません。私があなたの問題に正しい道を進んでいると信じているなら、私は必要に応じて他の詳細で答えを喜んで編集します。

2
giampaolo

ネットワークトラフィックをログに記録する必要があり、URLConnectionオブジェクトがある場合、問題はすでに解決されています。
ストリームレベルでログを記録する場合は、I/Oストリームの上に小さなラッパーを書き込み、すべてのデータを記録してから下位のネットワークレイヤーに転送する必要があります。それ以外の場合は、接続オブジェクトを直接使用して取得できます。必要な情報とそれらを記録します。
Cookieを管理するには、Java.net.HttpCookie Java 6.で導入されました。6.行う必要があるのは、CookieManagerのインスタンスを作成し、それをデフォルトのCookieマネージャーとして設定することだけです。

CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

&接続Cookieの管理に使用できます!

1