Using Syslog's unix socket with Log4J2 - log4j

I would like to send the logs of an application on a rsyslog server using the client protocol : Unix socket.
Both application and rsyslog server are on the same machine.
I've been comparing different logging tools : Log4J, Logback and Log4J2.
Log4J's Syslog appender doesn't permit it natively. A solution is to use Syslog4J and configure our Syslog4JAppender this way :
<appender name="mySyslogAppender" class="org.productivity.java.syslog4j.impl.log4j.Syslog4jAppender">
<param name="protocol" value="unix_socket" />
...
</appender>
Same as Log4J, Logback's Syslog appender doesn't permit it natively. A solution is to use Syslog4J and logback-syslog4j tool, and configure our appender this way :
<appender name="mySyslogAppender" class="com.papertrailapp.logback.Syslog4jAppender">
<syslogConfig class="org.productivity.java.syslog4j.impl.unix.socket.UnixSocketSyslogConfig">
...
</syslogConfig>
</appender>
Now I'm looking for a solution for Log4J 2, but I didn't find any.
Do you know one ?
Do these tools will include natively this functionality ?

Related

log4net items not shown in AppServiceAppLogs

We are using log4net for our application logging in azure.
We configured it according to this document , the logs are stored in
d:/home/LogFiles/Application/Log4netfile-[%processid].txt
we can download the files from https://xxxx.scm.azurewebsites.net/api/dump and I can also see them in Log stream, there it looks like this
2022-02-06T18:22:57 PID[29616] Verbose log4net: Adding appender named [FileAppender] to logger [root].
2022-02-06T18:22:57 PID[29616] Verbose log4net: Hierarchy Threshold []
2022-02-06T18:22:58 PID[29616] Verbose LOG4NET Fatal LOG4NET LOG4NET
2022-02-06T18:22:58 PID[29616] Verbose LOG4NET Debug Message Message
Line items like:
log4net: Adding appender named
are created by log4net during internal setup (using debug=true), and those show up in our AppServiceAppLogs, however, items which are genereted by the logger using:
Logger.Fatal("LOG4NET Fatal LOG4NET LOG4NET");
are visible in stream and files but they are not showing up in AppServiceLogs.
I tried multiple different appenders the only one which shows up in Log-Streams and in files is FileAppender (or RollingFileAppender), all others are not showing in LogStreams or (as expected) in the files.
Based on this https://learn.microsoft.com/en-us/azure/app-service/troubleshoot-diagnostic-logs#send-logs-to-azure-monitor I assume that everything writen to the files should be than sent to azure-monitor - but in our case this is not hapening. Could you provide some reference about implementation / code how the sending of the files is done, and which process does that ?
I am wandering is there anything which we could configure differently to get the log-items to end up in AppServiceLogs? Or should we use some other appender?
I am aware of the issue in AspNetTraceAppender and I am trying to avoid implementation of new appender.
There are a few things you can look into:
Call log4net configure before writing to your log file (only once is enough):
log4net.Config.XmlConfigurator();
or
log4net.Config.XmlConfigurator.Configure();
and then you can add flushing to your configuration:
<appender name="AzureTraceAppender" type="log4net.Appender.TraceAppender">
<param name="ImmediateFlush" value="true" />
<layout type="log4net.Layout.PatternLayout">
<!-- can be any pattern you like -->
<conversionPattern value="%logger - %message" />
</layout>
</appender>
Immediately, this will flush the message.
In Global.asax, To make log4net read your configuration.
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
// Initialize log4net.
log4net.Config.XmlConfigurator.Configure();
}
Make sure Azure Diagnostics has configured to all information needed for debugging.
After that, you can enable internal log4net debugging. Refer internal debugging on this log4net faq page. Standard it should log to your listener you have configured. To the trace element Add the autoflush="true" option . Or find directory on the worker role you can write to and access to read your logs.

Logging with applicationinsights in spring boot app

We are using spring boot to send metrics to app insight we are using applicationinsights-logging-log4j2.
Below are the appenders we are using in logj2-spring.xml
*
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{MM-dd-yyyy'T'HH:mm:ss.SSS,UTC} %correlationId [%thread] %-5level %logger{36}- %msg%n"/>
</Console>
<ApplicationInsightsAppender name="aiAppender">
</ApplicationInsightsAppender>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console" />
<AppenderRef ref="aiAppender" />
</Root>
</Loggers>
We are seeing the logs in app insight search screen however i have few questions.
Is there a way to define a custom info in logging like correlationId(guid used to track a flow uniquely) and send it to AI just like we are appending in console logs.
Is there anything like pattern we can define for AI.
Is there a use of console appender and logging to console if we are logging to AI.
You can create a class that will extend the OncePerRequestFilter, and in that class generate one Id using UUID generator and set this UUID in variable, let's say RequestId.
And then write MDC.put('requestid', RequestId).
OncePerRequestFilter class is executed with every HTTP request, you won't be required to call the class extending it explicitly, and MDC.put('requestid', RequestId) will be added as external property in your application insight log.
This is just a workaround for correlationid though it is providing us a same feature, that we can aggregate a log. Whatever requestid is being generated, you can retrieve that and then use it application insight to see logs for that request.
I believe console appender is still helpful, because I. AI we can see loga after at least 4 to 5 mins, so for real time debugging console logs are helpful. Though you can. Configure what type of logs you want to see in console and what you wanna sent to ai.

Log4j and centralizing log collection

I have an existing distributed application using log4j to write logs to the local server. I want to preserve the existing functionality and also have some of those logs sent to a central repository. I've seen examples of using log4j with SocketAppender to send a log to a remote server, but haven't seen an example of multiple server sending to the same remote server writing each server's logs in a separate file. Is there an example of this?
As an alternative, I'm curious about using the JDBCAppender using a database as the centralized log repository but have the same question regarding how do differentiate where the messages came from when viewing query results. Is there a log4j properties setting that identifies the sender that can be interpreted on the listener server?
For your first question - it will depend on the remote server to whom your client program is sending logs. If you have developed some program for receiving logs on remote server then, there are 2 approaches to create separate log file for each client logs -
Server program should listen on a particular port and after receiving some logs, it should check client IP and then create log file for each client IP.
Make server program to listen on different port for each client and once client is connected to its specific port, receive the data and dump in a log file. This approach seems easy but not recommended.
If your server is based on linux, I would recommend you to use rsyslog for centralizing log collection. In rsyslog, you can configure each client separately and dump the logs in separate log file.
For second question - you can use Nested diagnostic Context (NDC) feature of log4j for writing hostname in database. See this example. This example is using USER_ID as extra column for writing in database. Similarly, you can use this extra column for writing hostname. In the starting of your client program before writing any log statement, you have to put value in NDC using below code -
NDC.push(InetAddress.getLocalHost().getHostName());
you have to make some changes in the Configuration File. Considering multiple applications want to write their log files to the centralised remote location, If yes then the below mentioned changes would help:
You need to make the change in each individual application's Log4j config file.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="60">
<Properties>
<Property name="server-log-path">REMOTE_SERVER_PATH</Property>
</Properties>
<Appenders>
<File name="Login-App-File-Appender" fileName="${server-log-path}/file_name.log" >
<PatternLayout>
<pattern>
[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>
</PatternLayout>
</File>
<File name="CheckOut-App-File-Appender" fileName="${server-log-path}/file_name.log" >
<PatternLayout>
<pattern>
[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="com.microService.LoginService" level="info" additivity="false">
<AppenderRef ref="Login-App-File-Appender"/>
</Logger>
<Logger name="com.microService.CheckOutService" level="info" additivity="false">
<AppenderRef ref="CheckOut-App-File-Appender"/>
</Logger>
<Root>
<AppenderRef ref="Login-App-File-Appender"/>
</Root>
</Loggers>
</Configuration>

what is 'facility' in log4net Appender?

can you explain me what is'facility' in the log4net appender config ? This is an example from papertrail guide.
<appender name="PaperTrail" type="log4net.Appender.RemoteSyslogAppender">
<facility value="Local6" />
...
</appender>
What is the Local6 for ? and the value 'Local6' ? I did some google search but still feeling confused about it. And I'm looking best practice to use log4net for papertrail too.

Does Log4Net Http Appender exist?

Is there an appender in log4net that can allow a winform client to read a log4net log on another server without using a share? My application is hosted as a web service. I'm looking for an HTTP appender or something similar.
There is a GitHub project called PostLog that is a HttpAppender for log4net.
I think you could use the Remoting Appender, something like this:
<appender name="RemotingAppender" type="log4net.Appender.RemotingAppender" >
<sink value="http://localhost:8080/LoggingSink" />
<lossy value="false" />
<bufferSize value="95" />
<onlyFixPartialEventData value="true" />
</appender>
According to the docs:
This Appender is designed to deliver
events to a remote sink. That is any
object that implements the
RemotingAppender.IRemoteLoggingSink
interface. It delivers the events
using .NET remoting. The object to
deliver events to is specified by
setting the appenders Sink property.
There is also a UdpAppender and there is this open source client that can receive these messages:
http://log2console.codeplex.com/

Resources