1 16 17 19 package org.apache.log4j.net; 20 21 import java.net.InetAddress ; 22 import java.net.Socket ; 23 import java.io.IOException ; 24 import java.io.ObjectOutputStream ; 25 import java.io.ObjectOutputStream ; 26 27 import org.apache.log4j.helpers.LogLog; 28 import org.apache.log4j.spi.LoggingEvent; 29 import org.apache.log4j.AppenderSkeleton; 30 31 99 100 public class SocketAppender extends AppenderSkeleton { 101 102 105 static final int DEFAULT_PORT = 4560; 106 107 110 static final int DEFAULT_RECONNECTION_DELAY = 30000; 111 112 116 String remoteHost; 117 118 InetAddress address; 119 int port = DEFAULT_PORT; 120 ObjectOutputStream oos; 121 int reconnectionDelay = DEFAULT_RECONNECTION_DELAY; 122 boolean locationInfo = false; 123 124 private Connector connector; 125 126 int counter = 0; 127 128 129 private static final int RESET_FREQUENCY = 1; 132 133 public SocketAppender() { 134 } 135 136 139 public SocketAppender(InetAddress address, int port) { 140 this.address = address; 141 this.remoteHost = address.getHostName(); 142 this.port = port; 143 connect(address, port); 144 } 145 146 149 public SocketAppender(String host, int port) { 150 this.port = port; 151 this.address = getAddressByName(host); 152 this.remoteHost = host; 153 connect(address, port); 154 } 155 156 159 public void activateOptions() { 160 connect(address, port); 161 } 162 163 169 synchronized public void close() { 170 if(closed) 171 return; 172 173 this.closed = true; 174 cleanUp(); 175 } 176 177 181 public void cleanUp() { 182 if(oos != null) { 183 try { 184 oos.close(); 185 } catch(IOException e) { 186 LogLog.error("Could not close oos.", e); 187 } 188 oos = null; 189 } 190 if(connector != null) { 191 connector.interrupted = true; 193 connector = null; } 195 } 196 197 void connect(InetAddress address, int port) { 198 if(this.address == null) 199 return; 200 try { 201 cleanUp(); 203 oos = new ObjectOutputStream (new Socket (address, port).getOutputStream()); 204 } catch(IOException e) { 205 206 String msg = "Could not connect to remote log4j server at [" 207 +address.getHostName()+"]."; 208 if(reconnectionDelay > 0) { 209 msg += " We will try again later."; 210 fireConnector(); } 212 LogLog.error(msg, e); 213 } 214 } 215 216 217 public void append(LoggingEvent event) { 218 if(event == null) 219 return; 220 221 if(address==null) { 222 errorHandler.error("No remote host is set for SocketAppender named \""+ 223 this.name+"\"."); 224 return; 225 } 226 227 if(oos != null) { 228 try { 229 if(locationInfo) { 230 event.getLocationInformation(); 231 } 232 oos.writeObject(event); 233 oos.flush(); 235 if(++counter >= RESET_FREQUENCY) { 236 counter = 0; 237 oos.reset(); 241 } 242 } catch(IOException e) { 243 oos = null; 244 LogLog.warn("Detected problem with connection: "+e); 245 if(reconnectionDelay > 0) { 246 fireConnector(); 247 } 248 } 249 } 250 } 251 252 void fireConnector() { 253 if(connector == null) { 254 LogLog.debug("Starting a new connector thread."); 255 connector = new Connector(); 256 connector.setDaemon(true); 257 connector.setPriority(Thread.MIN_PRIORITY); 258 connector.start(); 259 } 260 } 261 262 static 263 InetAddress getAddressByName(String host) { 264 try { 265 return InetAddress.getByName(host); 266 } catch(Exception e) { 267 LogLog.error("Could not find address of ["+host+"].", e); 268 return null; 269 } 270 } 271 272 276 public boolean requiresLayout() { 277 return false; 278 } 279 280 285 public void setRemoteHost(String host) { 286 address = getAddressByName(host); 287 remoteHost = host; 288 } 289 290 293 public String getRemoteHost() { 294 return remoteHost; 295 } 296 297 301 public void setPort(int port) { 302 this.port = port; 303 } 304 305 308 public int getPort() { 309 return port; 310 } 311 312 317 public void setLocationInfo(boolean locationInfo) { 318 this.locationInfo = locationInfo; 319 } 320 321 324 public boolean getLocationInfo() { 325 return locationInfo; 326 } 327 328 337 public void setReconnectionDelay(int delay) { 338 this.reconnectionDelay = delay; 339 } 340 341 344 public int getReconnectionDelay() { 345 return reconnectionDelay; 346 } 347 348 360 class Connector extends Thread { 361 362 boolean interrupted = false; 363 364 public 365 void run() { 366 Socket socket; 367 while(!interrupted) { 368 try { 369 sleep(reconnectionDelay); 370 LogLog.debug("Attempting connection to "+address.getHostName()); 371 socket = new Socket (address, port); 372 synchronized(this) { 373 oos = new ObjectOutputStream (socket.getOutputStream()); 374 connector = null; 375 LogLog.debug("Connection established. Exiting connector thread."); 376 break; 377 } 378 } catch(InterruptedException e) { 379 LogLog.debug("Connector interrupted. Leaving loop."); 380 return; 381 } catch(java.net.ConnectException e) { 382 LogLog.debug("Remote host "+address.getHostName() 383 +" refused connection."); 384 } catch(IOException e) { 385 LogLog.debug("Could not connect to " + address.getHostName()+ 386 ". Exception is " + e); 387 } 388 } 389 } 391 392 398 } 399 400 } 401 | Popular Tags |