Socket Logging

by John Zukowski

A couple of recent Core Java Technologies Tech Tips were related to the Java Logging API, found in the java.util.logging package. You may have read the recent tip titled Logging Localized Messages or the 2002 tip titled Filtering Logged Messages. The logging examples are always to the local file system or console. However, you can install any logging Handler, including the default SocketHandler, which allows you to send your log messages to a centralized server. Setting up the handler is easy. Configuring the server requires a little work.

Here's what a typical logging program looks like. Basically, just get the Logger and log a message to it. You control the severity of the message and and the content of the message itself.

import java.io.\*;
import java.util.logging.\*;

public class LogTest {
  private static Logger logger =
      Logger.getAnonymousLogger();
  public static void main(String argv[]) throws IOException {
    logger.log(Level.SEVERE, "Hello, World");
    logger.log(Level.INFO, "Welcome Home");
  }
}

By default, the messages go to whatever is configured in the logging.properties file found for the Java Runtime Environment (JRE). The handlers line of that file specifies which Handler to use for logging messages. That default is the ConsoleHandler:

handlers= java.util.logging.ConsoleHandler

But the file also includes a default FileHandler definition:

java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

And changing the handlers line to the following will cause messages to go the FileHandler in addition to the ConsoleHandler.

handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

The system comes with two additional system-defined Handler types. The MemoryHandler class represents an in-memory circular buffer and SocketHandler for logging messages to the network. The constructor public SocketHandler(String host, int port) then allows you to define where to send network log messages, or you can place the necessary settings in the logging.properties file and use the no-argument version of the constructor.

If you would prefer not to use the logging.properties file, you can add the SocketHandler to the LogTest program. Simply create the Handler and add it to the Logger with the addHandler() call. Assuming that something is listening at the other end, you'll get messages sent using the default XMLFormatter.

import java.io.\*;
import java.util.logging.\*;

public class LogTest {
  private static Logger logger =
      Logger.getAnonymousLogger();
  public static void main(String argv[]) throws IOException {
    Handler handler = new SocketHandler("localhost", 5000);
    logger.addHandler(handler);
    logger.log(Level.SEVERE, "Hello, World");
    logger.log(Level.INFO, "Welcome Home");
  }
}

This sends messages to port 5000 on localhost (the user's computer). Of course, by default, nothing is listening on the other end. You must create a server.

The following is a very simple version of a server that listens on port 5000 for connections and dumps data to its console. You could also use this to send data.

import javax.net.ssl.\*;
import javax.net.\*;
import java.io.\*;
import java.net.\*;

public class LogServer {
  private static final int PORT_NUM = 5000;
  public static void main(String args[]) {
    ServerSocketFactory serverSocketFactory =
      ServerSocketFactory.getDefault();
    ServerSocket serverSocket = null;
    try {
      serverSocket =
        serverSocketFactory.createServerSocket(PORT_NUM);
    } catch (IOException ignored) {
      System.err.println("Unable to create server");
      System.exit(-1);
    }
    System.out.printf("LogServer running on port: %s%n", PORT_NUM);
    while (true) {
      Socket socket = null;
      try {
        socket = serverSocket.accept();
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(
          new InputStreamReader(is, "US-ASCII"));
        String line = null;
        while ((line = br.readLine()) != null) {
          System.out.println(line);
        }
      } catch (IOException exception) {
        // Just handle next request.
      } finally {
        if (socket != null) {
          try {
            socket.close();
          } catch (IOException ignored) {
          }
        }
      }
    }
  }
}

The program here comes from the SSL Servers tip, but the author has modified that code by removing the SSL piece and using a regular ServerSocketFactory. Also, instead of echoing the message back, that message goes to the console.

Now, if you compile and run the LogServer in one window and run the LogTest program in another window, you'll notice the messages received by the LogServer. You can run LogTest multiple times to repeatedly send the same two messages. The server simply continues to accept messages.

As you can see, there isn't much to sending logging messages to a centralized network server. A configuration like this can help considerably when logging infrequent problems, as users will not have to log exactly what they were doing when a rare error situation occurred.

For more information on creating a server, see the All About Sockets lesson of the Java SE Tutorial's Custom Networking trail.

\*\*\*\*\*\*\*\*

Ask the Experts Transcript: NetBeans IDE 6.0. Is there an obfuscator function in NetBeans? How can I run/invoke JavaFx code from a NetBeans module? What is the current status of PHP support in NetBeans? Get answers to these and a wide variety of other questions about NetBeans in this transcript.

\*\*\*\*\*\*\*\*

Java SE 6 Update N introduces new features and enhancements aimed at providing an optimized consumer end user experience. We would like to invite you to try the Early Access versions and provide us your feedback. For a list of features: https://jdk6.dev.java.net/testing.html You can find more information at: http://jdk6.dev.java.net/ProjectHamburg.html

Comments:

Post a Comment:
Comments are closed for this entry.
About

John O'Conner

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today