Issue Details (XML | Word | Printable)

Key: LOGCXX-7
Type: Improvement Improvement
Status: Resolved Resolved
Resolution: Fixed
Priority: Minor Minor
Assignee: Michaël CATANZARITI
Reporter: Curt Arnold
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Log4cxx

SocketAppender binary format not compatible with Chainsaw

Created: 10/Aug/04 04:43 PM   Updated: 26/Jan/08 03:14 AM
Return to search
Component/s: Appender
Affects Version/s: 0.9.7
Fix Version/s: 0.10.0

Time Tracking:
Not Specified

Resolution Date: 26/Jan/08 03:14 AM


 Description  « Hide
Chainsaw can process debug events sent by the socket appender from log4j (using Java serialization), however log4net and log4cxx implementations of SocketAppender do not create compatible byte streams. It would be an improvement if both log4net and log4cxx produced streams compatible with log4j. It is possible, but not likely, that there are listeners for the existing formats that would be broken with such a change.

Chainsaw is compatible with XMLSocketAppender.

Thread starting at: http://nagoya.apache.org/eyebrowse/ReadMsg?listName=log4cxx-user@logging.apache.org&msgNo=155

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Curt Arnold added a comment - 22/Dec/04 02:20 PM
http://nagoya.apache.org/eyebrowse/ReadMsg?listName=log4cxx-user@logging.apache.org&msgNo=612

Hi,

After a little bit of struggling we succeeded in building
0.9.7 on the tru64 using the compaq cxx compiler. However,
we now run into a runtime problem.

Using the DelayedLoop example and the simple socket server
on the same platform works fine. However, if we run the
DelayedLoop example on windows and the simple socket server
on tru64 it does not work. DeleyedLoop does succeed in
establishing a connection with the socket server, however
no messages arrive (also no error reports on either
side). We suspect something like an 32 bits integer is written
and a 64 bits integer is read. Could this be the case? If
so, will this still be the case in the next release?

After some poking around (in CVS head) I discovered that
the SocketOutputStream class uses plain int, long and
unsigned int types for writing data to the socket.
Shouldn't this be some kind of platform safe types?

How is this best fixed?

Curt Arnold added a comment - 20/Nov/07 08:28 PM
The following is an analysis for the tests/witness/serialization files in log4j 1.2 based from http://java.sun.com/javase/6/docs/platform/serialization/spec/protocol.html. The newHandle production in the spec doesn't seem to appear in the serialized form, either I'm misinterpreting it or it is a bug in the spec.

Analysis of simple.bin

AC ED == Stream magic
00 05 == Stream version

73 == TC_OBJECT, start of newObject
72 == TC_CLASSDESC, start of newClassDesc
00 21 == "org.apache.log4j.spi.LoggingEvent".length()
6F 72 ... 6E 74 == "org.apache.log4j.spi.LoggingEvent"
F3 F2 B9 23 74 0B B5 3F == LoggingEvent.serialVersionUID
newHandle should appear here
03 == classDescFlags of SC_WRITE_METHOD | SC_SERIALIZABLE
00 0A == fields.length()
5A == prim_typecode for boolean 'Z'
00 15 == "mdcCopyLookupRequired".length()
6D 64 ... 65 64 == "mdcCopyLookupRequired"
5A == boolean field 'Z'
00 01 == "ndcLookupRequired".length()
6E 64 ... 65 64 == "ndcLookupRequired"
4A == prim_typecode for long 'J'
00 09 == "timeStamp".length
74 69 ... 70 == "timeStamp"
4C == obj_typecode 'L'
00 0C == "categoryName".length
63 61 ... 6D 65 == "categoryName"
74 == TC_STRING?
00 12 == "Ljava/lang/String;".length
4C 6A ... 63 67 3B == "Ljava/lang/String;"
4C == obj_typecode 'L'
00 0C == "locationInfo".length
6C 6F ... 66 6F == "locationInfo"
74 == TC_STRING?
00 23 == "Lorg/apache/log4j/spi/LocationInfo;"
4C 6F ... 3B == "Lorg/.../LocationInfo;"
4C == obj_typecode 'L'
00 07 == "mdcCopy".length
6D 64 ... 79 74 == "mdcCopy"
74 == TC_STRING
00 15 == "Ljava/util/Hashtable;"
4C 6A ... 3B == "Ljava/util/Hashtable;"
4C == obj_typecode 'L'
00 03 == "ndc".length
6E 64 63 == "ndc"
71 == TC_REFERENCE
00 7E 00 01 == handle to second serialized field (looks like shortcut to String)
4C == obj_typecode 'L'
00 0F == "renderedMessage".length()
72 65 ... 67 65 == "renderedMessage"
71 == TC_REFERENCE
00 7E 00 01 == shortcut to String
4C == obj_typecode 'L'
00 0A == "threadName".length()
74 68 ... 6D 65 == "threadName"
71 == TC_REFERENCE
00 7E 00 01 - string shortcut
4C == obj_typecode 'L'
00 0D == "throwableInfo".length
74 68 ... 66 6F == "throwableInfo"
74 == TC_STRING
00 2B == "Lorg/apache/log4j/ThrowableInformation;".length()
4C 6F ... 6E 3B == "Lorg/apache/log4j/ThrowableInformation;"
78 == TC_ENDBLOCKDATA (no class annotation)
70 == TC_NULL (no superClassDesc, LoggingEvent extends Object)

Content from 0000-015A appears to be fixed

Fields in order of class descriptor
00 == mdcCopyLookupRequired
00 == ndcLookupRequired
00 00 01 05 26 1C EB 0C == timeStamp
74 00 04 72 6F 6F 74 == categoryName: TC_STRING "root".length() "root"
70 == locationInfo : TC_NULL
70 == mdcCopy : TC_NULL
70 == ndc : TC_NULL
74 00 0D 48 65 ... 64 2E == renderedMessage: TC_STRING "Hello, world.".length() "Hello, World"
74 00 04 6D 61 69 6E == threadName: TC_STRING "main".length() "main"
70 == throwableInfo: TC_NULL

Level is written by LoggingEvent.writeObject after default serialization

77 == TC_BLOCKDATA
04 size
00 00 4E 20 - Level.INFO
70 == TC_NULL - indicates using standard log4j Level class
78 == TC_ENDBLOCKDATA

-----------
Analysis of location.bin

Content from 0000-015A appears to be fixed per analysis in simple.bin.analysis

Fields in order of class descriptor
00 == mdcCopyLookupRequired
00 == ndcLookupRequired
00 00 01 05 26 1F FD D5 == timeStamp
74 00 04 72 6F 6F 74 == categoryName: TC_STRING "root".length() "root"

locationInfo follows (simple was TC_NULL == 0x70)

73 == TC_OBJECT
72 == TC_CLASSDESC
00 21 == "org.apache.log4j.spi.LocationInfo".length()
6F 72 ... 6F == "org.apache.log4j.spi.LocationInfo"
ED 99 BB E1 4A 91 A5 72 == serialVersionID
02 == classDescFlags: SC_SERIALIZABLE
00 01 == fields.length()
4C == obj_typecode 'L'
00 08 == "fullInfo".length()
66 75 ... 66 6F == "fullInfo"
71 == TC_REFERENCE
00 7E 00 01 == shortcut to String
78 == TC_ENDBLOCKDATA (no class annotation)
70 == TC_NULL (no superclass)
70 == TC_NULL (location determination failed due to flaw in test, would expect to be TC_STRING length data)
70 == mdcCopy : TC_NULL

rest follows simple.bin

--------------

Analysis of ndc.bin


Content from 0000-015A appears to be fixed per analysis in simple.bin.analysis

Fields in order of class descriptor
00 == mdcCopyLookupRequired
00 == ndcLookupRequired
00 00 01 05 26 21 85 35 == timeStamp
74 00 04 72 6F 6F 74 == categoryName: TC_STRING "root".length() "root"
70 == locationInfo : TC_NULL
70 == mdcCopy : TC_NULL
74 == TC_STRING
00 08 == "ndc test".length()
6E 64 ... 73 74 == "ndc test"
74 00 0D 48 65 ... 64 2E == renderedMessage: TC_STRING "Hello, world.".length() "Hello, World"

rest follows simple.bin


------

Analysis of mdc.bin

Content from 0000-015A appears to be fixed per analysis in simple.bin.analysis

Fields in order of class descriptor
00 == mdcCopyLookupRequired
00 == ndcLookupRequired
00 00 01 05 26 21 E9 E1 == timeStamp
74 00 04 72 6F 6F 74 == categoryName: TC_STRING "root".length() "root"
70 == locationInfo : TC_NULL
73 == TC_OBJECT
72 == TC_CLASSDESC
00 13 == "java.util.Hashtable".length()
6A 61 ... 6C 65 == "java.util.Hashtable"
13 BB 0F 25 21 4A E4 B8 == serialVersionID
03 == classDescFlags: SC_SERIALIZABLE | SC_WRITE_OBJECT
00 02== fields.length()
46 == prim_typecode 'F' float
00 0A == "loadFactor".length()
6C 6F ... 6F 72 == "loadFactor"
49 == prim_typecode 'I' integer
00 09 == "threshold".length()
74 68 ... 6F 6C== "threshold"
78 == TC_ENDBLOCKDATA (no class annotation)
70 == TC_NULL (no superclass)
3F 40 00 00 == 0.75
00 00 00 05 == 5
77 == TC_BLOCKDATA
08 == size
00 00 00 07 == buckets.length()
00 00 00 01 == length
74 == TC_STRING
00 06 == "mdckey".length()
6D 64 63 6B 65 79 == "mdckey"
74 == TC_STRING
00 08 == "mdcvalue".length()
6D 64 63 .. 65 == "mdcvalue"
78 == TC_ENDBLOCKDATA
74 == TC_STRING
00 08 == "ndc test".length()
6E 64 ... 73 74 == "ndc test"
74 00 0D 48 65 ... 64 2E == renderedMessage: TC_STRING "Hello, world.".length() "Hello, World"

rest follows simple.bin