FileDocCategorySizeDatePackage
SocketServer.javaAPI DocApache log4j 1.2.156922Sat Aug 25 00:09:40 BST 2007org.apache.log4j.net

SocketServer

public class SocketServer extends Object
A {@link SocketNode} based server that uses a different hierarchy for each client.
Usage: java org.apache.log4j.net.SocketServer port configFile configDir

where port is a part number where the server listens,
configFile is a configuration file fed to the {@link PropertyConfigurator} and
configDir is a path to a directory containing configuration files, possibly one for each client host.

The configFile is used to configure the log4j default hierarchy that the SocketServer will use to report on its actions.

When a new connection is opened from a previously unknown host, say foo.bar.net, then the SocketServer will search for a configuration file called foo.bar.net.lcf under the directory configDir that was passed as the third argument. If the file can be found, then a new hierarchy is instantiated and configured using the configuration file foo.bar.net.lcf. If and when the host foo.bar.net opens another connection to the server, then the previously configured hierarchy is used.

In case there is no file called foo.bar.net.lcf under the directory configDir, then the generic hierarchy is used. The generic hierarchy is configured using a configuration file called generic.lcf under the configDir directory. If no such file exists, then the generic hierarchy will be identical to the log4j default hierarchy.

Having different client hosts log using different hierarchies ensures the total independence of the clients with respect to their logging settings.

Currently, the hierarchy that will be used for a given request depends on the IP address of the client host. For example, two separate applicatons running on the same host and logging to the same server will share the same hierarchy. This is perfectly safe except that it might not provide the right amount of independence between applications. The SocketServer is intended as an example to be enhanced in order to implement more elaborate policies.

author
Ceki Gülcü
since
1.0

Fields Summary
static String
GENERIC
static String
CONFIG_FILE_EXT
static Logger
cat
static SocketServer
server
static int
port
Hashtable
hierarchyMap
LoggerRepository
genericHierarchy
File
dir
Constructors Summary
public SocketServer(File directory)

    this.dir = directory;
    hierarchyMap = new Hashtable(11);
  
Methods Summary
org.apache.log4j.spi.LoggerRepositoryconfigureHierarchy(java.net.InetAddress inetAddress)

    cat.info("Locating configuration file for "+inetAddress);
    // We assume that the toSting method of InetAddress returns is in
    // the format hostname/d1.d2.d3.d4 e.g. torino/192.168.1.1
    String s = inetAddress.toString();
    int i = s.indexOf("/");
    if(i == -1) {
      cat.warn("Could not parse the inetAddress ["+inetAddress+
	       "]. Using default hierarchy.");
      return genericHierarchy();
    } else {
      String key = s.substring(0, i);

      File configFile = new File(dir, key+CONFIG_FILE_EXT);
      if(configFile.exists()) {
	Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG));
	hierarchyMap.put(inetAddress, h);

	new PropertyConfigurator().doConfigure(configFile.getAbsolutePath(), h);

	return h;
      } else {
	cat.warn("Could not find config file ["+configFile+"].");
	return genericHierarchy();
      }
    }
  
org.apache.log4j.spi.LoggerRepositorygenericHierarchy()

    if(genericHierarchy == null) {
      File f = new File(dir, GENERIC+CONFIG_FILE_EXT);
      if(f.exists()) {
	genericHierarchy = new Hierarchy(new RootLogger(Level.DEBUG));
	new PropertyConfigurator().doConfigure(f.getAbsolutePath(), genericHierarchy);
      } else {
	cat.warn("Could not find config file ["+f+
		 "]. Will use the default hierarchy.");
	genericHierarchy = LogManager.getLoggerRepository();
      }
    }
    return genericHierarchy;
  
static voidinit(java.lang.String portStr, java.lang.String configFile, java.lang.String dirStr)

    try {
      port = Integer.parseInt(portStr);
    }
    catch(java.lang.NumberFormatException e) {
      e.printStackTrace();
      usage("Could not interpret port number ["+ portStr +"].");
    }

    PropertyConfigurator.configure(configFile);

    File dir = new File(dirStr);
    if(!dir.isDirectory()) {
      usage("["+dirStr+"] is not a directory.");
    }
    server = new SocketServer(dir);
  
public static voidmain(java.lang.String[] argv)


  
  
     
    if(argv.length == 3)
      init(argv[0], argv[1], argv[2]);
    else
      usage("Wrong number of arguments.");

    try {
      cat.info("Listening on port " + port);
      ServerSocket serverSocket = new ServerSocket(port);
      while(true) {
	cat.info("Waiting to accept a new client.");
	Socket socket = serverSocket.accept();
	InetAddress inetAddress =  socket.getInetAddress();
	cat.info("Connected to client at " + inetAddress);

	LoggerRepository h = (LoggerRepository) server.hierarchyMap.get(inetAddress);
	if(h == null) {
	  h = server.configureHierarchy(inetAddress);
	}

	cat.info("Starting new socket node.");
	new Thread(new SocketNode(socket, h)).start();
      }
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  
static voidusage(java.lang.String msg)

    System.err.println(msg);
    System.err.println(
      "Usage: java " +SocketServer.class.getName() + " port configFile directory");
    System.exit(1);