Log all network interactions of Java application

百般思念 提交于 2019-12-18 14:15:41

问题


I have a monstrous Java app (a client of little-known application server GNUEnterprise) and its source, which I can compile back after making some changes to it. The app uses network heavily and I need to monitor each request and response. I could use a sniffer like Wireshark, but the application works with its server over SSL, so not knowing SSL-certificate's private key any sniffed traffic is pretty useless.

What can I do to make every request and response to be logged from the application itself? I need to see all sent and received headers. I don't want to alter all code responsible for network interaction. What I want is to put a code like

Network.setDefaultLogger(myCustomLoggerInstance);

somewhere near start of the app and then in the myCustomLoggerInstance do all the logging I need.

Also, given all network operations are made with URLConnections, I can get response headers with con.getHeaderFields() and request headers with con.getRequestProperties(). But why cookies aren't there? How to dump sent and received cookies in the same way?

EDIT: What I'm trying to reach is to mimic RPC-application's communication with it's server over SSL, say, using curl. For this I need to get detailed log of app's network traffic.


回答1:


Can't you use a logging proxy server, e.g. http://www.charlesproxy.com/ or http://fiddler2.com/? Charles Proxy can also decode AMF requests, Fiddler is the champion for SSL interception.

IIRC you can set system properties http.proxyHost and http.proxyPort to 127.0.0.1 and 8888, and java URLConnections will automatically connect via your logging proxy server, and you get a nice view of your HTTP Traffic.

Or, if the intention is to be able to replay the communication, use JMeter HTTP Proxy, this records in a format that is suitable for replay. It has also built-in support for handling cookies.

If the application uses nice web services, SoapUI also has a monitoring proxy that intercepts web service calls for which you have imported the WSDL.




回答2:


A quick way to log all SSL traffic is to startup java with:

-Djavax.net.debug=all

Or set it as a system property:

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

Brace yourself. Standard out gets NOISY if you do this!

(*Note: only logs SSL traffic and SSL debug info (handshakes, etc). Regular sockets are not logged.)




回答3:


I just want to post a snippet of code that you can use at starting point. I do not have a"global" logger but with small changes to existing code you can reach your goal. I "log" on standard output, since your problem can be split into two pieces: getting the info from UrlConnection and store it for further reference.

This code logs the request:

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();
}

}

saving all this data to one or more files is not hard. If you believe that I'm on right way for you problem, I would be glad to edit the answer with other details as needed.




回答4:


I dug a little further, and apparently, HttpURLConnection comes with java.util.logging enabled by default.

See related questions: Java: Display request of an HttpURLConnection before sending and How to enable wire logging for a java HttpURLConnection traffic?

Java.util.logging was Sun's (failed) attempt at standardizing logging providers in Java 1.4. You can bridge it to SLF4J via the jul-to-slf4j module if you want to avoid tweaking system properties.

But I would still prefer Fiddler or JMeter proxy though :-)




回答5:


If you want to log network traffic & you have URLConnection objects then the problem is already solved!
If you want to log at stream level, you need to write a little wrapper on top of your I/O streams & log all data before transfer them to lower network layers, otherwise you can use connection objects directly to get required info & log them.
For managing cookies, you should use java.net.HttpCookie which is introduced in java 6. Only thing you have to do is to create an instance of CookieManager & set it as default cookie manager:

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

& you can use it for managing connection cookies!



来源:https://stackoverflow.com/questions/18512522/log-all-network-interactions-of-java-application

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!