Tuesday, 11 March 2014

Simple Logging - Extended

This is a followup of the Simple Logging blogpost.

It is possible to change the logging.properties file to use a FileHandler. This directs everything to a file, (obviously).

Check reference 3 for a good explanation of the logging.properties file.

Unfortunately the default values of the FileHandler in the default JSE logging.properties6 file leaves a lot to be desired.

property
default
comments
mine
limit5000050 kilobytes is quite small for a log file5000000
count1this means the total number of files written is 1, so if the log increases beyond 'limit', you lose the old messages as the file is re-initialized100
appendfalsemight want to set this to true, to prevent loss of log messages upon restart. Unfortunately, this means you'll have *two* XML files within the log and they need to be separated afterwards.true

The following Handlers seem to be already available in Java4, if you're looking for something different.

I very much like the XMLFormatter. It provides even more information than general logging, and it can be easily post-processed.

JLogViewer


JLogViewer1 can view the XML logs written to file. I am sure there are other programs that perform the same function, but this is the one I happened to come across.

java -cp jlogviewer_1_0_0d.jar gianluca.utility.LogViewer

Fixing the logs

Unfortunately for me, the logs contain odd characters (because I am writing received data from sockets into the logs) that are not properly handled by jlogviewer.

I was required to remove the special characters from my logs. Found a blog post2 on how to remove them.
cat java0.log.0 | tr -d "\013" | tr -d "\001" | tr -d "\000" | tr -d "\017" > sanitized_java.log

Update 17-03-2014: updated the item on appending to existing logs.

References

[1] JLogViewer
http://jlogviewer.sourceforge.net/
[2] Removing special characters in Linux
http://deepupc.wordpress.com/2009/10/28/removing-special-charactersmca-in-vi/
[3] java Logging - Configuration
http://tutorials.jenkov.com/java-logging/configuration.html
[4] javadoc java.util.logging.Handler
http://docs.oracle.com/javase/7/docs/api/java/util/logging/Handler.html
[5] javadoc java.util.logging.LogManager
http://docs.oracle.com/javase/7/docs/api/java/util/logging/LogManager.html
[6] default logging.properties provided by JRE 7
https://gist.github.com/maartenl/9346237

Tuesday, 4 March 2014

SocketProxyServer

I recently had a need to check out the communication between a client and a server, as well as act upon the contents. Now, I could have used a Network Sniffer to find that out, but it's hard to have a hook with a Network Sniffer and a Java program. Besides, the level of detail is a bit too high. I was only interested in what data is actually going over the line.

With this in mind, I set about to write my "socket proxy server".

The main reason for this "socket proxy server" is because I both do not control the client and the server, yet I wish to "be involved". One saving grace is that I can change the server IP address on the client.

I tested my socket proxy server by starting it as a proxy to a simple website.

java -cp socketproxy.jar com.tools.socketproxy.Main 8080 www.karchan.org 80

So, now I could connect to http://localhost:8080 and I would see the website provided.

Here is the communication as the socket proxy server saw it. First the messages as sent by the client.
received from client:{GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:27.0) Gecko/20100101 Firefox/27.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: has_js=1
Connection: keep-alive
If-Modified-Since: Wed, 26 Feb 2014 16:26:34 +0000
If-None-Match: "1393431994"

}
Consequently the reply from the server.
received from server:{HTTP/1.1 200 OK
Date: Wed, 26 Feb 2014 16:29:04 GMT
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Wed, 26 Feb 2014 16:29:04 +0000
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
ETag: "1393432144"
Link: </node/1>; rel="canonical",</node/1>; rel="shortlink"
X-Generator: Drupal 7 (http://drupal.org)
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

26a5
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
  "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" version="XHTML+RDFa 1.0" dir="ltr"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:dc="http://purl.org/dc/terms/"
  xmlns:foaf="http://xmlns.com/foaf/0.1/"
...


The UML diagram above, shows the main Thread classes and how they relate to each other.

Dealing with multi-threaded programming is always hard and dangerous. In our case, the threads are provided by a fixed thread pool in the concurrency package of Java. I also had a List of Messages, so the list was created using Collections.synchronizedList(List list). What helps is that two connections cannot interfere with each other, making threading easier.

You can find the source code (Java 7) and javadoc in the references below.

Currently the functionality is limited, however it should be easy to extend.

For example, the current listener will only be called after the conversation has finished. This makes the current implementation unsuitable for directly interfering in the communication.

I required this socket proxy server for one of my private hobby projects. This will be the subject of one of my next blog posts. See [1].

References

Github - socketproxy repository
https://github.com/maartenl/socketproxy
Github - socketproxy javadoc
http://maartenl.github.io/socketproxy/javadoc/
[1] Google App Engine - First Try
http://randomthoughtsonjavaprogramming.blogspot.nl/2014/03/google-app-engine-first-try.html