KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > log4j > net > SocketServer


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.log4j.net;
18
19 import java.net.Socket JavaDoc;
20 import java.net.ServerSocket JavaDoc;
21 import java.net.InetAddress JavaDoc;
22 import java.io.File JavaDoc;
23 import java.util.Hashtable JavaDoc;
24
25 import org.apache.log4j.*;
26 import org.apache.log4j.spi.*;
27
28
29 /**
30    A {@link SocketNode} based server that uses a different hierarchy
31    for each client.
32
33    <pre>
34      <b>Usage:</b> java org.apache.log4j.net.SocketServer port configFile configDir
35
36      where <b>port</b> is a part number where the server listens,
37            <b>configFile</b> is a configuration file fed to the {@link PropertyConfigurator} and
38            <b>configDir</b> is a path to a directory containing configuration files, possibly one for each client host.
39      </pre>
40
41      <p>The <code>configFile</code> is used to configure the log4j
42      default hierarchy that the <code>SocketServer</code> will use to
43      report on its actions.
44
45      <p>When a new connection is opened from a previously unknown
46      host, say <code>foo.bar.net</code>, then the
47      <code>SocketServer</code> will search for a configuration file
48      called <code>foo.bar.net.lcf</code> under the directory
49      <code>configDir</code> that was passed as the third argument. If
50      the file can be found, then a new hierarchy is instantiated and
51      configured using the configuration file
52      <code>foo.bar.net.lcf</code>. If and when the host
53      <code>foo.bar.net</code> opens another connection to the server,
54      then the previously configured hierarchy is used.
55
56      <p>In case there is no file called <code>foo.bar.net.lcf</code>
57      under the directory <code>configDir</code>, then the
58      <em>generic</em> hierarchy is used. The generic hierarchy is
59      configured using a configuration file called
60      <code>generic.lcf</code> under the <code>configDir</code>
61      directory. If no such file exists, then the generic hierarchy will be
62      identical to the log4j default hierarchy.
63
64      <p>Having different client hosts log using different hierarchies
65      ensures the total independence of the clients with respect to
66      their logging settings.
67
68      <p>Currently, the hierarchy that will be used for a given request
69      depends on the IP address of the client host. For example, two
70      separate applicatons running on the same host and logging to the
71      same server will share the same hierarchy. This is perfectly safe
72      except that it might not provide the right amount of independence
73      between applications. The <code>SocketServer</code> is intended
74      as an example to be enhanced in order to implement more elaborate
75      policies.
76
77
78     @author Ceki G&uuml;lc&uuml;
79
80     @since 1.0 */

81
82 public class SocketServer {
83
84   static String JavaDoc GENERIC = "generic";
85   static String JavaDoc CONFIG_FILE_EXT = ".lcf";
86
87   static Logger cat = Logger.getLogger(SocketServer.class);
88   static SocketServer server;
89   static int port;
90
91   // key=inetAddress, value=hierarchy
92
Hashtable JavaDoc hierarchyMap;
93   LoggerRepository genericHierarchy;
94   File JavaDoc dir;
95
96   public
97   static
98   void main(String JavaDoc argv[]) {
99     if(argv.length == 3)
100       init(argv[0], argv[1], argv[2]);
101     else
102       usage("Wrong number of arguments.");
103
104     try {
105       cat.info("Listening on port " + port);
106       ServerSocket JavaDoc serverSocket = new ServerSocket JavaDoc(port);
107       while(true) {
108     cat.info("Waiting to accept a new client.");
109     Socket JavaDoc socket = serverSocket.accept();
110     InetAddress JavaDoc inetAddress = socket.getInetAddress();
111     cat.info("Connected to client at " + inetAddress);
112
113     LoggerRepository h = (LoggerRepository) server.hierarchyMap.get(inetAddress);
114     if(h == null) {
115       h = server.configureHierarchy(inetAddress);
116     }
117
118     cat.info("Starting new socket node.");
119     new Thread JavaDoc(new SocketNode(socket, h)).start();
120       }
121     }
122     catch(Exception JavaDoc e) {
123       e.printStackTrace();
124     }
125   }
126
127
128   static
129   void usage(String JavaDoc msg) {
130     System.err.println(msg);
131     System.err.println(
132       "Usage: java " +SocketServer.class.getName() + " port configFile directory");
133     System.exit(1);
134   }
135
136   static
137   void init(String JavaDoc portStr, String JavaDoc configFile, String JavaDoc dirStr) {
138     try {
139       port = Integer.parseInt(portStr);
140     }
141     catch(java.lang.NumberFormatException JavaDoc e) {
142       e.printStackTrace();
143       usage("Could not interpret port number ["+ portStr +"].");
144     }
145
146     PropertyConfigurator.configure(configFile);
147
148     File JavaDoc dir = new File JavaDoc(dirStr);
149     if(!dir.isDirectory()) {
150       usage("["+dirStr+"] is not a directory.");
151     }
152     server = new SocketServer(dir);
153   }
154
155
156   public
157   SocketServer(File JavaDoc directory) {
158     this.dir = directory;
159     hierarchyMap = new Hashtable JavaDoc(11);
160   }
161
162   // This method assumes that there is no hiearchy for inetAddress
163
// yet. It will configure one and return it.
164
LoggerRepository configureHierarchy(InetAddress JavaDoc inetAddress) {
165     cat.info("Locating configuration file for "+inetAddress);
166     // We assume that the toSting method of InetAddress returns is in
167
// the format hostname/d1.d2.d3.d4 e.g. torino/192.168.1.1
168
String JavaDoc s = inetAddress.toString();
169     int i = s.indexOf("/");
170     if(i == -1) {
171       cat.warn("Could not parse the inetAddress ["+inetAddress+
172            "]. Using default hierarchy.");
173       return genericHierarchy();
174     } else {
175       String JavaDoc key = s.substring(0, i);
176
177       File JavaDoc configFile = new File JavaDoc(dir, key+CONFIG_FILE_EXT);
178       if(configFile.exists()) {
179     Hierarchy h = new Hierarchy(new RootLogger((Level) Priority.DEBUG));
180     hierarchyMap.put(inetAddress, h);
181
182     new PropertyConfigurator().doConfigure(configFile.getAbsolutePath(), h);
183
184     return h;
185       } else {
186     cat.warn("Could not find config file ["+configFile+"].");
187     return genericHierarchy();
188       }
189     }
190   }
191
192   LoggerRepository genericHierarchy() {
193     if(genericHierarchy == null) {
194       File JavaDoc f = new File JavaDoc(dir, GENERIC+CONFIG_FILE_EXT);
195       if(f.exists()) {
196     genericHierarchy = new Hierarchy(new RootLogger((Level) Priority.DEBUG));
197     new PropertyConfigurator().doConfigure(f.getAbsolutePath(), genericHierarchy);
198       } else {
199     cat.warn("Could not find config file ["+f+
200          "]. Will use the default hierarchy.");
201     genericHierarchy = LogManager.getLoggerRepository();
202       }
203     }
204     return genericHierarchy;
205   }
206 }
207
Popular Tags