X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=srcjar%2Forg%2Fapache%2Flog4j%2Fnet%2FSocketServer.java;fp=srcjar%2Forg%2Fapache%2Flog4j%2Fnet%2FSocketServer.java;h=fda74adef3856e2eeeea007daeb89cceb4493776;hb=2d6292c0377bc6b773c6844a45d3f2c5fac352c7;hp=0000000000000000000000000000000000000000;hpb=954af328a2a6a0055572cd1a09ee035301222574;p=jalview.git diff --git a/srcjar/org/apache/log4j/net/SocketServer.java b/srcjar/org/apache/log4j/net/SocketServer.java new file mode 100644 index 0000000..fda74ad --- /dev/null +++ b/srcjar/org/apache/log4j/net/SocketServer.java @@ -0,0 +1,213 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j.net; + +import java.io.File; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Hashtable; + +import org.apache.log4j.Hierarchy; +import org.apache.log4j.Level; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.RootLogger; + + +/** + 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 applications 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 */ + +public class SocketServer { + + static String GENERIC = "generic"; + static String CONFIG_FILE_EXT = ".lcf"; + + static Logger cat = Logger.getLogger(SocketServer.class); + static SocketServer server; + static int port; + + // key=inetAddress, value=hierarchy + Hashtable hierarchyMap; + LoggerRepository genericHierarchy; + File dir; + + public + static + void main(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 + void usage(String msg) { + System.err.println(msg); + System.err.println( + "Usage: java " +SocketServer.class.getName() + " port configFile directory"); + System.exit(1); + } + + static + void init(String portStr, String configFile, 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 + SocketServer(File directory) { + this.dir = directory; + hierarchyMap = new Hashtable(11); + } + + // This method assumes that there is no hiearchy for inetAddress + // yet. It will configure one and return it. + LoggerRepository configureHierarchy(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(); + } + } + } + + LoggerRepository genericHierarchy() { + 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; + } +}