记录Java应用程序的所有网络交互



我有一个巨大的Java应用程序(鲜为人知的应用程序服务器GNUEnterprise的客户端)及其源代码,我可以在对其进行一些更改后将其编译回来。该应用程序严重使用网络,我需要监控每个请求和响应。我可以使用像Wireshark这样的嗅探器,但该应用程序通过SSL与服务器一起工作,所以不知道SSL证书的私钥——任何嗅探的流量都是毫无用处的。

我可以做些什么来从应用程序本身记录每个请求和响应?我需要查看所有发送和接收的邮件头。我不想更改所有负责网络交互的代码。我想要的是放一个类似的代码

Network.setDefaultLogger(myCustomLoggerInstance);

在应用程序启动附近的某个地方,然后在myCustomLoggerInstance中进行我需要的所有日志记录。

此外,假设所有网络操作都是用URLConnections进行的,我可以用con.getHeaderFields()获得响应标头,用con.getRequestProperties()获得请求标头。但是为什么没有饼干呢?如何以相同的方式转储发送和接收的cookie?

EDIT:我试图实现的是模拟RPC应用程序通过SSL与其服务器的通信,例如使用curl。为此,我需要获得应用程序网络流量的详细日志。

记录所有SSL流量的一种快速方法是用启动java

-Djavax.net.debug=all

或者将其设置为系统属性:

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

振作起来。如果你这样做,标准输出会发出噪音!

(*注意:只记录SSL流量和SSL调试信息(握手等)。未记录常规套接字。)

你不能使用日志代理服务器吗,例如。http://www.charlesproxy.com/或http://fiddler2.com/?Charles Proxy还可以解码AMF请求,Fiddler是SSL拦截的冠军。

IIRC您可以将系统属性http.proxyHost和http.proxyPort设置为127.0.0.1和8888,java URLConnection将通过日志代理服务器自动连接,您可以很好地查看http流量。

或者,如果目的是能够重播通信,请使用JMeter HTTP Proxy,这将以适合重播的格式进行记录。它还内置了对处理cookie的支持。

如果应用程序使用漂亮的web服务,SoapUI也有一个监视代理,它可以拦截您已导入WSDL的web服务调用。

我进一步研究了一下,很明显,HttpURLConnection默认启用java.util.logging。

请参阅相关问题:Java:在发送之前显示HttpURLConnection的请求,以及如何为Java HttpURLConnection流量启用有线日志记录?

Java.util.logging是Sun在Java 1.4中标准化日志记录提供程序的尝试(失败)。如果您想避免调整系统属性,可以通过jul-to-SLF4J模块将其桥接到SLF4J。

但我仍然更喜欢Fiddler或JMeter代理:-)

我只想发布一段代码,您可以在开始时使用它。我没有一个"全局"记录器,但只要对现有代码进行一些小的更改,你就可以达到你的目标。我"登录"标准输出,因为您的问题可以分为两部分:从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();
}

}

将所有这些数据保存到一个或多个文件并不困难。若你们相信我对你们的问题是正确的,我很乐意根据需要编辑答案和其他细节。

如果您想记录网络流量&如果您有URLConnection对象,那么问题已经解决了
如果你想在流级别进行日志记录,你需要在你的I/O流上写一个小包装器&在将所有数据传输到较低的网络层之前记录它们,否则您可以直接使用连接对象来获取所需的信息&记录它们
为了管理cookie,您应该使用java6中引入的java.net.HttpCookie。你唯一要做的就是创建一个CookieManager&将其设置为默认cookie管理器:

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

&您可以使用它来管理连接cookie!

最新更新