001 /* 002 * Copyright 2005-2006 Stephen McConnell. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.station.server; 020 021 import java.io.IOException; 022 import java.io.InputStream; 023 import java.io.ObjectInputStream; 024 import java.io.BufferedInputStream; 025 import java.net.Socket; 026 import java.net.ServerSocket; 027 import java.net.SocketException; 028 import java.util.logging.Logger; 029 import java.util.logging.LogRecord; 030 031 import net.dpml.depot.LogStatement; 032 033 import net.dpml.lang.PID; 034 035 /** 036 * The LoggingServer is a remote service that handles the aggregation of 037 * log records from multiple jvm processes. 038 * 039 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 040 * @version 1.2.0 041 */ 042 public class LoggingServer implements Runnable 043 { 044 private static final PID PROCESS = new PID(); 045 046 private final ServerSocket m_server; 047 048 private int m_count = 0; 049 050 /** 051 * Creation of a new logging service instance. 052 * @param port the log server port 053 * @exception IOException if an IO exception occurs 054 */ 055 public LoggingServer( int port ) throws IOException 056 { 057 m_server = new ServerSocket( port ); 058 } 059 060 /** 061 * Runnable implementation. 062 */ 063 public void run() 064 { 065 while( true ) 066 { 067 try 068 { 069 Socket socket = m_server.accept(); 070 RequestHandler handler = new RequestHandler( socket ); 071 Thread thread = new Thread( handler ); 072 thread.start(); 073 } 074 catch( Throwable e ) 075 { 076 e.printStackTrace(); 077 m_count++; 078 } 079 } 080 } 081 082 int getErrorCount() 083 { 084 return m_count; 085 } 086 087 /** 088 * Internal utility class to handle a client connection. 089 */ 090 final class RequestHandler implements Runnable 091 { 092 private final Socket m_socket; 093 094 /** 095 * Creation of a new request handler. 096 * @param socket the socket 097 */ 098 private RequestHandler( Socket socket ) 099 { 100 m_socket = socket; 101 } 102 103 /** 104 * Run the process. 105 */ 106 public void run() 107 { 108 try 109 { 110 InputStream input = m_socket.getInputStream(); 111 BufferedInputStream buffer = new BufferedInputStream( input ); 112 ObjectInputStream ois = new ObjectInputStream( buffer ); 113 while( true ) 114 { 115 Object object = ois.readObject(); 116 if( object instanceof LogStatement ) 117 { 118 LogStatement statement = (LogStatement) object; 119 PID pid = statement.getPID(); 120 if( !PROCESS.equals( pid ) ) 121 { 122 int id = pid.getValue(); 123 LogRecord record = statement.getLogRecord(); 124 String raw = record.getMessage(); 125 String message = "$[" + id + "] " + raw; 126 record.setMessage( message ); 127 Logger logger = getNamedLogger( record ); 128 logger.log( record ); 129 } 130 } 131 } 132 //System.out.println( "## DONE" ); 133 //input.close(); 134 //m_socket.close(); 135 } 136 catch( ClassNotFoundException e ) 137 { 138 e.printStackTrace(); 139 } 140 catch( SocketException ioe ) 141 { 142 // ignore 143 } 144 catch( IOException ioe ) 145 { 146 ioe.printStackTrace(); 147 } 148 } 149 150 private Logger getNamedLogger( LogRecord record ) 151 { 152 String name = record.getLoggerName(); 153 if( null != name ) 154 { 155 return Logger.getLogger( name ); 156 } 157 else 158 { 159 return Logger.getAnonymousLogger(); 160 } 161 } 162 } 163 164 } 165