log4net :comparing adonetappender and rollingfileappender - log4net

I am trying to see which one of these appenders would perform better (the shorter the time, the better).
RollingFileAppender or ADONetAppender?
What are the other parameters I should consider when choosing an appender ?
I saw that my WebServer "holds on" to the rollingfile. Can I set something like
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
(reference: FileAppender section in log4net documentation) in my rolling file appender so that multiple applications/servers can write to the same file ?
our DB server is in a SAN drive, but the log files would be written locally to the hard drive (or may be a SAN drive in the near future)

If your ADONetAppender loses the connection, it will stop logging, but with the option
<reconnectonerror value="true" />
it will try to reconnect.

We have better luck using the rolling file appender. We've noticed that if there is a network glitch the ADO.NET appender stops logging. For example, a reboot after service pack installs on a weekly basis would kill your logger.
Keep in mind that also means keeping your logs on the same server if you are going with file appender - http://ferventcoder.com/archive/2009/07/16/log4net-note-always-keep-your-logs-on-the-same-server.aspx
I've never seen the minimal locking mechanism. It does look like you will pay some performance penalties if you do use it: http://logging.apache.org/log4net/release/sdk/log4net.Appender.FileAppender.MinimalLock.html

I generally use RollingFileAppender to a local disk - this is robust and fast (if you can't write to a local disk, you generally have a fatal problem).
Writing to ADO.NET can fail - for example if the logging database is taken offline for backup purposes while your application is running.
I would also avoid using MinimalLock because of the performance overhead - instead have a separate log file for each application. If you occasionally need to see consolidated log data, you can merge the relevant parts of the logs, or simply open the relevant parts side-by-side in a viewer.

Related

AWS EC2 instance Application logs

I want to store logs of applications like uWSGI ("/var/log/uwsgi/uwsgi.log") on a device that can be accessed from
multiple instances and can save their logs to that particular device under their own instance name dir.
So does AWS provides any solution to do that....
There are a number of approaches you can take here. If you want to have an experience that is like writing directly to the filesystem, then you could look at using something like s3fs to mount a common S3 bucket to each of your instances. This would give you more or less a real-time log merge though honestly I would be concerned over the performance of such a set up in a high volume application.
You could process the logs at some regular interval to push the data to some common store. This would not be real time, but would likely be a pretty simple solution. The problem here is that it may be difficult to interleave your log entries from different servers if you need to have them arranged in time order.
Personally, I set up a Graylog server for each instance cluster I have, to which I log all my access logs, error logs, etc. It is UDP based, so it is fire and forget from the application servers' standpoint. It provides nice search/querying tools as well. Personally I like this approach as it removes log management from the application servers altogether.
Two options that I've used:
Use syslog (or Syslog-NG) to log to a centralized location. We do this to ship our AWS log data offsite to our datacenter. Syslog-NG is more reliable than plain ole' Syslog and allows us to use MongoDB as a backing store.
Use logrotate to push your logs to S3. It's not real-time like the Syslog solution, but it's a lot easier to set up and manage, especially if you have a lot of instances and aren't using a VPC
Loggly and Splunk Storm are also two interesting SaaS products intended to solve this problem.

distributed logging: JMS and log4j?

Been doing some searching for a solution to this problem: I need log entries from apps running on several machines to be sent to & aggregated on a remote server. Requirements:
logging in the app needs to be asynchronous (can't wait for log entry to traverse network)
logging in the app needs to be queued; if the network fails, log entries need to be queued locally and sent to
centralized server when the network becomes available again
I'm looking at using log4j and a JMSAppender. Assuming that's a suitable solution, are there any examples available? What process would be running on the centralized server to receive log entries in this scenario?
Thanks.
One simple setup I came to think about is to use Apache ActiveMQ
It is an open source messaging broker (JMS compatible) that is able to cluster queues among several physical machines and the ActiveMQ installation is rather lightweight. You simple install one ActiveMQ on each of your applications machines. Then on the logging server (Physical Server C in the picture) you would have another ActiveMQ. Your application would use a JMS appender (read more here) and you could actually just use the included apache camel to read from the queue and write a log on file or database without needing to write an application for that task.
It could be as simple as adding something like the following to the camel.xml in the activemq /conf installation and import the camel.xml in the activemq.xml configuration.
<route>
<from uri="activemq:queue:LogQueue"/>
<to uri="file:target/folder/?fileName=logfile.log&fileExist=Append"/>
</route>
You could use a myrriad of other frameworks, JMS servers and technologies, but I think this is a rather easy approach to achieve with very low cost and high stability.

Logging of multiple appenders to same logger

I want to implement same logfile for different appenders ..Is it possible to do so?or should i have to use different log files?
To be on the safe side it is probably better not to do this as it could lead to synchronization issues, deadlock or corrupt log files.
However, logback (log4j's successor) allows this, in prudent mode.
Another alternative, is to have your multiple appenders log to a single SocketAppender and have the receiving socket log to a file.
Don't know log4j, but log4net has ForwardingAppender and BufferingForwardingAppender, and I guess it's probably similar.
So presumably you could have multiple ForwardingAppenders that all forward to the same FileAppender.

How to configure log4net for fallback

This is my situation. I have successfully implemented logging to remote syslog using log4net. However, as far as I could test, if syslog IP is not valid, all messages will not log anywhere and no exception is raised. It just does nothing.
Hence, it would be nice to have some sort of fallback. Let's say if writing to syslog fails, write to file or to database.
Is that even possible with log4net? Or would I have to configure it to log to two locations at the same time?
I don't think you can do this by configuration. This issue is open in the log4net feature backlog.
If your application can eat the logging overhead, the easiest solution would be to log to an alternative appender by default.
Alternatively you could try to wrap the appender you're using in a custom appender, and implement the fallback scenario if the syslog appender throws an exception. If it doesn't swallow them silently.
From log4net FAQ:
You can implement the log4net.Appender.IAppender interface to create you own customized appender. We recommend that you extend the log4net.Appender.AppenderSkeleton class rather than starting from scratch. You should implement your custom code in a assembly separate from the log4net assembly.
To get started it is worth looking at the source of the log4net.Appender.TraceAppender as an example of the minimum amount of code required to get an appender working.
Third option would be to look into the source code of your appender and see if you can fork it and do the necessary customizations there.

Log4Net GetLogger creates rolling files even for the unreferenced files

I have a C# solution that contains three executables. I have each of these three executables sharing the same log4net configuration file. At startup of each of the executable, they retrieve a logger (one logger per executable, as per configuration file further below). When one of the executable performs Log.GetLogger(), it creates all the rolling files instead of only the one rolling file that is referred to as appender-ref in the executable's logger configuration.
For instance, when I startup my sending daemon executable, it performs Log.GetLogger("SendingDaemonLogger") which creates 3 files Log/RuleScheduler.txt, Log/NotificationGenerator.txt and Log/NotificationSender.txt instead of only the desired Log/NotificationSender.txt.
Then when I startup another of the executables, for instance the rule scheduler daemon, this other process cannot write in Log/RuleScheduler.txt because it has been created and locked by the sending daemon process.
I am guessing that there may be three different solutions to my problem:
The GetLogger should only create the rolling file appenders that are referenced in the config
I should have one config file per executable, this way each config file could list only one rolling file appender and starting each of the executable would not create the rolling files of the other daemons. I am however reluctant to do this because some of the configuration (SMTP appender, console appender) is shared between the daemons and I don't want to have duplicate copies to maintain. Unless there is a way to have a config file including another one?
Maybe there is a way to configure the rolling file so that concurrent access across processes is allowed? This solution still isn't perfect in my opinion because any of the daemons should not be creating the rolling files of some other daemons.
Thanks in advance for your help!
I have difficulties for posting the config file properly here (this website interprets as HTML). Please go to the following link for seeing my log4net configuration file:
log4Net configuration file
Better late than never...
Use the following filename definition for an file appender.
The %appdomain will be replaced on startup with the appdomains friendly name.
Now you can use the exact same configuration file for multiple apps and still have separate logfiles. No need to configure multiple appenders...
<file type="log4net.Util.PatternString" value="C:\logs\%appdomain.log" />
see PatternString documentation for available patterns.
I think that all 3 files are created for the reason given in this answer. Though you could write your own appender that does not show this behavior it is not advisable. This leaves you with either having 3 separate config files or configuring minimal locking:
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
I have no experience with the latter so I cannot tell you how good this works. I would probably go for the three separate config files.

Resources