http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/96ebd9ad/src/main/java/org/apache/log4j/net/SocketNode13.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/net/SocketNode13.java b/src/main/java/org/apache/log4j/net/SocketNode13.java index 1d5d77c..281fdb3 100644 --- a/src/main/java/org/apache/log4j/net/SocketNode13.java +++ b/src/main/java/org/apache/log4j/net/SocketNode13.java @@ -17,14 +17,6 @@ package org.apache.log4j.net; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import org.apache.log4j.Logger; import org.apache.log4j.helpers.Constants; import org.apache.log4j.plugins.Pauseable; @@ -33,266 +25,279 @@ import org.apache.log4j.spi.ComponentBase; import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.spi.LoggingEvent; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + // Contributors: Moses Hohman <mmhoh...@rainbow.uchicago.edu> /** - Read {@link LoggingEvent} objects sent from a remote client using - Sockets (TCP). These logging events are logged according to local - policy, as if they were generated locally. - - <p>For example, the socket node might decide to log events to a - local file and also resent them to a second socket node. - - Implementation lifted from org.apache.log4j.net.SocketNode - in log4j 1.3 and renamed to prevent collision with - log4j 1.2 implementation. - - @author Ceki Gülcü - @author Paul Smith (psm...@apache.org) - - -*/ + * Read {@link LoggingEvent} objects sent from a remote client using + * Sockets (TCP). These logging events are logged according to local + * policy, as if they were generated locally. + * <p> + * <p>For example, the socket node might decide to log events to a + * local file and also resent them to a second socket node. + * <p> + * Implementation lifted from org.apache.log4j.net.SocketNode + * in log4j 1.3 and renamed to prevent collision with + * log4j 1.2 implementation. + * + * @author Ceki Gülcü + * @author Paul Smith (psm...@apache.org) + */ public class SocketNode13 extends ComponentBase implements Runnable, Pauseable { /** * Paused state. */ - private boolean paused; + private boolean paused; /** * Closed state. */ - private boolean closed; + private boolean closed; /** * Socket. */ - private Socket socket; + private Socket socket; /** * Receiver. */ - private Receiver receiver; + private Receiver receiver; /** * List of listeners. */ - private final List listenerList = Collections.synchronizedList(new ArrayList()); - - - - /** - Constructor for socket and logger repository. - @param s socket - @param hierarchy logger repository - */ - public SocketNode13(final Socket s, - final LoggerRepository hierarchy) { - super(); - this.socket = s; - this.repository = hierarchy; - } - - /** - Constructor for socket and receiver. - @param s socket - @param r receiver - */ - public SocketNode13(final Socket s, final Receiver r) { - super(); - this.socket = s; - this.receiver = r; - } - - /** - * Set the event listener on this node. - * - * @deprecated Now supports mutliple listeners, this method - * simply invokes the removeSocketNodeEventListener() to remove - * the listener, and then readds it. - * @param l listener - */ - public void setListener(final SocketNodeEventListener l) { - removeSocketNodeEventListener(l); - addSocketNodeEventListener(l); - } - - /** - * Adds the listener to the list of listeners to be notified of the - * respective event. - * @param listener the listener to add to the list - */ - public void addSocketNodeEventListener( - final SocketNodeEventListener listener) { - listenerList.add(listener); - } - - /** - * Removes the registered Listener from this instances list of - * listeners. If the listener has not been registered, then invoking - * this method has no effect. - * - * @param listener the SocketNodeEventListener to remove - */ - public void removeSocketNodeEventListener( - final SocketNodeEventListener listener) { - listenerList.remove(listener); - } + private final List listenerList = Collections.synchronizedList(new ArrayList()); /** - * Deserialize events from socket until interrupted. + * Constructor for socket and logger repository. + * + * @param s socket + * @param hierarchy logger repository */ - public void run() { - LoggingEvent event; - Logger remoteLogger; - Exception listenerException = null; - ObjectInputStream ois; - - try { - ois = - new ObjectInputStream( - new BufferedInputStream(socket.getInputStream())); - } catch (Exception e) { - ois = null; - listenerException = e; - getLogger().error("Exception opening ObjectInputStream to " + socket, e); + public SocketNode13(final Socket s, + final LoggerRepository hierarchy) { + super(); + this.socket = s; + this.repository = hierarchy; } - if (ois != null) { + /** + * Constructor for socket and receiver. + * + * @param s socket + * @param r receiver + */ + public SocketNode13(final Socket s, final Receiver r) { + super(); + this.socket = s; + this.receiver = r; + } - String hostName = socket.getInetAddress().getHostName(); - String remoteInfo = hostName + ":" + socket.getPort(); + /** + * Set the event listener on this node. + * + * @param l listener + * @deprecated Now supports mutliple listeners, this method + * simply invokes the removeSocketNodeEventListener() to remove + * the listener, and then readds it. + */ + public void setListener(final SocketNodeEventListener l) { + removeSocketNodeEventListener(l); + addSocketNodeEventListener(l); + } - /** - * notify the listener that the socket has been - * opened and this SocketNode is ready and waiting - */ - fireSocketOpened(remoteInfo); + /** + * Adds the listener to the list of listeners to be notified of the + * respective event. + * + * @param listener the listener to add to the list + */ + public void addSocketNodeEventListener( + final SocketNodeEventListener listener) { + listenerList.add(listener); + } - try { - while (!isClosed()) { - // read an event from the wire - event = (LoggingEvent) ois.readObject(); - event.setProperty(Constants.HOSTNAME_KEY, hostName); - // store the known remote info in an event property - event.setProperty("log4j.remoteSourceInfo", remoteInfo); + /** + * Removes the registered Listener from this instances list of + * listeners. If the listener has not been registered, then invoking + * this method has no effect. + * + * @param listener the SocketNodeEventListener to remove + */ + public void removeSocketNodeEventListener( + final SocketNodeEventListener listener) { + listenerList.remove(listener); + } - // if configured with a receiver, tell it to post the event - if (!isPaused() && !isClosed()) { - if ((receiver != null)) { - receiver.doPost(event); - // else post it via the hierarchy - } else { - // get a logger from the hierarchy. The name of the logger - // is taken to be the name contained in the event. - remoteLogger = repository.getLogger(event.getLoggerName()); + /** + * Deserialize events from socket until interrupted. + */ + public void run() { + LoggingEvent event; + Logger remoteLogger; + Exception listenerException = null; + ObjectInputStream ois; + + try { + ois = + new ObjectInputStream( + new BufferedInputStream(socket.getInputStream())); + } catch (Exception e) { + ois = null; + listenerException = e; + getLogger().error("Exception opening ObjectInputStream to " + socket, e); + } - //event.logger = remoteLogger; - // apply the logger-level filter - if (event - .getLevel() - .isGreaterOrEqual(remoteLogger.getEffectiveLevel())) { - // finally log the event as if was generated locally - remoteLogger.callAppenders(event); - } + if (ois != null) { + + String hostName = socket.getInetAddress().getHostName(); + String remoteInfo = hostName + ":" + socket.getPort(); + + /** + * notify the listener that the socket has been + * opened and this SocketNode is ready and waiting + */ + fireSocketOpened(remoteInfo); + + try { + while (!isClosed()) { + // read an event from the wire + event = (LoggingEvent) ois.readObject(); + event.setProperty(Constants.HOSTNAME_KEY, hostName); + // store the known remote info in an event property + event.setProperty("log4j.remoteSourceInfo", remoteInfo); + + // if configured with a receiver, tell it to post the event + if (!isPaused() && !isClosed()) { + if ((receiver != null)) { + receiver.doPost(event); + + // else post it via the hierarchy + } else { + // get a logger from the hierarchy. The name of the logger + // is taken to be the name contained in the event. + remoteLogger = repository.getLogger(event.getLoggerName()); + + //event.logger = remoteLogger; + // apply the logger-level filter + if (event + .getLevel() + .isGreaterOrEqual(remoteLogger.getEffectiveLevel())) { + // finally log the event as if was generated locally + remoteLogger.callAppenders(event); + } + } + } else { + //we simply discard this event. + } + } + } catch (java.io.EOFException e) { + getLogger().info("Caught java.io.EOFException closing connection."); + listenerException = e; + } catch (java.net.SocketException e) { + getLogger().info("Caught java.net.SocketException closing connection."); + listenerException = e; + } catch (IOException e) { + getLogger().info("Caught java.io.IOException: " + e); + getLogger().info("Closing connection."); + listenerException = e; + } catch (Exception e) { + getLogger().error("Unexpected exception. Closing connection.", e); + listenerException = e; } - } else { - //we simply discard this event. - } } - } catch (java.io.EOFException e) { - getLogger().info("Caught java.io.EOFException closing connection."); - listenerException = e; - } catch (java.net.SocketException e) { - getLogger().info("Caught java.net.SocketException closing connection."); - listenerException = e; - } catch (IOException e) { - getLogger().info("Caught java.io.IOException: " + e); - getLogger().info("Closing connection."); - listenerException = e; - } catch (Exception e) { - getLogger().error("Unexpected exception. Closing connection.", e); - listenerException = e; - } - } - // close the socket - try { - if (ois != null) { - ois.close(); - } - } catch (Exception e) { - //getLogger().info("Could not close connection.", e); - } + // close the socket + try { + if (ois != null) { + ois.close(); + } + } catch (Exception e) { + //getLogger().info("Could not close connection.", e); + } - // send event to listener, if configured - if (listenerList.size() > 0 && !isClosed()) { - fireSocketClosedEvent(listenerException); + // send event to listener, if configured + if (listenerList.size() > 0 && !isClosed()) { + fireSocketClosedEvent(listenerException); + } } - } - /** - * Notifies all registered listeners regarding the closing of the Socket. - * @param listenerException listener exception - */ - private void fireSocketClosedEvent(final Exception listenerException) { - synchronized (listenerList) { - for (Object aListenerList : listenerList) { - SocketNodeEventListener snel = + /** + * Notifies all registered listeners regarding the closing of the Socket. + * + * @param listenerException listener exception + */ + private void fireSocketClosedEvent(final Exception listenerException) { + synchronized (listenerList) { + for (Object aListenerList : listenerList) { + SocketNodeEventListener snel = (SocketNodeEventListener) aListenerList; - if (snel != null) { - snel.socketClosedEvent(listenerException); + if (snel != null) { + snel.socketClosedEvent(listenerException); + } } } } - } - /** - * Notifies all registered listeners regarding the opening of a Socket. - * @param remoteInfo remote info - */ - private void fireSocketOpened(final String remoteInfo) { - synchronized (listenerList) { - for (Object aListenerList : listenerList) { - SocketNodeEventListener snel = + /** + * Notifies all registered listeners regarding the opening of a Socket. + * + * @param remoteInfo remote info + */ + private void fireSocketOpened(final String remoteInfo) { + synchronized (listenerList) { + for (Object aListenerList : listenerList) { + SocketNodeEventListener snel = (SocketNodeEventListener) aListenerList; - if (snel != null) { - snel.socketOpened(remoteInfo); + if (snel != null) { + snel.socketOpened(remoteInfo); + } } } } - } /** * Sets if node is paused. + * * @param b new value */ - public void setPaused(final boolean b) { - this.paused = b; - } + public void setPaused(final boolean b) { + this.paused = b; + } /** * Get if node is paused. + * * @return true if pause. */ - public boolean isPaused() { - return this.paused; - } + public boolean isPaused() { + return this.paused; + } /** * Close the node and underlying socket */ - public void close() throws IOException { - getLogger().debug("closing socket"); - this.closed = true; - socket.close(); - fireSocketClosedEvent(null); - } - + public void close() throws IOException { + getLogger().debug("closing socket"); + this.closed = true; + socket.close(); + fireSocketClosedEvent(null); + } + /** * Get if node is closed. + * * @return true if closed. */ - public boolean isClosed() { - return this.closed; - } + public boolean isClosed() { + return this.closed; + } }
http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/96ebd9ad/src/main/java/org/apache/log4j/net/SocketNodeEventListener.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/net/SocketNodeEventListener.java b/src/main/java/org/apache/log4j/net/SocketNodeEventListener.java index 6d17602..037f31f 100644 --- a/src/main/java/org/apache/log4j/net/SocketNodeEventListener.java +++ b/src/main/java/org/apache/log4j/net/SocketNodeEventListener.java @@ -20,24 +20,26 @@ package org.apache.log4j.net; import java.util.EventListener; /** - Interface used to listen for {@link SocketNode} related - events. Clients register an instance of the interface and the - instance is called back when the various events occur. - - @author Mark Womack - @author Paul Smith (psm...@apache.org) -*/ + * Interface used to listen for {@link SocketNode} related + * events. Clients register an instance of the interface and the + * instance is called back when the various events occur. + * + * @author Mark Womack + * @author Paul Smith (psm...@apache.org) + */ public interface SocketNodeEventListener extends EventListener { - /** - * Called when the SocketNode is created and begins awaiting data. - * @param remoteInfo remote info - */ - void socketOpened(String remoteInfo); + /** + * Called when the SocketNode is created and begins awaiting data. + * + * @param remoteInfo remote info + */ + void socketOpened(String remoteInfo); - /** - Called when the socket the node was given has been closed. - @param e exception - */ - void socketClosedEvent(Exception e); + /** + * Called when the socket the node was given has been closed. + * + * @param e exception + */ + void socketClosedEvent(Exception e); } http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/96ebd9ad/src/main/java/org/apache/log4j/net/SocketReceiver.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/net/SocketReceiver.java b/src/main/java/org/apache/log4j/net/SocketReceiver.java index 29725ab..b120142 100644 --- a/src/main/java/org/apache/log4j/net/SocketReceiver.java +++ b/src/main/java/org/apache/log4j/net/SocketReceiver.java @@ -17,461 +17,487 @@ package org.apache.log4j.net; -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Vector; - import org.apache.log4j.plugins.Pauseable; import org.apache.log4j.plugins.Plugin; import org.apache.log4j.plugins.Receiver; import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.spi.LoggingEvent; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.*; + /** - SocketReceiver receives a remote logging event on a configured - socket and "posts" it to a LoggerRepository as if the event was - generated locally. This class is designed to receive events from - the SocketAppender class (or classes that send compatible events). - - <p>Once the event has been "posted", it will be handled by the - appenders currently configured in the LoggerRespository. - - @author Mark Womack - @author Scott Deboy (sde...@apache.org) - @author Paul Smith (psm...@apache.org) -*/ + * SocketReceiver receives a remote logging event on a configured + * socket and "posts" it to a LoggerRepository as if the event was + * generated locally. This class is designed to receive events from + * the SocketAppender class (or classes that send compatible events). + * <p> + * <p>Once the event has been "posted", it will be handled by the + * appenders currently configured in the LoggerRespository. + * + * @author Mark Womack + * @author Scott Deboy (sde...@apache.org) + * @author Paul Smith (psm...@apache.org) + */ public class SocketReceiver extends Receiver implements Runnable, PortBased, - Pauseable { + Pauseable { /** * socket map. */ - private Map<Socket, SocketNode13> socketMap = new HashMap<>(); + private Map<Socket, SocketNode13> socketMap = new HashMap<>(); /** * Paused. */ - private boolean paused; + private boolean paused; /** * Thread. */ - private Thread rThread; + private Thread rThread; /** * Port. */ - protected int port; + protected int port; /** * Server socket. */ - private ServerSocket serverSocket; + private ServerSocket serverSocket; /** * Socket list. */ - private Vector<Socket> socketList = new Vector<>(); + private Vector<Socket> socketList = new Vector<>(); - /** - * The MulticastDNS zone advertised by a SocketReceiver - */ - public static final String ZONE = "_log4j_obj_tcpaccept_receiver.local."; + /** + * The MulticastDNS zone advertised by a SocketReceiver + */ + public static final String ZONE = "_log4j_obj_tcpaccept_receiver.local."; /** * Listener. */ - private SocketNodeEventListener listener = null; + private SocketNodeEventListener listener = null; /** * Listeners. */ - private final List listenerList = Collections.synchronizedList(new ArrayList()); - private boolean advertiseViaMulticastDNS; - private ZeroConfSupport zeroConf; + private final List listenerList = Collections.synchronizedList(new ArrayList()); + private boolean advertiseViaMulticastDNS; + private ZeroConfSupport zeroConf; /** * Create new instance. */ - public SocketReceiver() { + public SocketReceiver() { super(); - } + } /** * Create new instance. + * * @param p port */ - public SocketReceiver(final int p) { - super(); - port = p; - } + public SocketReceiver(final int p) { + super(); + port = p; + } /** * Create new instance. - * @param p port + * + * @param p port * @param repo logger repository */ - public SocketReceiver(final int p, final LoggerRepository repo) { - super(); - this.port = p; - repository = repo; - } - - /** {@inheritDoc} */ - public int getPort() { - return port; - } - - /** {@inheritDoc} */ - public void setPort(final int p) { - port = p; - } - - /** - * Returns true if the receiver is the same class and they are - * configured for the same properties, and super class also considers - * them to be equivalent. This is used by PluginRegistry when determining - * if the a similarly configured receiver is being started. - * - * @param testPlugin The plugin to test equivalency against. - * @return boolean True if the testPlugin is equivalent to this plugin. - */ - public boolean isEquivalent(final Plugin testPlugin) { - if ((testPlugin != null) && testPlugin instanceof SocketReceiver) { - SocketReceiver sReceiver = (SocketReceiver) testPlugin; - - return (port == sReceiver.getPort() && super.isEquivalent(testPlugin)); + public SocketReceiver(final int p, final LoggerRepository repo) { + super(); + this.port = p; + repository = repo; } - return false; - } - - /** - Starts the SocketReceiver with the current options. */ - public void activateOptions() { - if (!isActive()) { - // shutdown(); - rThread = new Thread(this); - rThread.setDaemon(true); - rThread.start(); - if (advertiseViaMulticastDNS) { - zeroConf = new ZeroConfSupport(ZONE, port, getName()); - zeroConf.advertise(); - } - - active = true; + /** + * {@inheritDoc} + */ + public int getPort() { + return port; } - } - /** - * Called when the receiver should be stopped. Closes the - * server socket and all of the open sockets. - */ - public synchronized void shutdown() { - getLogger().debug(getName() + " received shutdown request"); + /** + * {@inheritDoc} + */ + public void setPort(final int p) { + port = p; + } - // mark this as no longer running - active = false; + /** + * Returns true if the receiver is the same class and they are + * configured for the same properties, and super class also considers + * them to be equivalent. This is used by PluginRegistry when determining + * if the a similarly configured receiver is being started. + * + * @param testPlugin The plugin to test equivalency against. + * @return boolean True if the testPlugin is equivalent to this plugin. + */ + public boolean isEquivalent(final Plugin testPlugin) { + if ((testPlugin != null) && testPlugin instanceof SocketReceiver) { + SocketReceiver sReceiver = (SocketReceiver) testPlugin; - if (rThread != null) { - rThread.interrupt(); - rThread = null; - } - if (advertiseViaMulticastDNS) { - zeroConf.unadvertise(); + return (port == sReceiver.getPort() && super.isEquivalent(testPlugin)); + } + + return false; } - doShutdown(); - } - - /** - * Does the actual shutting down by closing the server socket - * and any connected sockets that have been created. - */ - private synchronized void doShutdown() { - active = false; - - getLogger().debug(getName() + " doShutdown called"); - - // close the server socket - closeServerSocket(); - - // close all of the accepted sockets - closeAllAcceptedSockets(); - } - - /** - * Closes the server socket, if created. - */ - private void closeServerSocket() { - getLogger().debug("{} closing server socket", getName()); - - try { - if (serverSocket != null) { - serverSocket.close(); - } - } catch (Exception e) { - // ignore for now + /** + * Starts the SocketReceiver with the current options. + */ + public void activateOptions() { + if (!isActive()) { + // shutdown(); + rThread = new Thread(this); + rThread.setDaemon(true); + rThread.start(); + if (advertiseViaMulticastDNS) { + zeroConf = new ZeroConfSupport(ZONE, port, getName()); + zeroConf.advertise(); + } + + active = true; + } } - serverSocket = null; - } - - /** - * Closes all the connected sockets in the List. - */ - private synchronized void closeAllAcceptedSockets() { - for (Object aSocketList : socketList) { - try { - ((Socket) aSocketList).close(); - } catch (Exception e) { - // ignore for now - } - } - - // clear member variables - socketMap.clear(); - socketList.clear(); - } - - /** - Sets the flag to indicate if receiver is active or not. - @param b new value - */ - protected synchronized void setActive(final boolean b) { - active = b; - } - - public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) { - this.advertiseViaMulticastDNS = advertiseViaMulticastDNS; - } - - public boolean isAdvertiseViaMulticastDNS() { - return advertiseViaMulticastDNS; - } - - /** - Loop, accepting new socket connections. */ - public void run() { /** - * Ensure we start fresh. + * Called when the receiver should be stopped. Closes the + * server socket and all of the open sockets. */ - closeServerSocket(); - closeAllAcceptedSockets(); - - // start the server socket - try { - serverSocket = new ServerSocket(port); - } catch (Exception e) { - getLogger().error( - "error starting SocketReceiver (" + this.getName() - + "), receiver did not start", e); - active = false; - - return; + public synchronized void shutdown() { + getLogger().debug(getName() + " received shutdown request"); + + // mark this as no longer running + active = false; + + if (rThread != null) { + rThread.interrupt(); + rThread = null; + } + if (advertiseViaMulticastDNS) { + zeroConf.unadvertise(); + } + + doShutdown(); } - Socket socket = null; + /** + * Does the actual shutting down by closing the server socket + * and any connected sockets that have been created. + */ + private synchronized void doShutdown() { + active = false; - try { - getLogger().debug("in run-about to enter while not interrupted loop"); + getLogger().debug(getName() + " doShutdown called"); - active = true; + // close the server socket + closeServerSocket(); - while (!rThread.isInterrupted()) { - // if we have a socket, start watching it - if (socket != null) { - getLogger().debug( - "socket not null - creating and starting socketnode"); - socketList.add(socket); - - SocketNode13 node = new SocketNode13(socket, this); - synchronized (listenerList) { - for (Object aListenerList : listenerList) { - SocketNodeEventListener l = - (SocketNodeEventListener) aListenerList; - node.addSocketNodeEventListener(l); - } - } - socketMap.put(socket, node); - new Thread(node).start(); - socket = null; - } + // close all of the accepted sockets + closeAllAcceptedSockets(); + } - getLogger().debug("waiting to accept socket"); + /** + * Closes the server socket, if created. + */ + private void closeServerSocket() { + getLogger().debug("{} closing server socket", getName()); + + try { + if (serverSocket != null) { + serverSocket.close(); + } + } catch (Exception e) { + // ignore for now + } - // wait for a socket to open, then loop to start it - socket = serverSocket.accept(); - getLogger().debug("accepted socket"); - } - } catch (Exception e) { - getLogger().warn( - "exception while watching socket server in SocketReceiver (" - + this.getName() + "), stopping"); + serverSocket = null; } - getLogger().debug("{} has exited the not interrupted loop", getName()); + /** + * Closes all the connected sockets in the List. + */ + private synchronized void closeAllAcceptedSockets() { + for (Object aSocketList : socketList) { + try { + ((Socket) aSocketList).close(); + } catch (Exception e) { + // ignore for now + } + } - // socket not watched because we a no longer running - // so close it now. - if (socket != null) { - try { - socket.close(); - } catch (IOException e1) { - getLogger().warn("socket exception caught - socket closed"); - } + // clear member variables + socketMap.clear(); + socketList.clear(); } - getLogger().debug("{} is exiting main run loop", getName()); - } + /** + * Sets the flag to indicate if receiver is active or not. + * + * @param b new value + */ + protected synchronized void setActive(final boolean b) { + active = b; + } - /** - * Returns a Vector of SocketDetail representing the IP/Domain name - * of the currently connected sockets that this receiver has - * been responsible for creating. - * @return Vector of SocketDetails - */ - public Vector<SocketDetail> getConnectedSocketDetails() { - Vector<SocketDetail> details = new Vector<>(socketList.size()); + public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) { + this.advertiseViaMulticastDNS = advertiseViaMulticastDNS; + } - for (Enumeration<Socket> enumeration = socketList.elements(); - enumeration.hasMoreElements(); - ) { - Socket socket = enumeration.nextElement(); - details.add( - new SocketDetail(socket, socketMap.get(socket))); + public boolean isAdvertiseViaMulticastDNS() { + return advertiseViaMulticastDNS; } - return details; - } - - /** - * Returns the currently configured SocketNodeEventListener that - * will be automatically set for each SocketNode created. - * @return SocketNodeEventListener currently configured - * - * @deprecated This receiver now supports multiple listeners - */ - public SocketNodeEventListener getListener() { - return listener; - } - - /** - * Adds the listener to the list of listeners to be notified of the - * respective event. - * @param l the listener to add to the list - */ - public void addSocketNodeEventListener( - final SocketNodeEventListener l) { - listenerList.add(l); - } - - /** - * Removes the registered Listener from this instances list of - * listeners. If the listener has not been registered, then invoking - * this method has no effect. - * - * @param l the SocketNodeEventListener to remove - */ - public void removeSocketNodeEventListener( - final SocketNodeEventListener l) { - listenerList.remove(l); - } - - /** - * Sets the SocketNodeEventListener that will be used for each - * created SocketNode. - * @param l the listener to set on each creation of a SocketNode - * @deprecated This receiver now supports multiple listeners and - * so this method simply removes the listener (if there already) - * and readds it to the list. - * - * The passed listener will also be returned via the getListener() - * method still, but this is also deprecated - */ - public void setListener(final SocketNodeEventListener l) { - removeSocketNodeEventListener(l); - addSocketNodeEventListener(l); - this.listener = l; - } - - /** {@inheritDoc} */ - public boolean isPaused() { - return paused; - } - - /** {@inheritDoc} */ - public void setPaused(final boolean b) { - paused = b; - } + /** + * Loop, accepting new socket connections. + */ + public void run() { + /** + * Ensure we start fresh. + */ + closeServerSocket(); + closeAllAcceptedSockets(); + + // start the server socket + try { + serverSocket = new ServerSocket(port); + } catch (Exception e) { + getLogger().error( + "error starting SocketReceiver (" + this.getName() + + "), receiver did not start", e); + active = false; + + return; + } + + Socket socket = null; + + try { + getLogger().debug("in run-about to enter while not interrupted loop"); + + active = true; + + while (!rThread.isInterrupted()) { + // if we have a socket, start watching it + if (socket != null) { + getLogger().debug( + "socket not null - creating and starting socketnode"); + socketList.add(socket); + + SocketNode13 node = new SocketNode13(socket, this); + synchronized (listenerList) { + for (Object aListenerList : listenerList) { + SocketNodeEventListener l = + (SocketNodeEventListener) aListenerList; + node.addSocketNodeEventListener(l); + } + } + socketMap.put(socket, node); + new Thread(node).start(); + socket = null; + } + + getLogger().debug("waiting to accept socket"); + + // wait for a socket to open, then loop to start it + socket = serverSocket.accept(); + getLogger().debug("accepted socket"); + } + } catch (Exception e) { + getLogger().warn( + "exception while watching socket server in SocketReceiver (" + + this.getName() + "), stopping"); + } + + getLogger().debug("{} has exited the not interrupted loop", getName()); + + // socket not watched because we a no longer running + // so close it now. + if (socket != null) { + try { + socket.close(); + } catch (IOException e1) { + getLogger().warn("socket exception caught - socket closed"); + } + } + + getLogger().debug("{} is exiting main run loop", getName()); + } /** - * Socket detail. + * Returns a Vector of SocketDetail representing the IP/Domain name + * of the currently connected sockets that this receiver has + * been responsible for creating. + * + * @return Vector of SocketDetails */ - private static final class SocketDetail implements AddressBased, PortBased, - Pauseable { - /** - * Address. - */ - private String address; - /** - * Port. - */ - private int port; - /** - * Socket node. - */ - private SocketNode13 socketNode; - - /** - * Create new instance. - * @param socket socket - * @param node socket node - */ - private SocketDetail(final Socket socket, - final SocketNode13 node) { - super(); - this.address = socket.getInetAddress().getHostName(); - this.port = socket.getPort(); - this.socketNode = node; + public Vector<SocketDetail> getConnectedSocketDetails() { + Vector<SocketDetail> details = new Vector<>(socketList.size()); + + for (Enumeration<Socket> enumeration = socketList.elements(); + enumeration.hasMoreElements(); + ) { + Socket socket = enumeration.nextElement(); + details.add( + new SocketDetail(socket, socketMap.get(socket))); + } + + return details; } - /** {@inheritDoc} */ - public String getAddress() { - return address; + /** + * Returns the currently configured SocketNodeEventListener that + * will be automatically set for each SocketNode created. + * + * @return SocketNodeEventListener currently configured + * @deprecated This receiver now supports multiple listeners + */ + public SocketNodeEventListener getListener() { + return listener; } - /** {@inheritDoc} */ - public int getPort() { - return port; + /** + * Adds the listener to the list of listeners to be notified of the + * respective event. + * + * @param l the listener to add to the list + */ + public void addSocketNodeEventListener( + final SocketNodeEventListener l) { + listenerList.add(l); } - /** {@inheritDoc} */ - public String getName() { - return "Socket"; + /** + * Removes the registered Listener from this instances list of + * listeners. If the listener has not been registered, then invoking + * this method has no effect. + * + * @param l the SocketNodeEventListener to remove + */ + public void removeSocketNodeEventListener( + final SocketNodeEventListener l) { + listenerList.remove(l); } - /** {@inheritDoc} */ - public boolean isActive() { - return true; + /** + * Sets the SocketNodeEventListener that will be used for each + * created SocketNode. + * + * @param l the listener to set on each creation of a SocketNode + * @deprecated This receiver now supports multiple listeners and + * so this method simply removes the listener (if there already) + * and readds it to the list. + * <p> + * The passed listener will also be returned via the getListener() + * method still, but this is also deprecated + */ + public void setListener(final SocketNodeEventListener l) { + removeSocketNodeEventListener(l); + addSocketNodeEventListener(l); + this.listener = l; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ public boolean isPaused() { - return socketNode.isPaused(); + return paused; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ public void setPaused(final boolean b) { - socketNode.setPaused(b); + paused = b; + } + + /** + * Socket detail. + */ + private static final class SocketDetail implements AddressBased, PortBased, + Pauseable { + /** + * Address. + */ + private String address; + /** + * Port. + */ + private int port; + /** + * Socket node. + */ + private SocketNode13 socketNode; + + /** + * Create new instance. + * + * @param socket socket + * @param node socket node + */ + private SocketDetail(final Socket socket, + final SocketNode13 node) { + super(); + this.address = socket.getInetAddress().getHostName(); + this.port = socket.getPort(); + this.socketNode = node; + } + + /** + * {@inheritDoc} + */ + public String getAddress() { + return address; + } + + /** + * {@inheritDoc} + */ + public int getPort() { + return port; + } + + /** + * {@inheritDoc} + */ + public String getName() { + return "Socket"; + } + + /** + * {@inheritDoc} + */ + public boolean isActive() { + return true; + } + + /** + * {@inheritDoc} + */ + public boolean isPaused() { + return socketNode.isPaused(); + } + + /** + * {@inheritDoc} + */ + public void setPaused(final boolean b) { + socketNode.setPaused(b); + } } - } - /** {@inheritDoc} */ - public void doPost(final LoggingEvent event) { - if (!isPaused()) { - super.doPost(event); + + /** + * {@inheritDoc} + */ + public void doPost(final LoggingEvent event) { + if (!isPaused()) { + super.doPost(event); + } } - } } http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/96ebd9ad/src/main/java/org/apache/log4j/net/UDPAppender.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/net/UDPAppender.java b/src/main/java/org/apache/log4j/net/UDPAppender.java index 896f145..81e97ea 100644 --- a/src/main/java/org/apache/log4j/net/UDPAppender.java +++ b/src/main/java/org/apache/log4j/net/UDPAppender.java @@ -5,9 +5,9 @@ * 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. @@ -19,8 +19,8 @@ package org.apache.log4j.net; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.helpers.Constants; -import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.xml.XMLLayout; import java.io.IOException; @@ -30,301 +30,300 @@ import java.net.InetAddress; import java.net.UnknownHostException; - /** - * Sends log information as a UDP datagrams. - * - * <p>The UDPAppender is meant to be used as a diagnostic logging tool - * so that logging can be monitored by a simple UDP client. - * - * <p>Messages are not sent as LoggingEvent objects but as text after - * applying the designated Layout. - * - * <p>The port and remoteHost properties can be set in configuration properties. - * By setting the remoteHost to a broadcast address any number of clients can - * listen for log messages. - * - * <p>This was inspired and really extended/copied from {@link SocketAppender}. - * Please see the docs for the proper credit to the authors of that class. + * Sends log information as a UDP datagrams. + * <p> + * <p>The UDPAppender is meant to be used as a diagnostic logging tool + * so that logging can be monitored by a simple UDP client. + * <p> + * <p>Messages are not sent as LoggingEvent objects but as text after + * applying the designated Layout. + * <p> + * <p>The port and remoteHost properties can be set in configuration properties. + * By setting the remoteHost to a broadcast address any number of clients can + * listen for log messages. + * <p> + * <p>This was inspired and really extended/copied from {@link SocketAppender}. + * Please see the docs for the proper credit to the authors of that class. * - * @author <a href="mailto:kbr...@versatilesolutions.com">Kevin Brown</a> - * @author Scott Deboy <sde...@apache.org> + * @author <a href="mailto:kbr...@versatilesolutions.com">Kevin Brown</a> + * @author Scott Deboy <sde...@apache.org> */ -public class UDPAppender extends AppenderSkeleton implements PortBased{ - /** - * The default port number for the UDP packets, 9991. - */ - public static final int DEFAULT_PORT = 9991; - - /** - We remember host name as String in addition to the resolved - InetAddress so that it can be returned via getOption(). - */ - String hostname; - String remoteHost; - String application; - String encoding; - InetAddress address; - int port = DEFAULT_PORT; - DatagramSocket outSocket; - - /** - * The MulticastDNS zone advertised by a UDPAppender - */ - public static final String ZONE = "_log4j_xml_udp_appender.local."; - - // if there is something irrecoverably wrong with the settings, there is no - // point in sending out packeets. - boolean inError = false; - private boolean advertiseViaMulticastDNS; - private ZeroConfSupport zeroConf; +public class UDPAppender extends AppenderSkeleton implements PortBased { + /** + * The default port number for the UDP packets, 9991. + */ + public static final int DEFAULT_PORT = 9991; + + /** + * We remember host name as String in addition to the resolved + * InetAddress so that it can be returned via getOption(). + */ + String hostname; + String remoteHost; + String application; + String encoding; + InetAddress address; + int port = DEFAULT_PORT; + DatagramSocket outSocket; + + /** + * The MulticastDNS zone advertised by a UDPAppender + */ + public static final String ZONE = "_log4j_xml_udp_appender.local."; + + // if there is something irrecoverably wrong with the settings, there is no + // point in sending out packeets. + boolean inError = false; + private boolean advertiseViaMulticastDNS; + private ZeroConfSupport zeroConf; public UDPAppender() { - super(false); - } - - /** - Sends UDP packets to the <code>address</code> and <code>port</code>. - */ - public UDPAppender(final InetAddress address, final int port) { - super(false); - this.address = address; - this.remoteHost = address.getHostName(); - this.port = port; - activateOptions(); - } - - /** - Sends UDP packets to the <code>address</code> and <code>port</code>. - */ - public UDPAppender(final String host, final int port) { - super(false); - this.port = port; - this.address = getAddressByName(host); - this.remoteHost = host; - activateOptions(); - } - - /** - Open the UDP sender for the <b>RemoteHost</b> and <b>Port</b>. - */ - public void activateOptions() { - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException uhe) { - try { - hostname = InetAddress.getLocalHost().getHostAddress(); - } catch (UnknownHostException uhe2) { - hostname = "unknown"; - } + super(false); } - //allow system property of application to be primary - if (application == null) { - application = System.getProperty(Constants.APPLICATION_KEY); - } else { - if (System.getProperty(Constants.APPLICATION_KEY) != null) { - application = application + "-" + System.getProperty(Constants.APPLICATION_KEY); - } + /** + * Sends UDP packets to the <code>address</code> and <code>port</code>. + */ + public UDPAppender(final InetAddress address, final int port) { + super(false); + this.address = address; + this.remoteHost = address.getHostName(); + this.port = port; + activateOptions(); } - if(remoteHost != null) { - address = getAddressByName(remoteHost); - connect(address, port); - } else { - String err = "The RemoteHost property is required for SocketAppender named "+ name; - LogLog.error(err); - throw new IllegalStateException(err); + /** + * Sends UDP packets to the <code>address</code> and <code>port</code>. + */ + public UDPAppender(final String host, final int port) { + super(false); + this.port = port; + this.address = getAddressByName(host); + this.remoteHost = host; + activateOptions(); } - if (layout == null) { - layout = new XMLLayout(); + /** + * Open the UDP sender for the <b>RemoteHost</b> and <b>Port</b>. + */ + public void activateOptions() { + try { + hostname = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException uhe) { + try { + hostname = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException uhe2) { + hostname = "unknown"; + } + } + + //allow system property of application to be primary + if (application == null) { + application = System.getProperty(Constants.APPLICATION_KEY); + } else { + if (System.getProperty(Constants.APPLICATION_KEY) != null) { + application = application + "-" + System.getProperty(Constants.APPLICATION_KEY); + } + } + + if (remoteHost != null) { + address = getAddressByName(remoteHost); + connect(address, port); + } else { + String err = "The RemoteHost property is required for SocketAppender named " + name; + LogLog.error(err); + throw new IllegalStateException(err); + } + + if (layout == null) { + layout = new XMLLayout(); + } + + if (advertiseViaMulticastDNS) { + zeroConf = new ZeroConfSupport(ZONE, port, getName()); + zeroConf.advertise(); + } + + super.activateOptions(); } - if (advertiseViaMulticastDNS) { - zeroConf = new ZeroConfSupport(ZONE, port, getName()); - zeroConf.advertise(); + /** + * Close this appender. + * <p>This will mark the appender as closed and + * call then {@link #cleanUp} method. + */ + public synchronized void close() { + if (closed) { + return; + } + + if (advertiseViaMulticastDNS) { + zeroConf.unadvertise(); + } + + this.closed = true; + cleanUp(); } - super.activateOptions(); - } - - /** - Close this appender. - <p>This will mark the appender as closed and - call then {@link #cleanUp} method. - */ - public synchronized void close() { - if (closed) { - return; + /** + * Close the UDP Socket and release the underlying + * connector thread if it has been created + */ + public void cleanUp() { + if (outSocket != null) { + try { + outSocket.close(); + } catch (Exception e) { + LogLog.error("Could not close outSocket.", e); + } + + outSocket = null; + } } - if (advertiseViaMulticastDNS) { - zeroConf.unadvertise(); + void connect(InetAddress address, int port) { + if (this.address == null) { + return; + } + + try { + // First, close the previous connection if any. + cleanUp(); + outSocket = new DatagramSocket(); + outSocket.connect(address, port); + } catch (IOException e) { + LogLog.error( + "Could not open UDP Socket for sending.", e); + inError = true; + } } - - this.closed = true; - cleanUp(); - } - - /** - Close the UDP Socket and release the underlying - connector thread if it has been created - */ - public void cleanUp() { - if (outSocket != null) { - try { - outSocket.close(); - } catch (Exception e) { - LogLog.error("Could not close outSocket.", e); - } - - outSocket = null; + + public void append(LoggingEvent event) { + if (inError) { + return; + } + + if (event == null) { + return; + } + + if (address == null) { + return; + } + + if (outSocket != null) { + event.setProperty(Constants.HOSTNAME_KEY, hostname); + if (application != null) { + event.setProperty(Constants.APPLICATION_KEY, application); + } + + try { + StringBuilder buf = new StringBuilder(layout.format(event)); + + byte[] payload; + if (encoding == null) { + payload = buf.toString().getBytes(); + } else { + payload = buf.toString().getBytes(encoding); + } + + DatagramPacket dp = + new DatagramPacket(payload, payload.length, address, port); + outSocket.send(dp); + } catch (IOException e) { + outSocket = null; + LogLog.warn("Detected problem with UDP connection: " + e); + } + } } - } - void connect(InetAddress address, int port) { - if (this.address == null) { - return; + public boolean isActive() { + return !inError; } - try { - // First, close the previous connection if any. - cleanUp(); - outSocket = new DatagramSocket(); - outSocket.connect(address, port); - } catch (IOException e) { - LogLog.error( - "Could not open UDP Socket for sending.", e); - inError = true; + InetAddress getAddressByName(String host) { + try { + return InetAddress.getByName(host); + } catch (Exception e) { + LogLog.error("Could not find address of [" + host + "].", e); + return null; + } } - } - public void append(LoggingEvent event) { - if(inError) { - return; + /** + * The UDPAppender uses layouts. Hence, this method returns + * <code>true</code>. + */ + public boolean requiresLayout() { + return true; } - - if (event == null) { - return; + + /** + * The <b>RemoteHost</b> option takes a string value which should be + * the host name or ipaddress to send the UDP packets. + */ + public void setRemoteHost(String host) { + remoteHost = host; } - if (address == null) { - return; + /** + * Returns value of the <b>RemoteHost</b> option. + */ + public String getRemoteHost() { + return remoteHost; } - if (outSocket != null) { - event.setProperty(Constants.HOSTNAME_KEY, hostname); - if (application != null) { - event.setProperty(Constants.APPLICATION_KEY, application); - } + /** + * The <b>App</b> option takes a string value which should be the name of the application getting logged. + * If property was already set (via system property), don't set here. + */ + public void setApplication(String app) { + this.application = app; + } - try { - StringBuilder buf = new StringBuilder(layout.format(event)); + /** + * Returns value of the <b>App</b> option. + */ + public String getApplication() { + return application; + } - byte[] payload; - if(encoding == null) { - payload = buf.toString().getBytes(); - } else { - payload = buf.toString().getBytes(encoding); - } + /** + * The <b>Encoding</b> option specifies how the bytes are encoded. If this option is not specified, + * the System encoding is used. + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } - DatagramPacket dp = - new DatagramPacket(payload, payload.length, address, port); - outSocket.send(dp); - } catch (IOException e) { - outSocket = null; - LogLog.warn("Detected problem with UDP connection: " + e); - } + /** + * Returns value of the <b>Encoding</b> option. + */ + public String getEncoding() { + return encoding; } - } - - public boolean isActive() { - return !inError; - } - - InetAddress getAddressByName(String host) { - try { - return InetAddress.getByName(host); - } catch (Exception e) { - LogLog.error("Could not find address of [" + host + "].", e); - return null; + + /** + * The <b>Port</b> option takes a positive integer representing + * the port where UDP packets will be sent. + */ + public void setPort(int port) { + this.port = port; } - } - - /** - The UDPAppender uses layouts. Hence, this method returns - <code>true</code>. - */ - public boolean requiresLayout() { - return true; - } - - /** - The <b>RemoteHost</b> option takes a string value which should be - the host name or ipaddress to send the UDP packets. - */ - public void setRemoteHost(String host) { - remoteHost = host; - } - - /** - Returns value of the <b>RemoteHost</b> option. - */ - public String getRemoteHost() { - return remoteHost; - } - - /** - The <b>App</b> option takes a string value which should be the name of the application getting logged. - If property was already set (via system property), don't set here. - */ - public void setApplication(String app) { - this.application = app; - } - - /** - Returns value of the <b>App</b> option. - */ - public String getApplication() { - return application; - } - - /** - The <b>Encoding</b> option specifies how the bytes are encoded. If this option is not specified, - the System encoding is used. - */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - Returns value of the <b>Encoding</b> option. - */ - public String getEncoding() { - return encoding; - } /** - The <b>Port</b> option takes a positive integer representing - the port where UDP packets will be sent. - */ - public void setPort(int port) { - this.port = port; - } - - /** - Returns value of the <b>Port</b> option. - */ - public int getPort() { - return port; - } - - public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) { - this.advertiseViaMulticastDNS = advertiseViaMulticastDNS; - } - - public boolean isAdvertiseViaMulticastDNS() { - return advertiseViaMulticastDNS; - } + * Returns value of the <b>Port</b> option. + */ + public int getPort() { + return port; + } + + public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) { + this.advertiseViaMulticastDNS = advertiseViaMulticastDNS; + } + + public boolean isAdvertiseViaMulticastDNS() { + return advertiseViaMulticastDNS; + } } http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/96ebd9ad/src/main/java/org/apache/log4j/net/UDPReceiver.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/net/UDPReceiver.java b/src/main/java/org/apache/log4j/net/UDPReceiver.java index fefab1e..ae990f7 100644 --- a/src/main/java/org/apache/log4j/net/UDPReceiver.java +++ b/src/main/java/org/apache/log4j/net/UDPReceiver.java @@ -5,9 +5,9 @@ * 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. @@ -17,6 +17,11 @@ package org.apache.log4j.net; +import org.apache.log4j.plugins.Pauseable; +import org.apache.log4j.plugins.Receiver; +import org.apache.log4j.spi.Decoder; +import org.apache.log4j.spi.LoggingEvent; + import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -24,253 +29,247 @@ import java.net.SocketException; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.plugins.Pauseable; -import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.Decoder; -import org.apache.log4j.spi.LoggingEvent; - /** - * Receive LoggingEvents encoded with an XMLLayout, convert the XML data to a - * LoggingEvent and post the LoggingEvent. - * - * @author Scott Deboy <sde...@apache.org> + * Receive LoggingEvents encoded with an XMLLayout, convert the XML data to a + * LoggingEvent and post the LoggingEvent. * + * @author Scott Deboy <sde...@apache.org> */ public class UDPReceiver extends Receiver implements PortBased, Pauseable { - private static final int PACKET_LENGTH = 16384; - private UDPReceiverThread receiverThread; - private String encoding; - - //default to log4j xml decoder - private String decoder = "org.apache.log4j.xml.XMLDecoder"; - private Decoder decoderImpl; - protected boolean paused; - private transient boolean closed = false; - private int port; - private DatagramSocket socket; - UDPHandlerThread handlerThread; - private boolean advertiseViaMulticastDNS; - private ZeroConfSupport zeroConf; - - /** - * The MulticastDNS zone advertised by a UDPReceiver - */ - public static final String ZONE = "_log4j_xml_udp_receiver.local."; + private static final int PACKET_LENGTH = 16384; + private UDPReceiverThread receiverThread; + private String encoding; + + //default to log4j xml decoder + private String decoder = "org.apache.log4j.xml.XMLDecoder"; + private Decoder decoderImpl; + protected boolean paused; + private transient boolean closed = false; + private int port; + private DatagramSocket socket; + UDPHandlerThread handlerThread; + private boolean advertiseViaMulticastDNS; + private ZeroConfSupport zeroConf; + + /** + * The MulticastDNS zone advertised by a UDPReceiver + */ + public static final String ZONE = "_log4j_xml_udp_receiver.local."; public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - /** - * The <b>Encoding</b> option specifies how the bytes are encoded. If this - * option is not specified, the system encoding will be used. - * */ - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - * Returns value of the <b>Encoding</b> option. - */ - public String getEncoding() { - return encoding; - } - - public String getDecoder() { - return decoder; - } - - public void setDecoder(String decoder) { - this.decoder = decoder; - } - - public boolean isPaused() { - return paused; - } - - public void setPaused(boolean b) { - paused = b; - } - - public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) { - this.advertiseViaMulticastDNS = advertiseViaMulticastDNS; - } - - public boolean isAdvertiseViaMulticastDNS() { - return advertiseViaMulticastDNS; - } - - public synchronized void shutdown() { - if(closed == true) { - return; + return port; + } + + public void setPort(int port) { + this.port = port; } - closed = true; - active = false; - // Closing the datagram socket will unblock the UDPReceiverThread if it is - // was waiting to receive data from the socket. - if (socket != null) { - socket.close(); + + /** + * The <b>Encoding</b> option specifies how the bytes are encoded. If this + * option is not specified, the system encoding will be used. + */ + public void setEncoding(String encoding) { + this.encoding = encoding; } - if (advertiseViaMulticastDNS) { - zeroConf.unadvertise(); + /** + * Returns value of the <b>Encoding</b> option. + */ + public String getEncoding() { + return encoding; } - - try { - if(handlerThread != null) { - handlerThread.close(); - handlerThread.join(); - } - if(receiverThread != null) { - receiverThread.join(); - } - } catch(InterruptedException ie) { + + public String getDecoder() { + return decoder; } - } - /** - Returns true if this receiver is active. */ -// public synchronized boolean isActive() { -// return isActive; -//} + public void setDecoder(String decoder) { + this.decoder = decoder; + } - public void activateOptions() { - try { - Class c = Class.forName(decoder); - Object o = c.newInstance(); - - if (o instanceof Decoder) { - this.decoderImpl = (Decoder) o; - } - } catch (ClassNotFoundException cnfe) { - getLogger().warn("Unable to find decoder", cnfe); - } catch (IllegalAccessException | InstantiationException iae) { - getLogger().warn("Could not construct decoder", iae); + public boolean isPaused() { + return paused; } - try { - socket = new DatagramSocket(port); - receiverThread = new UDPReceiverThread(); - receiverThread.start(); - handlerThread = new UDPHandlerThread(); - handlerThread.start(); - if (advertiseViaMulticastDNS) { - zeroConf = new ZeroConfSupport(ZONE, port, getName()); - zeroConf.advertise(); - } - active = true; - } catch (IOException ioe) { - ioe.printStackTrace(); + public void setPaused(boolean b) { + paused = b; } - } - class UDPHandlerThread extends Thread { - private final List<String> list = new ArrayList<>(); + public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) { + this.advertiseViaMulticastDNS = advertiseViaMulticastDNS; + } - public UDPHandlerThread() { - setDaemon(true); + public boolean isAdvertiseViaMulticastDNS() { + return advertiseViaMulticastDNS; } - public void append(String data) { - synchronized (list) { - list.add(data); - list.notify(); - } + public synchronized void shutdown() { + if (closed == true) { + return; + } + closed = true; + active = false; + // Closing the datagram socket will unblock the UDPReceiverThread if it is + // was waiting to receive data from the socket. + if (socket != null) { + socket.close(); + } + + if (advertiseViaMulticastDNS) { + zeroConf.unadvertise(); + } + + try { + if (handlerThread != null) { + handlerThread.close(); + handlerThread.join(); + } + if (receiverThread != null) { + receiverThread.join(); + } + } catch (InterruptedException ie) { + } } /** - * Allow the UDPHandlerThread to wakeup and exit gracefully. + * Returns true if this receiver is active. */ - void close() { - synchronized(list) { - list.notify(); - } +// public synchronized boolean isActive() { +// return isActive; +//} + public void activateOptions() { + try { + Class c = Class.forName(decoder); + Object o = c.newInstance(); + + if (o instanceof Decoder) { + this.decoderImpl = (Decoder) o; + } + } catch (ClassNotFoundException cnfe) { + getLogger().warn("Unable to find decoder", cnfe); + } catch (IllegalAccessException | InstantiationException iae) { + getLogger().warn("Could not construct decoder", iae); + } + + try { + socket = new DatagramSocket(port); + receiverThread = new UDPReceiverThread(); + receiverThread.start(); + handlerThread = new UDPHandlerThread(); + handlerThread.start(); + if (advertiseViaMulticastDNS) { + zeroConf = new ZeroConfSupport(ZONE, port, getName()); + zeroConf.advertise(); + } + active = true; + } catch (IOException ioe) { + ioe.printStackTrace(); + } } - public void run() { - ArrayList<String> list2 = new ArrayList<>(); + class UDPHandlerThread extends Thread { + private final List<String> list = new ArrayList<>(); - while (!UDPReceiver.this.closed) { - synchronized (list) { - try { - while (!UDPReceiver.this.closed && list.size() == 0) { - list.wait(300); + public UDPHandlerThread() { + setDaemon(true); + } + + public void append(String data) { + synchronized (list) { + list.add(data); + list.notify(); } + } - if (list.size() > 0) { - list2.addAll(list); - list.clear(); + /** + * Allow the UDPHandlerThread to wakeup and exit gracefully. + */ + void close() { + synchronized (list) { + list.notify(); } - } catch (InterruptedException ie) { - } } - if (list2.size() > 0) { + public void run() { + ArrayList<String> list2 = new ArrayList<>(); + + while (!UDPReceiver.this.closed) { + synchronized (list) { + try { + while (!UDPReceiver.this.closed && list.size() == 0) { + list.wait(300); + } + + if (list.size() > 0) { + list2.addAll(list); + list.clear(); + } + } catch (InterruptedException ie) { + } + } - for (Object aList2 : list2) { - String data = (String) aList2; - List<LoggingEvent> v = decoderImpl.decodeEvents(data); + if (list2.size() > 0) { - if (v != null) { + for (Object aList2 : list2) { + String data = (String) aList2; + List<LoggingEvent> v = decoderImpl.decodeEvents(data); + + if (v != null) { + + for (Object aV : v) { + if (!isPaused()) { + doPost((LoggingEvent) aV); + } + } + } + } - for (Object aV : v) { - if (!isPaused()) { - doPost((LoggingEvent) aV); + list2.clear(); + } else { + try { + synchronized (this) { + wait(1000); } + } catch (InterruptedException ie) { } } - } + } // while + getLogger().debug(UDPReceiver.this.getName() + "'s handler thread is exiting"); + } // run + } // UDPHandlerThread + + class UDPReceiverThread extends Thread { + public UDPReceiverThread() { + setDaemon(true); + } - list2.clear(); - } else { - try { - synchronized (this) { - wait(1000); + public void run() { + byte[] b = new byte[PACKET_LENGTH]; + DatagramPacket p = new DatagramPacket(b, b.length); + + while (!UDPReceiver.this.closed) { + try { + socket.receive(p); + + //this string constructor which accepts a charset throws an exception if it is + //null + if (encoding == null) { + handlerThread.append( + new String(p.getData(), 0, p.getLength())); + } else { + handlerThread.append( + new String(p.getData(), 0, p.getLength(), encoding)); + } + } catch (SocketException se) { + //disconnected + } catch (IOException ioe) { + ioe.printStackTrace(); + } } - } catch (InterruptedException ie) { - } - } - } // while - getLogger().debug(UDPReceiver.this.getName()+ "'s handler thread is exiting"); - } // run - } // UDPHandlerThread - - class UDPReceiverThread extends Thread { - public UDPReceiverThread() { - setDaemon(true); - } - - public void run() { - byte[] b = new byte[PACKET_LENGTH]; - DatagramPacket p = new DatagramPacket(b, b.length); - while (!UDPReceiver.this.closed) { - try { - socket.receive(p); - - //this string constructor which accepts a charset throws an exception if it is - //null - if (encoding == null) { - handlerThread.append( - new String(p.getData(), 0, p.getLength())); - } else { - handlerThread.append( - new String(p.getData(), 0, p.getLength(), encoding)); - } - } catch (SocketException se) { - //disconnected - } catch (IOException ioe) { - ioe.printStackTrace(); + //LogLog.debug(UDPReceiver.this.getName() + "'s thread is ending."); } - } - - //LogLog.debug(UDPReceiver.this.getName() + "'s thread is ending."); } - } } http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/96ebd9ad/src/main/java/org/apache/log4j/net/XMLSocketNode.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/net/XMLSocketNode.java b/src/main/java/org/apache/log4j/net/XMLSocketNode.java index 99d1fe0..f71b424 100644 --- a/src/main/java/org/apache/log4j/net/XMLSocketNode.java +++ b/src/main/java/org/apache/log4j/net/XMLSocketNode.java @@ -17,182 +17,185 @@ package org.apache.log4j.net; -import org.apache.log4j.*; +import org.apache.log4j.Logger; import org.apache.log4j.helpers.Constants; import org.apache.log4j.plugins.Receiver; -import org.apache.log4j.spi.*; +import org.apache.log4j.spi.ComponentBase; +import org.apache.log4j.spi.Decoder; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.LoggingEvent; import java.io.IOException; import java.io.InputStream; - import java.net.Socket; - import java.util.List; /** - Read {@link LoggingEvent} objects sent from a remote client using XML over - Sockets (TCP). These logging events are logged according to local - policy, as if they were generated locally. + * Read {@link LoggingEvent} objects sent from a remote client using XML over + * Sockets (TCP). These logging events are logged according to local + * policy, as if they were generated locally. + * <p> + * <p>For example, the socket node might decide to log events to a + * local file and also resent them to a second socket node. + * + * @author Scott Deboy <sde...@apache.org>; + * @since 0.8.4 + */ +public class XMLSocketNode extends ComponentBase implements Runnable { + Socket socket; + Receiver receiver; + Decoder decoder; + SocketNodeEventListener listener; + + /** + * Constructor for socket and logger repository. + */ + public XMLSocketNode( + String decoder, Socket socket, LoggerRepository hierarchy) { + this.repository = hierarchy; + try { + Class c = Class.forName(decoder); + Object o = c.newInstance(); + + if (o instanceof Decoder) { + this.decoder = (Decoder) o; + } + } catch (ClassNotFoundException cnfe) { + getLogger().warn("Unable to find decoder", cnfe); + } catch (IllegalAccessException | InstantiationException iae) { + getLogger().warn("Unable to construct decoder", iae); + } - <p>For example, the socket node might decide to log events to a - local file and also resent them to a second socket node. + this.socket = socket; + } - @author Scott Deboy <sde...@apache.org>; + /** + * Constructor for socket and reciever. + */ + public XMLSocketNode(String decoder, Socket socket, Receiver receiver) { + try { + Class c = Class.forName(decoder); + Object o = c.newInstance(); + + if (o instanceof Decoder) { + this.decoder = (Decoder) o; + } + } catch (ClassNotFoundException cnfe) { + getLogger().warn("Unable to find decoder", cnfe); + } catch (IllegalAccessException | InstantiationException iae) { + getLogger().warn("Unable to construct decoder", iae); + } - @since 0.8.4 -*/ -public class XMLSocketNode extends ComponentBase implements Runnable { - Socket socket; - Receiver receiver; - Decoder decoder; - SocketNodeEventListener listener; - - /** - Constructor for socket and logger repository. */ - public XMLSocketNode( - String decoder, Socket socket, LoggerRepository hierarchy) { - this.repository = hierarchy; - try { - Class c = Class.forName(decoder); - Object o = c.newInstance(); - - if (o instanceof Decoder) { - this.decoder = (Decoder) o; - } - } catch (ClassNotFoundException cnfe) { - getLogger().warn("Unable to find decoder", cnfe); - } catch (IllegalAccessException | InstantiationException iae) { - getLogger().warn("Unable to construct decoder", iae); + this.socket = socket; + this.receiver = receiver; } - this.socket = socket; - } - - /** - Constructor for socket and reciever. */ - public XMLSocketNode(String decoder, Socket socket, Receiver receiver) { - try { - Class c = Class.forName(decoder); - Object o = c.newInstance(); - - if (o instanceof Decoder) { - this.decoder = (Decoder) o; - } - } catch (ClassNotFoundException cnfe) { - getLogger().warn("Unable to find decoder", cnfe); - } catch (IllegalAccessException | InstantiationException iae) { - getLogger().warn("Unable to construct decoder", iae); + /** + * Set the event listener on this node. + */ + public void setListener(SocketNodeEventListener _listener) { + listener = _listener; } - this.socket = socket; - this.receiver = receiver; - } - - /** - Set the event listener on this node. */ - public void setListener(SocketNodeEventListener _listener) { - listener = _listener; - } - - public void run() { - Logger remoteLogger; - Exception listenerException = null; - InputStream is; - - if ((this.receiver == null) || (this.decoder == null)) { - listenerException = - new Exception( - "No receiver or decoder provided. Cannot process xml socket events"); - getLogger().error( - "Exception constructing XML Socket Receiver", listenerException); - } + public void run() { + Logger remoteLogger; + Exception listenerException = null; + InputStream is; + + if ((this.receiver == null) || (this.decoder == null)) { + listenerException = + new Exception( + "No receiver or decoder provided. Cannot process xml socket events"); + getLogger().error( + "Exception constructing XML Socket Receiver", listenerException); + } - try { - is = socket.getInputStream(); - } catch (Exception e) { - is = null; - listenerException = e; - getLogger().error("Exception opening ObjectInputStream to " + socket, e); - } + try { + is = socket.getInputStream(); + } catch (Exception e) { + is = null; + listenerException = e; + getLogger().error("Exception opening ObjectInputStream to " + socket, e); + } - if (is != null) { - String hostName = socket.getInetAddress().getHostName(); - String remoteInfo = hostName + ":" + socket.getPort(); - - try { - //read data from the socket - //it's up to the individual decoder to handle incomplete event data - while (true) { - byte[] b = new byte[1024]; - int length = is.read(b); - if (length == -1) { - getLogger().info( - "no bytes read from stream - closing connection."); - break; - } - List<LoggingEvent> v = decoder.decodeEvents(new String(b, 0, length)); - - if (v != null) { - - for (Object aV : v) { - LoggingEvent e = (LoggingEvent) aV; - e.setProperty(Constants.HOSTNAME_KEY, hostName); - - // store the known remote info in an event property - e.setProperty("log4j.remoteSourceInfo", remoteInfo); - - // if configured with a receiver, tell it to post the event - if (receiver != null) { - receiver.doPost(e); - - // else post it via the hierarchy - } else { - // get a logger from the hierarchy. The name of the logger - // is taken to be the name contained in the event. - remoteLogger = repository.getLogger(e.getLoggerName()); - - //event.logger = remoteLogger; - // apply the logger-level filter - if ( - e.getLevel().isGreaterOrEqual( - remoteLogger.getEffectiveLevel())) { - // finally log the event as if was generated locally - remoteLogger.callAppenders(e); - } - } - } - } + if (is != null) { + String hostName = socket.getInetAddress().getHostName(); + String remoteInfo = hostName + ":" + socket.getPort(); + + try { + //read data from the socket + //it's up to the individual decoder to handle incomplete event data + while (true) { + byte[] b = new byte[1024]; + int length = is.read(b); + if (length == -1) { + getLogger().info( + "no bytes read from stream - closing connection."); + break; + } + List<LoggingEvent> v = decoder.decodeEvents(new String(b, 0, length)); + + if (v != null) { + + for (Object aV : v) { + LoggingEvent e = (LoggingEvent) aV; + e.setProperty(Constants.HOSTNAME_KEY, hostName); + + // store the known remote info in an event property + e.setProperty("log4j.remoteSourceInfo", remoteInfo); + + // if configured with a receiver, tell it to post the event + if (receiver != null) { + receiver.doPost(e); + + // else post it via the hierarchy + } else { + // get a logger from the hierarchy. The name of the logger + // is taken to be the name contained in the event. + remoteLogger = repository.getLogger(e.getLoggerName()); + + //event.logger = remoteLogger; + // apply the logger-level filter + if ( + e.getLevel().isGreaterOrEqual( + remoteLogger.getEffectiveLevel())) { + // finally log the event as if was generated locally + remoteLogger.callAppenders(e); + } + } + } + } + } + } catch (java.io.EOFException e) { + getLogger().info("Caught java.io.EOFException closing connection."); + listenerException = e; + } catch (java.net.SocketException e) { + getLogger().info( + "Caught java.net.SocketException closing connection."); + listenerException = e; + } catch (IOException e) { + getLogger().info("Caught java.io.IOException: " + e); + getLogger().info("Closing connection."); + listenerException = e; + } catch (Exception e) { + getLogger().error("Unexpected exception. Closing connection.", e); + listenerException = e; + } } - } catch (java.io.EOFException e) { - getLogger().info("Caught java.io.EOFException closing connection."); - listenerException = e; - } catch (java.net.SocketException e) { - getLogger().info( - "Caught java.net.SocketException closing connection."); - listenerException = e; - } catch (IOException e) { - getLogger().info("Caught java.io.IOException: " + e); - getLogger().info("Closing connection."); - listenerException = e; - } catch (Exception e) { - getLogger().error("Unexpected exception. Closing connection.", e); - listenerException = e; - } - } - // close the socket - try { - if (is != null) { - is.close(); - } - } catch (Exception e) { - //logger.info("Could not close connection.", e); - } + // close the socket + try { + if (is != null) { + is.close(); + } + } catch (Exception e) { + //logger.info("Could not close connection.", e); + } - // send event to listener, if configured - if (listener != null) { - listener.socketClosedEvent(listenerException); + // send event to listener, if configured + if (listener != null) { + listener.socketClosedEvent(listenerException); + } } - } }