logging/error handling inside a custom log4net appender - log4net

We have a internally-developed logging system, and we wanted to gain the benefits of log4net such as being able to use multiple appenders simultaneously. We decided to move the legacy logging system into a custom log4net appender. That worked great when the legacy system was configured correctly, but the legacy logger actually writes to a WCF client (making it slow for verbose logging, the reason we wanted to engage other log4net appenders), and recently the WCF configuration was not quite what it should have been. When this happened the application seemed to run ok, but obviously the custom appender for the legacy system was not working. The other appenders worked fine, but there was no output from the custom legacy appender and no error messages indicating that there was a problem.
What is the proper way to handle "recursive" logging, that is logging from inside a custom log4net appender? I tried a naive solution: grabbing log4net from its static object and logging inside the appender:
public class MyCustomAppender : AppenderSkeleton
{
protected override void Append(log4net.Core.LoggingEvent loggingEvent)
{
try
{
// something which throws here...
}
catch (Exception ex)
{
log4net.LogManager.GetLogger(this.GetType()).Error(this.GetType().ToString() + ": error during append", ex);
}
}
}
This was an abject failure, "System.Threading.LockRecursionException: Recursive read lock acquisitions not allowed in this mode." Fair enough; it was the naive solution.
I also tried:
this.ErrorHandler.Error(this.GetType().ToString() + ": error during append", ex);
in the exception handler, as it seemed possible it might be the right thing. Nothing obvious happened.
Is there a way to log errors through log4net inside an appender? Or do I have to do something like hard-code writing to the windows event log directly? Obviously there is great danger of infinite recursive descent, but I would think there would be some way of letting the operator know that one of the appenders failed to run.
JR

Of course as soon as I posted the question, I remembered something. log4net has a debugging switch inside the appSettings. I used this code:
this.ErrorHandler.Error(this.GetType().ToString() + ": error during append", ex);
inside the catch block, then set the magic setting on:
<appSettings>
<!--this is wonderful magic-->
<add key="log4net.Internal.Debug" value="true" />
</appSettings>
Now the ConsoleAppender (the other appender I was using) put out the custom appender exception message.
JR

Make sure you have this line at top:
using System.Threading;

Related

How can I find the logging level of the root in log4net?

Given a Log4Net logger on my C# ASP.NET application, how can I get the logging level of the root logger?
The specific error case I am trying to trap is that when the root is set to trace it causes an error in NHibernate because of the version we are on, so I would just like to trap that and shut down the WCF service in the case where someone sets the log level incorrectly.
I'm sure someone else has tried to do this before, so I would like to benefit from prior knowledge. My google fu is weak tonight. Help me StackOverflow, you're my only hope.
var rootLogger = ((Hierarchy) LogManager.GetRepository()).Root;
if (rootLogger.Level == Level.Trace) …

How to trace log level changes caused by .ConfigureAndWatch

Using .ConfigureAndWatch we have configured log4net to reconfigure its logging level without restarting application processes.
A process start we trace the currently configured log level to our trace file.
How can we detect and trace to our trace files the log level changes happening through .ConfigureAndWatch?
I just (re)discovered that ILoggerRepository has a ConfigurationChanged event.
Tracing log level changes from there works fine.
private static void repository_ConfigurationChanged(object sender, System.EventArgs e)
{
var currentTracelLevel = ((log4net.Repository.Hierarchy.Logger)_trace.Logger).EffectiveLevel;
_trace.InfoFormat("----------------------------- log4net level={0}", currentTracelLevel);
}
You can activate the log4net internal debugging, then you will receive messages from the ConfigureAndWatchHandler class when a change occurs, either on the console or in the trace output (see link for more information)
re your comment: In order to pull back the event into your own code and not rely on the console or trace output I'd recommend creating a custom trace appender that loops back into log4net. This way you can filter out messages you want to bring back into your own logs.

Log4j exception lead to application abort

My java application use log4j(flume appender with AsyncAppender) to log to remote log server.
If log server is down, log4j will try to reconnect a few times,but then my java application was shutdown.Is there any possible my java application goes normal with the exception of log4j?
the right solution is :
use AsyncAppender with FlumeAppender. more detail see http://edwardsbean.github.io/blog/2014/01/14/flume-in-action-1/
You have two choices
Catch the exception and ignore it
set the UnsafeMode property to true.

Getting Azure Logs from role process

I've configured the Azure Diagnostics so that the logs get uploaded to a storage table. I'm using Trace.TraceXxx from my code and all works well.
Now I'm trying to add tracing from the Role OnStart() and OnStop() methods. I know that the tracing works as I see the lines in the Debug window when running in the emulator. But from the cloud deployment, it seems that these trace lines never get uploaded to the table. My guess is that it is somewhat related to TraceSources, as the only trace lines I've in the table come from the w3wp.exe source... Any hint ?
Thanks
Like you said you can add the trace listener using the WaIISHost.exe.config, but besides that you can also add the trace listener in code (you'll need a reference to Microsoft.WindowsAzure.Diagnostics.dll):
public class WebRole : RoleEntryPoint
{
public override void Run()
{
var listener = new Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener();
Trace.Listeners.Add(listener);
...
}
}
Another way of setting up diagnostics is through the configuration file. If you created a VS solution recently, it will automatically create the diagnostics plug-in and configuration for the trace listener. With the config file (diagnostics.wadcfg) there is no code that needs to be written for the different data sources. Here is a link where you can get started and a sample file:
http://msdn.microsoft.com/en-us/library/gg604918.aspx
You cannot include custom performance counters right now and you need to make sure that you don’t try to allocate more than 4GB of buffer to anything (you can leave at 0), or it tends to fail.
Note, the time interval format (e.g PT1M). That is a serialization format, so PTXM is X minutes, while PTXS is X in seconds. You need to mark this as content and copy always in Visual Studio (place at root of project) so it gets packaged.
And here is a link to the three ways to setup diagnostics
http://msdn.microsoft.com/en-us/library/windowsazure/hh411541.aspx
Ranjith
http://www.opstera.com

Use Asynchronous appender with JMS appender in log4j

I want to know more details about AsyncAppender
lyk
Can we control retries if attached appender is not working?
How does it handle error if attached appender encounters the error
N how can I remove attached appender from async appender....
As you know the AsyncAppender is just a wrapper for other appenders. When you create an AsyncAppender you have attach your "real" appenders to it.
The AsyncAppender will buffer your log messages until it has reached your configured limit and publish those log message to the attached appenders all at once.
From the code for AsyncAppender, it is looks like when the buffer is full it simply calls the doAppend method for each attached appender (simple for loop through all appenders). It would be up to the attached appenders to handle error conditions and retries.
I suggest implementing a custom appender by extending SkeletonAppender and handling everything yourself in the methods you override.
To answer your last question, AsyncAppender has a removeAppender method:
public void removeAppender(final Appender appender) {

Resources