I use log4net in my console application, I use log.Error("Message to log");
multiple times in if/else structures.
My application has to return a code which specifies if an error has occurred during the run of the application (0 → ok, 1 → at least 1 error occurred).
Is there a way to ask log4net if it logged an error, for instance:
bool b = LogManager.AtLeastOneErrorHasBeenLogged;
You can configure the log4net. config file to create log files. The file is located in the webroot\App_data directory of the installation.
This seems like it would be straightforward if you use a custom appender whose only purpose is to track if an error occurred.
This (untested) example uses the technique of only calling the appender if the log level is Error by using a LevelRangeFilter
but you could just as easily check the log level (or other criteria) in the Append method, or in the root logger config. The example assumes you are using XML config rather than programmatic config, but it is possible to add appenders programatically so they are used by all loggers.
The appender:
public namespace MyApp
{
public class ErrorFlagAppender : AppenderSkeleton
{
public bool ErrorOccurred { get; set; }
protected override void Append(LoggingEvent loggingEvent)
{
ErrorOccurred = true;
}
}
}
The config:
<appender name="ErrorFlagAppender" type="MyApp.ErrorFlagAppender,MyApp" >
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR"/>
<levelMax value="ERROR"/>
</filter>
</appender>
<root>
<appender-ref ref="[your existingappender]" />
<appender-ref ref="ErrorFlagAppender" />
</root>
Then you can have an extension method to see if an error occurred:
public static class LogManagerExtensions
{
public static bool AtLeastOneErrorHasBeenLogged(this LogManager logManager)
{
var flagAppenders = logManager.GetRepository()
.GetAppenders()
.OfType<ErrorFlagAppender>();
return flagAppenders.Any(f => f. ErrorOccurred);
}
}
I think that most people would consider the idea of asking log4net (or whatever logging framework one might use) if an error was logged to be very odd. You are in control of calling log4net, so why not keep track yourself if an error occurred. What if the user of your program turns off logging in the config file? If an error happens when logging is turned off and you are depending on whether or not an error was logged, then you have no way of knowing that an error occurred. Nicholas Carey suggested to add logic inside your catch blocks to keep track of whether or not an exception occurred. Even if you don't use exceptions, you could do something similar inside your if/then/else logic:
(Note that I am borrowing Nicholas Carey's sample as a basis for my answer)
static int Main( string[] argv )
{
static int errorOccurred = 0;
try
{
log.Info("Begin");
if (SomeImportantPreconditionExists())
{
DoSomeStuff();
if (DoingSomeStuffWorkedRight())
{
Hooray();
}
else
{
log.Error("DoSomeStuff seems to have failed");
ErrorOccurred();
}
}
else
{
log.Error("SomeImportantPrecondition does not exist");
ErrorOccurred();
}
}
catch( Exception e )
{
log.Error("Exception of some sort", e);
ErrorOccurred();
}
return ErrorStatus();
}
private static void InitializeErrorOccurred()
{
errorOccurred = 0;
}
private static void ErrorOccurred()
{
errorOccurred = 1;
}
private static int ErrorStatus()
{
return errorOccurred;
}
Having posted that code, I have to say that I think that it likely you could come up with a more robust solution than what I posted.
My final advice is to NOT make your program logic depend on something that the logging framework does (or does not). Generally speaking, your program should run the same way whether logging is enabled or not (notwithstanding that when logging is enabled, messages are logged).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With