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 Peter Kraft <pe...@oskrafts.org> on 2007/03/22 19:07:42 UTC

Proposed Change to LoggingEvent.java

Hi Guys,

Due to a requirement for a project I am working on, we recently made a small change to the log4j source file spi/LoggingEvent.java.  We needed to pass in custom message objects when creating a log event, log those events over the SocketAppender, and write custom Appenders to deal with our objects on the other end of that socket.  Currently, because the LoggingEvent object can't guarantee that message objects are Serializable, it renders them as Strings upon Serialization.  In order to keep our custom objects intact, we added code to check, during Serialization, to see if a message object is Serializable.  If it is, a reference to that object is stored in a non-transient field during serialization, and restored to it's original field upon deserialization.

So, in the interest of giving back, would the log4j team be open to incorporating this idea in the official distribution?  This change could benefit anyone using SocketAppenders (or anyone serializing LoggingEvent objects for that matter) who doesn't want to render their logs as Strings prematurely.  As far as I can tell, there is no down side to this solution, since non-serializable objects are still treated in the same way as before.  I am using log4j version 1.2.14, but if there is interest, I can make a similar change to the latest development code base.  Below is a patch for spi/LoggingEvent.java version 1.2.14.

Thanks,
Peter


--- LoggingEvent.java.orig	2007-03-21 18:58:50.000000000 -0400
+++ LoggingEvent.java	2007-03-21 12:18:28.000000000 -0400
@@ -23,6 +23,7 @@
 import java.lang.reflect.Method;
 import java.io.ObjectOutputStream;
 import java.io.ObjectInputStream;
+import java.io.Serializable;
 import java.util.Hashtable;
 
 // Contributors:   Nelson Minar <ne...@monkey.org>
@@ -106,6 +107,9 @@
   /** The application supplied message of logging event. */
   transient private Object message;
 
+  /** A non-transient place holder for the message Object for serialization. */
+  private Serializable serializableMessage;
+
   /** The application supplied message rendered through the log4j
       objet rendering mechanism.*/
   private String renderedMessage;
@@ -377,6 +381,9 @@
   private void readObject(ObjectInputStream ois)
                         throws java.io.IOException, ClassNotFoundException {
     ois.defaultReadObject();
+    if(serializableMessage != null) {
+      message = serializableMessage;
+    }
     readLevel(ois);
 
     // Make sure that no location info is available to Layouts
@@ -390,8 +397,13 @@
     // method sets the threadName variable.
     this.getThreadName();
 
-    // This sets the renders the message in case it wasn't up to now.
-    this.getRenderedMessage();
+    // If the message can be serialized, save it off in a non-transient field.
+    // If not, this renders the message in case it wasn't up to now.
+    if(message instanceof Serializable) {
+      serializableMessage = (Serializable)message;
+    } else {
+      this.getRenderedMessage();
+    }
 
     // This call has a side effect of setting this.ndc and
     // setting ndcLookupRequired to false if not already false.

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