Log4J: How to Use Socketappender

log4j: How to use SocketAppender?

You can run the server using

java -classpath log4j.jar org.apache.log4j.net.SimpleSocketServer 4712 log4j-server.properties

The SimpleSocketServer receives logging events sent to the specified port number by the remote SocketAppender, and logs them as if they were generated locally, according to the configuration you supply in log4j-server.properties. It's up to you to configure the relevant console/file/rolling file appenders and attach them to the relevant loggers just as you would if you were doing the logging directly in the original process rather than piping the log events over a network socket. I.e. if you're currently creating local log files with something like:

log4j.rootLogger=DEBUG, file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=logfile.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%d] [%t] [%m]%n

then you would change it so that the sending side log4j.properties simply says

log4j.rootLogger=DEBUG, server
log4j.appender.server=org.apache.log4j.net.SocketAppender
log4j.appender.server.Port=4712
log4j.appender.server.RemoteHost=loghost
log4j.appender.server.ReconnectionDelay=10000

and the server-side log4j-server.properties contains the definitions that were previously on the sending side:

log4j.rootLogger=DEBUG, file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=logfile.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%d] [%t] [%m]%n

In particular, note that there's no point specifying a layout on the SocketAppender on the sending side - what goes over the network is the whole logging event object, it's the receiving side that is responsible for doing the layout.

log4j: How does a Socket Appender work?

From the SocketAppender documentation

Logging events are automatically buffered by the native TCP
implementation. This means that if the link to server is slow but
still faster than the rate of (log) event production by the client,
the client will not be affected by the slow network connection.
However, if the network connection is slower then the rate of event
production, then the client can only progress at the network rate. In
particular, if the network link to the the server is down, the client
will be blocked.

On the other hand, if the network link is up, but the
server is down, the client will not be blocked when making log
requests but the log events will be lost due to server unavailability.

Since the appender uses the TCP protocol, I would say the log events are "sort of synchronous".

Basically, the appender uses TCP to send the first log event to the server. However, if the network latency is so high that the message has still not been sent by the time a second event is generated, then the second log event will have to wait (and thus block), until the first event is consumed. So yes, it would slow down your application, if the app generates log events faster than the network can pass them on.

As mentioned by @Akhil and @Nikita, JMSAppender or AsyncAppender would be better options if you don't want the performance of your application to be impacted by the network latency.

Extracting logs send over SocketAppender via LogEvent Object

You don't get the first log (TRACE) because in your config file log4j2.properties, you have logger.socket.level=debug, but you should have logger.socket.level=trace to also enable the level TRACE.

Concerning the other logs, you should run your listener code in a loop: right now you're reading only the first log.

I didn't test this code but it should look like:

LogEvent event = null;
private Socket socket1 = null;
private ServerSocket ss = null;
PrintWriter sspw=null;
ObjectInputStream objectInputStream = null;
try {
//Creating Socket and making it listen to a specific port, receiving through streams.
//Servers socket creation and waiting
ss = new ServerSocket(9000);
socket1 = ss.accept();

objectInputStream = new ObjectInputStream(new BufferedInputStream(socket1.getInputStream()));

while (true) {
event = (LogEvent) objectInputStream.readObject();
System.out.println(event.getLoggerName());
System.out.println(event.getLevel());
System.out.println(event.getMessage().getFormattedMessage());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (objectInputStream != null) {
objectInputStream.close();
}
}


Related Topics



Leave a reply



Submit