Re: log4j socket appender
On 9/19/2014 4:34 PM, doug.farrell@gmail.com wrote:
Hi all,
I'm not a Java developer (work primarily in Python and JavaScript), but I need some help. I've written a logging server that handles log records sent via UDP, and I'd like to do the same thing with Java. I've got a Java test harness built that looks like this:
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class HelloWorld {
/* get an actual logger */
private static final Logger logger = LogManager.getLogger("HelloWorld");
public static void main(String[] args) {
logger.info("Info level message");
}
}
and has a log4j.xml configuration file that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<Socket name="SOCKET" host="localhost" port="9023" protocol="UDP">
<SerializedLayout />
</Socket>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="SOCKET"/>
</Root>
</Loggers>
</Configuration>
This works and sends log records from the Java test program to my Python logging server. However, I can't figure out what the format of the data received by the Python logging server is? This is the data I get back in my handler:
'\xac\xed\x00\x05sr\x00>org.apache.logging.log4j.core.impl.Log4jLogEvent$LogEventProxy\x9c\xed\x0f]p\xda*\x16\x02\x00\rZ\x00\x0cisEndOfBatchZ\x00\x12isLocationRequiredJ\x00\ntimeMillisL\x00\ncontextMapt\x00\x0fLjava/util/Map;L\x00\x0ccontextStackt\x005Lorg/apache/logging/log4j/ThreadContext$ContextStack;L\x00\x05levelt\x00 Lorg/apache/logging/log4j/Level;L\x00\nloggerFQCNt\x00\x12Ljava/lang/String;L\x00\nloggerNameq\x00~\x00\x04L\x00\x06markert\x00!Lorg/apache/logging/log4j/Marker;L\x00\x07messaget\x00*Lorg/apache/logging/log4j/message/Message;L\x00\x06sourcet\x00\x1dLjava/lang/StackTraceElement;L\x00\nthreadNameq\x00~\x00\x04L\x00\x0bthrownProxyt\x003Lorg/apache/logging/log4j/core/impl/ThrowableProxy;xp\x00\x01\x00\x00\x01H\x8f\x9d\xfb>sr\x00\x1ejava.util.Collections$EmptyMapY6\x14\x85Z\xdc\xe7\xd0\x02\x00\x00xpsr\x00>org.apache.logging.log4j.ThreadContext$EmptyThreadContextStack\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00xpsr\x00\x1eorg.apache.logging.log4j.Level\x00\x00\x00\x00
\x00\x18 \x1a\x02\x00\x03I\x00\x08intLevelL\x00\x04nameq\x00~\x00\x04L\x00\rstandardLevelt\x00,Lorg/apache/logging/log4j/spi/StandardLevel;xp\x00\x00\x01\x90t\x00\x04INFO~r\x00*org.apache.logging.log4j.spi.StandardLevel\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00xr\x00\x0ejava.lang.Enum\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00xpt\x00\x04INFOt\x00+org.apache.logging.log4j.spi.AbstractLoggert\x00\nHelloWorldpsr\x00.org.apache.logging.log4j.message.SimpleMessage\x8btM0`\xb7\xa2\xa8\x02\x00\x01L\x00\x07messageq\x00~\x00\x04xpt\x00\x12Info level messagesr\x00\x1bjava.lang.StackTraceElementa\t\xc5\x9a&6\xdd\x85\x02\x00\x04I\x00\nlineNumberL\x00\x0edeclaringClassq\x00~\x00\x04L\x00\x08fileNameq\x00~\x00\x04L\x00\nmethodNameq\x00~\x00\x04xp\x00\x00\x00\x0cq\x00~\x00\x17t\x00\x0fHelloWorld.javat\x00\x04maint\x00\x04mainpy'
I can see the data I want in there, but don't know how to parse this. Any hints, pointers or suggestions would be most welcome!
(Disclaimer: I'm no expert on log4j, so read at your own risk...)
You don't even want to think about parsing this data with anything
short of a full Java implementation. This is "serialized" data, that
is, a data stream into which one JVM can pickle entire objects (and
their sub-objects, recursively) so another JVM can reconstruct clones
of the originals. Serialization is mostly used for things like remote
procedure calls, where a JVM on machine 1 ships objects to a JVM on
machine 2, which operates on them and ships back results in a similar
fashion. You don't want to parse this stuff.
What you want, I think, is something other than SerializedLayout:
JsonLayout, maybe, or XmlLayout.
--
esosman@comcast-dot-net.invalid