Home » apache-log4j-1.2.15 » org.apache » log4j » net » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.log4j.net;
   19   
   20   import java.net.Socket;
   21   import java.net.ServerSocket;
   22   import java.net.InetAddress;
   23   import java.io.File;
   24   import java.util.Hashtable;
   25   
   26   import org.apache.log4j;
   27   import org.apache.log4j.spi;
   28   
   29   
   30   /**
   31      A {@link SocketNode} based server that uses a different hierarchy
   32      for each client.
   33   
   34      <pre>
   35        <b>Usage:</b> java org.apache.log4j.net.SocketServer port configFile configDir
   36   
   37        where <b>port</b> is a part number where the server listens,
   38              <b>configFile</b> is a configuration file fed to the {@link PropertyConfigurator} and
   39              <b>configDir</b> is a path to a directory containing configuration files, possibly one for each client host.
   40        </pre>
   41   
   42        <p>The <code>configFile</code> is used to configure the log4j
   43        default hierarchy that the <code>SocketServer</code> will use to
   44        report on its actions.
   45   
   46        <p>When a new connection is opened from a previously unknown
   47        host, say <code>foo.bar.net</code>, then the
   48        <code>SocketServer</code> will search for a configuration file
   49        called <code>foo.bar.net.lcf</code> under the directory
   50        <code>configDir</code> that was passed as the third argument. If
   51        the file can be found, then a new hierarchy is instantiated and
   52        configured using the configuration file
   53        <code>foo.bar.net.lcf</code>. If and when the host
   54        <code>foo.bar.net</code> opens another connection to the server,
   55        then the previously configured hierarchy is used.
   56   
   57        <p>In case there is no file called <code>foo.bar.net.lcf</code>
   58        under the directory <code>configDir</code>, then the
   59        <em>generic</em> hierarchy is used. The generic hierarchy is
   60        configured using a configuration file called
   61        <code>generic.lcf</code> under the <code>configDir</code>
   62        directory. If no such file exists, then the generic hierarchy will be
   63        identical to the log4j default hierarchy.
   64   
   65        <p>Having different client hosts log using different hierarchies
   66        ensures the total independence of the clients with respect to
   67        their logging settings.
   68   
   69        <p>Currently, the hierarchy that will be used for a given request
   70        depends on the IP address of the client host. For example, two
   71        separate applicatons running on the same host and logging to the
   72        same server will share the same hierarchy. This is perfectly safe
   73        except that it might not provide the right amount of independence
   74        between applications. The <code>SocketServer</code> is intended
   75        as an example to be enhanced in order to implement more elaborate
   76        policies.
   77   
   78   
   79       @author  Ceki G&uuml;lc&uuml;
   80   
   81       @since 1.0 */
   82   
   83   public class SocketServer  {
   84   
   85     static String GENERIC = "generic";
   86     static String CONFIG_FILE_EXT = ".lcf";
   87   
   88     static Logger cat = Logger.getLogger(SocketServer.class);
   89     static SocketServer server;
   90     static int port;
   91   
   92     // key=inetAddress, value=hierarchy
   93     Hashtable hierarchyMap;
   94     LoggerRepository genericHierarchy;
   95     File dir;
   96   
   97     public
   98     static
   99     void main(String argv[]) {
  100       if(argv.length == 3)
  101         init(argv[0], argv[1], argv[2]);
  102       else
  103         usage("Wrong number of arguments.");
  104   
  105       try {
  106         cat.info("Listening on port " + port);
  107         ServerSocket serverSocket = new ServerSocket(port);
  108         while(true) {
  109   	cat.info("Waiting to accept a new client.");
  110   	Socket socket = serverSocket.accept();
  111   	InetAddress inetAddress =  socket.getInetAddress();
  112   	cat.info("Connected to client at " + inetAddress);
  113   
  114   	LoggerRepository h = (LoggerRepository) server.hierarchyMap.get(inetAddress);
  115   	if(h == null) {
  116   	  h = server.configureHierarchy(inetAddress);
  117   	}
  118   
  119   	cat.info("Starting new socket node.");
  120   	new Thread(new SocketNode(socket, h)).start();
  121         }
  122       }
  123       catch(Exception e) {
  124         e.printStackTrace();
  125       }
  126     }
  127   
  128   
  129     static
  130     void  usage(String msg) {
  131       System.err.println(msg);
  132       System.err.println(
  133         "Usage: java " +SocketServer.class.getName() + " port configFile directory");
  134       System.exit(1);
  135     }
  136   
  137     static
  138     void init(String portStr, String configFile, String dirStr) {
  139       try {
  140         port = Integer.parseInt(portStr);
  141       }
  142       catch(java.lang.NumberFormatException e) {
  143         e.printStackTrace();
  144         usage("Could not interpret port number ["+ portStr +"].");
  145       }
  146   
  147       PropertyConfigurator.configure(configFile);
  148   
  149       File dir = new File(dirStr);
  150       if(!dir.isDirectory()) {
  151         usage("["+dirStr+"] is not a directory.");
  152       }
  153       server = new SocketServer(dir);
  154     }
  155   
  156   
  157     public
  158     SocketServer(File directory) {
  159       this.dir = directory;
  160       hierarchyMap = new Hashtable(11);
  161     }
  162   
  163     // This method assumes that there is no hiearchy for inetAddress
  164     // yet. It will configure one and return it.
  165     LoggerRepository configureHierarchy(InetAddress inetAddress) {
  166       cat.info("Locating configuration file for "+inetAddress);
  167       // We assume that the toSting method of InetAddress returns is in
  168       // the format hostname/d1.d2.d3.d4 e.g. torino/192.168.1.1
  169       String s = inetAddress.toString();
  170       int i = s.indexOf("/");
  171       if(i == -1) {
  172         cat.warn("Could not parse the inetAddress ["+inetAddress+
  173   	       "]. Using default hierarchy.");
  174         return genericHierarchy();
  175       } else {
  176         String key = s.substring(0, i);
  177   
  178         File configFile = new File(dir, key+CONFIG_FILE_EXT);
  179         if(configFile.exists()) {
  180   	Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG));
  181   	hierarchyMap.put(inetAddress, h);
  182   
  183   	new PropertyConfigurator().doConfigure(configFile.getAbsolutePath(), h);
  184   
  185   	return h;
  186         } else {
  187   	cat.warn("Could not find config file ["+configFile+"].");
  188   	return genericHierarchy();
  189         }
  190       }
  191     }
  192   
  193     LoggerRepository  genericHierarchy() {
  194       if(genericHierarchy == null) {
  195         File f = new File(dir, GENERIC+CONFIG_FILE_EXT);
  196         if(f.exists()) {
  197   	genericHierarchy = new Hierarchy(new RootLogger(Level.DEBUG));
  198   	new PropertyConfigurator().doConfigure(f.getAbsolutePath(), genericHierarchy);
  199         } else {
  200   	cat.warn("Could not find config file ["+f+
  201   		 "]. Will use the default hierarchy.");
  202   	genericHierarchy = LogManager.getLoggerRepository();
  203         }
  204       }
  205       return genericHierarchy;
  206     }
  207   }

Save This Page
Home » apache-log4j-1.2.15 » org.apache » log4j » net » [javadoc | source]