general exception
general exception

Reputation: 4342

log4net log debug messages only if debug variable is set

I have a console application that is using a log4net setup for logging information to the console output only at the moment.

I have various log.Debug("Debug info") statements which I only want to print out to the console if a debug flag within my application is set.

The debug variable is set by reading a switch passed to the application when it is invoked. The arguments are read using NDesk.Options.

I want to avoid wrapping every debug statement in an if:-

bool debug = false;

// read switches        
var p = new OptionSet() {
    { "d|debug", "debug mode", v => debug = v != null },
};

if (debug) {
    log.Debug("Debug info")
}

Is there anything I can put in the <log4net><appender> section of the configuration to enable this, or is there a way of overriding log.Debug to provide the logic ?

Upvotes: 0

Views: 3727

Answers (4)

Stefan Egli
Stefan Egli

Reputation: 17028

I did not test it extensively but you should be able to achieve what you want by setting the threshold of the repository like this:

var repository = LogManager.GetRepository();
if (repository != null)
{
    if (debug)
    {
        repository.Threshold = Level.Debug;
    }
    else
    {
        repository.Threshold = Level.Info;
    }
}

Upvotes: 0

Menelaos Vergis
Menelaos Vergis

Reputation: 3955

if you are initializing log4net using code add a debug filter to the appender

  private static void InitFileLogging(bool logDebugEvents)
    {
        string LOG_PATTERN = "%d [%t][%logger] %-5p %m%n";

        Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
        TraceAppender tracer = new TraceAppender();
        PatternLayout patternLayout = new PatternLayout();

        patternLayout.ConversionPattern = LOG_PATTERN;
        patternLayout.ActivateOptions();
        tracer.Layout = patternLayout;


        tracer.ActivateOptions();

        hierarchy.Root.AddAppender(tracer);

        RollingFileAppender roller = new RollingFileAppender
        {
            Layout = patternLayout,
            AppendToFile = true,
            RollingStyle = RollingFileAppender.RollingMode.Size,
            MaxSizeRollBackups = 4,
            MaximumFileSize = "300KB",
            StaticLogFileName = true,
            File = @"c:\temp\textLog.txt"
        };
        if (!logDebugEvents)
        {
            log4net.Filter.LevelMatchFilter debugFilter = new log4net.Filter.LevelMatchFilter() { AcceptOnMatch = false, LevelToMatch = Level.Debug };
            roller.AddFilter(debugFilter);
        }
        roller.ActivateOptions();


        hierarchy.Root.AddAppender(roller);

       // hierarchy.Root.Level = Level.All;
        hierarchy.Configured = true;

    }

else if you are usign externar config file get the appender and add the debug filter.

 private static void DisableDebugFileLogging()
    {
        XmlConfigurator.Configure();
        Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
        foreach (var appender in hierarchy.GetAppenders())
        {

            RollingFileAppender rolAppender = appender as RollingFileAppender; //or whatever appender you use
            if (rolAppender != null)
            {
                log4net.Filter.LevelMatchFilter debugFilter = new log4net.Filter.LevelMatchFilter() { AcceptOnMatch = false, LevelToMatch = Level.Debug };
                rolAppender.AddFilter(debugFilter);
            }
            rolAppender.ActivateOptions();
        }
    }

Upvotes: 0

Thomas
Thomas

Reputation: 5921

You can try to create your own appender like this :

public class MyAppender : AppenderSkeleton    
{
    private static bool TurnDebugOn = false;
    public static SetDebugLogging(bool toSet){
        TurnDebugOn = toSet;
    }

    protected override void Append(LoggingEvent loggingEvent)
    {
        bool logEvent = true;
        LogLevel logLevel = LogLevel.Err;
        switch (loggingEvent.Level.Name)
        {
            case "DEBUG":
                logEvent = TurnDebugOn;
                logLevel = LogLevel.Debug;
                break;
            case "WARN":
            case "INFO":
                logLevel = LogLevel.Info;
                break;
            case "ERROR":
                logLevel = LogLevel.Err;
                break;
            case "FATAL":
                logLevel = LogLevel.Critical;
                break;
        }
        if(logEvent){
            LogService.Log(LogNameEnum.Exception, LogCategoryEnum.BusinessLogic, logLevel, RenderLoggingEvent(loggingEvent));
        }
    }
} 

Then in your code :

MyAppender.SetDebugLogging(true);

in your config file:

...
<appender name="AppenderToUse" type="MyAppender">
...

Upvotes: 0

Joe Ratzer
Joe Ratzer

Reputation: 18569

Yes there is, e.g.:

<root>
  <level value="DEBUG" />
  <appender-ref ref="LogFileAppender" />
  <appender-ref ref="AdoNetAppender" />
  <appender-ref ref="EventLogAppender" />
</root>

Upvotes: 1

Related Questions