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 bu...@apache.org on 2007/04/02 22:04:51 UTC

DO NOT REPLY [Bug 42023] New: - LoggingEvent Message Object is lost upon serialization

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=42023>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=42023

           Summary: LoggingEvent Message Object is lost upon serialization
           Product: Log4j
           Version: 1.2
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Other
        AssignedTo: log4j-dev@logging.apache.org
        ReportedBy: peter@oskrafts.org


When a LoggingEvent object is serialized, the message object is lost.  This is
because the message object is a transient field, so it is rendered as a String
upon Serialization.

I am submitting this as a bug, instead of a feature request, because the current
functionality is broken when using custom objects and certain combinations of
Appenders.  If I use only a database Appender with a custom object, I can insert
all of the custom log data into the correct database fields with correct types.
 If I use a SocketAppender followed by a file Appender, I can render all of my
log data properly in the file.  However, if I use a SocketAppender followed by
my database Appender, the current log4j will not allow me to access all of the
data in a custom object to insert them into the correct database fields.  A
correct implementation should allow Appenders to function in the same way
regardless of whether they are called on a machine generating log events or a
machine collecting log events.

The other solution, which I find less desirable, would be to change the API to
allow only logging of Strings, and not Objects.  Being able to use custom
objects as log events is very valuable, as it allows for logging application
specific details such as IP address, username, application version, and much
much more.

I created a patch to spi/LoggingEvent.java in log4j version 1.2.14.  The basic
idea is that if the message object implements Serializable, it is stored in a
non-transient field.  If the object is not serializable, the functionality is
unchanged.  I can create a similar patch for the latest development version if
that is desirable.


--- LoggingEvent.java.orig	2007-03-21 18:58:50.000000000 -0400
+++ LoggingEvent.java	2007-04-02 14:14:19.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 serialized message Object. */
+  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
@@ -386,6 +393,11 @@
 
   private
   void writeObject(ObjectOutputStream oos) throws java.io.IOException {
+    // If the message can be serialized, save it off in a non-transient field.
+    if(message instanceof Serializable) {
+      serializableMessage = (Serializable)message;
+    }
+
     // Aside from returning the current thread name the wgetThreadName
     // method sets the threadName variable.
     this.getThreadName();

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

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


DO NOT REPLY [Bug 42023] - LoggingEvent Message Object is lost upon serialization

Posted by bu...@apache.org.
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=42023>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=42023


peter@oskrafts.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEEDINFO                    |ASSIGNED




------- Additional Comments From peter@oskrafts.org  2007-08-28 10:18 -------
To clarify the original submission, the later scenario from above is what I am
referring to.  I believe it is a design flaw for the log4j paradigm to fall
apart when LoggingEvents are serialized.  Log4j should either cause serialized
message objects to be reconstituted when a LoggingEvent is deserialized (which
is what my patch accomplishes), or should refuse to allow logging of arbitrary
message objects.

I understand the need for keeping the SocketAppender and SocketReceiver
unchanged, but the sample patch I submitted should accomplish the intended
purpose while being completely transparent to the rest of the log4j codebase,
including any Appenders.

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

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


DO NOT REPLY [Bug 42023] - LoggingEvent Message Object is lost upon serialization

Posted by bu...@apache.org.
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=42023>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=42023


carnold@apache.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |NEEDINFO




------- Additional Comments From carnold@apache.org  2007-08-21 15:27 -------
I'm unclear whether you are saying the SocketAppender corrupts the original LoggingEvent so that other 
appenders can't access the original message object.  Basically, that you have a log4j configuration with a 
SocketAppender and your custom DBAppender and your DBAppender stops working when the 
SocketAppender is added. I reviewed the code and didn't see a mechanism for that to happen, but maybe I 
missed something.

If you are saying that a deserialized LoggingEvent (perhaps reconstituted by a SocketReceiver) is missing 
the original message, that is by design and would have to wait until 1.2.16 to be looked at since it would 
change the wire format for SocketAppender.

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

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