How to configure log4net for fallback - log4net

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.

Related

How to obtain all log4net loggers currently running in all processes

Each process in our system uses log4net. Many of those processes are stared up as services. Some of those running applications are very verbose spewing debug entries and we'd like the ability to limit their output. All loggers use the same .config file to set their current logging level. I'm working on an app that will gain access to all loggers that set the source using
log4net.GlobalContext.Properties["source"] = source;
What I'd like to do is get a list of all loggers currently registered, obtain their source name and then change the .config file for each of those sources to individually configure the output level for each of them.
The problem I'm having is finding the list of all those loggers so I may add an entry in the .config file. Is there a way to do obtain that list of loggers across all processes from a single application?
I've tried using GetRepository().GetCurrentLoggers(), but that only returns the logger for the currently calling application.
There is no standard way of getting loggers which are in an other process. You have to make something your self.
Try this
using log4net.Repository.Hierarchy;
var appenders = ((Hierarchy)LogManager.GetRepository())
.Root.Appenders;

logging to ELK stack from karaf

I've been working on getting an ELK stack setup to have our logs centralized and easier to check, but I'm running into a bit of a snag.
I've modified a few of our java programs to use the socket appender from log4j and it's worked great each time. Now I'm trying to add it to karaf to have all of our karaf logs recorded but it doesn't seem to be working.
I added:
log4j.rootLogger=INFO, logstash, osgi:*
# Logstash appender
log4j.appender.logstash=org.apache.log4j.net.SocketAppender
log4j.appender.logstash.Port=PORT
log4j.appender.logstash.RemoteHost=HOST
log4j.appender.logstash.ReconnectionDelay=10000
to the file in {karaf_home}/etc/org.ops4j.pax.logging.cfg (with the correct port/host obviously) and then restarted karaf just to make sure (something I read said it would pick up changes automatically but I didn't know if I trusted it so I restarted it anyway) but nothing seems to be making it from karaf to our ELK stack. When I do log:display on the karaf console I see plenty of messages being written to the log, but none in ELK.
Any clue as to why this may not be working for karaf, but is working for other projects using the same appender?
You should have a look at karaf decanter. It already contains connectors that can be used to send logs to an ELK stack, the decanter-collector-log is probably what you are looking for

Where does Log4Net store it's logs?

I have a WinForms application and I'm currently evaluating Log4Net.
When I close the application and delete the log file, I expect to lose the logs. What happens is I launch the application and the logs of the last session get written in the file.
Log4net does not store the logs in a specific place. You can configure log4net where to store the logs. The basic principle is that you configure log appenders in configuration. This way you are flexible in where you are logging. There are many possible appenders, for example:
file
sql
eventlog
debug
blob storage
...
for a overview of 'out of the box' appenders: https://logging.apache.org/log4net/log4net-1.2.13/release/sdk/log4net.Appender.html
Each appender has different configuration options. You can have multiple appenders to log to different 'endpoints'.

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.

log4net :comparing adonetappender and rollingfileappender

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.

Resources