You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ca...@apache.org on 2007/04/12 19:07:47 UTC

svn commit: r528040 - in /logging/sandbox/log4j/receivers/src/main/java/org/apache/log4j/net: SocketHubReceiver.java SocketNode.java

Author: carnold
Date: Thu Apr 12 10:07:46 2007
New Revision: 528040

URL: http://svn.apache.org/viewvc?view=rev&rev=528040
Log:
Bug 42102: Make SocketNode inner class to avoid conflict with 1.2's implementation

Removed:
    logging/sandbox/log4j/receivers/src/main/java/org/apache/log4j/net/SocketNode.java
Modified:
    logging/sandbox/log4j/receivers/src/main/java/org/apache/log4j/net/SocketHubReceiver.java

Modified: logging/sandbox/log4j/receivers/src/main/java/org/apache/log4j/net/SocketHubReceiver.java
URL: http://svn.apache.org/viewvc/logging/sandbox/log4j/receivers/src/main/java/org/apache/log4j/net/SocketHubReceiver.java?view=diff&rev=528040&r1=528039&r2=528040
==============================================================================
--- logging/sandbox/log4j/receivers/src/main/java/org/apache/log4j/net/SocketHubReceiver.java (original)
+++ logging/sandbox/log4j/receivers/src/main/java/org/apache/log4j/net/SocketHubReceiver.java Thu Apr 12 10:07:46 2007
@@ -18,15 +18,22 @@
 package org.apache.log4j.net;
 
 import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.BufferedInputStream;
 import java.net.Socket;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.lang.reflect.Method;
 
 import org.apache.log4j.plugins.Plugin;
 import org.apache.log4j.plugins.Receiver;
+import org.apache.log4j.plugins.Pauseable;
 import org.apache.log4j.spi.LoggerRepository;
+import org.apache.log4j.spi.ComponentBase;
+import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.Logger;
 
 /**
   SocketHubReceiver receives a remote logging event on a configured
@@ -388,5 +395,293 @@
 
     // This method does nothing.
   }
+
+    /**
+       Read {@link org.apache.log4j.spi.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.
+
+        This class is a replica of org.apache.log4j.net.SocketNode
+        from log4j 1.3 which is substantially different from
+        the log4j 1.2 implementation.  The class was made a
+        member of SocketHubReceiver to avoid potential collisions.
+
+        @author  Ceki G&uuml;lc&uuml;
+        @author  Paul Smith (psmith@apache.org)
+    */
+    private static final class SocketNode
+            extends ComponentBase implements Runnable, Pauseable {
+
+        /**
+         * Paused state.
+         */
+      private boolean paused;
+        /**
+         * Socket.
+         */
+      private Socket socket;
+        /**
+         * Receiver.
+         */
+      private Receiver receiver;
+        /**
+         * List of listeners.
+         */
+      private List listenerList = Collections.synchronizedList(new ArrayList());
+
+        /**
+         * Method descriptor for LoggingEvent.setProperty
+         *   which does not exist in log4j 1.2.14.
+         */
+      private static final Method LOGGING_EVENT_SET_PROPERTY =
+              getLoggingEventSetProperty();
+
+        /**
+         * Get method descriptor for LoggingEvent.setProperty
+         *   which does not exist in log4j 1.2.14.
+         * @return method descriptor or null if not supported.
+         */
+      private static Method getLoggingEventSetProperty() {
+          Method m = null;
+          try {
+              m = LoggingEvent.class.getMethod("setProperty",
+                              new Class[] {
+                                      String.class, String.class
+                              });
+          } catch (NoSuchMethodException e) {
+              return null;
+          }
+          return m;
+      }
+
+      /**
+        Constructor for socket and logger repository.
+       @param s socket
+       @param hierarchy logger repository
+       */
+      public SocketNode(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 SocketNode(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);
+      }
+
+        /**
+         * Set property in event.
+         * @param event event, may not be null.
+         * @param propName property name
+         * @param propValue property value
+         * @return true if property was set
+         */
+      private static boolean setEventProperty(
+              final LoggingEvent event,
+              final String propName,
+              final String propValue) {
+          if (LOGGING_EVENT_SET_PROPERTY != null) {
+              try {
+                  LOGGING_EVENT_SET_PROPERTY.invoke(event,
+                          new Object[] {
+                                  propName, propValue
+                          });
+                  return true;
+              } catch (Exception e) {
+                  return false;
+              }
+          }
+          return false;
+      }
+
+        /**
+         * Deserialize events from socket until interrupted.
+         */
+      public void run() {
+        LoggingEvent event;
+        Logger remoteLogger;
+        Exception listenerException = null;
+        ObjectInputStream ois = null;
+
+        try {
+          ois =
+            new ObjectInputStream(
+              new BufferedInputStream(socket.getInputStream()));
+        } catch (Exception e) {
+          ois = null;
+          listenerException = e;
+          getLogger().error(
+                  "Exception opening ObjectInputStream to " + socket, e);
+        }
+
+        if (ois != null) {
+          String remoteInfo =
+            socket.getInetAddress().getHostName() + ":" + socket.getPort();
+
+          /**
+           * notify the listener that the socket has been
+           * opened and this SocketNode is ready and waiting
+           */
+          fireSocketOpened(remoteInfo);
+
+          try {
+            while (true) {
+              // read an event from the wire
+              event = (LoggingEvent) ois.readObject();
+
+              // store the known remote info in an event property
+              setEventProperty(event, "log4j.remoteSourceInfo", remoteInfo);
+
+              // if configured with a receiver, tell it to post the event
+              if (!isPaused()) {
+                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;
+          }
+        }
+
+        // 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) {
+          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 (Iterator iter = listenerList.iterator(); iter.hasNext();) {
+                SocketNodeEventListener snel =
+                        (SocketNodeEventListener) iter.next();
+                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 (Iterator iter = listenerList.iterator(); iter.hasNext();) {
+                SocketNodeEventListener snel =
+                        (SocketNodeEventListener) iter.next();
+                if (snel != null) {
+                    snel.socketOpened(remoteInfo);
+                }
+            }
+        }
+      }
+
+        /**
+         * Sets if node is paused.
+         * @param b new value
+         */
+      public void setPaused(final boolean b) {
+        this.paused = b;
+      }
+
+        /**
+         * Get if node is paused.
+         * @return true if pause.
+         */
+      public boolean isPaused() {
+        return this.paused;
+      }
+    }
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org