17

I can log info messages without a problem, but can't figure out how to log verbose messages. Any help would be welcomed.

My problem is:

loggingEvent.Level can be checked in the Format function. The possible values are amongst others, Info, Debug, Error, Verbose. There are more, but these are the ones I'll be using mostly.

The actual log object only has the following methods:

Log.Info
Log.Debug
Log.Warn
Log.Error

As you can see - no verbose!

So how can I Log a verbose message, this is different to debug

Thanks in advance

Grhm
  • 6,726
  • 4
  • 40
  • 64
JL.
  • 78,954
  • 126
  • 311
  • 459
  • Short Answer is - You can't unless you do some work to the plumbings. This might possibly change in later versions. This question was asked with version 1.2 of the product in mind. – JL. Feb 17 '10 at 10:45

6 Answers6

33

You can add a Verbose (or Trace level) to log4net by using extension methods. This is what I'm using:

public static class ILogExtentions
{
    public static void Trace(this ILog log, string message, Exception exception)
    {
        log.Logger.Log(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, 
            log4net.Core.Level.Trace, message, exception);
    }

    public static void Trace(this ILog log, string message)
    {
        log.Trace(message, null);
    }

    public static void Verbose(this ILog log, string message, Exception exception)
    {
        log.Logger.Log(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, 
            log4net.Core.Level.Verbose, message, exception);
    }

    public static void Verbose(this ILog log, string message)
    {
        log.Verbose(message, null);
    }

}

Usage example:

public class ClientDAO
{
    private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(ClientDAO));

    public void GetClientByCode()
    {
        log.Trace("your verbose message here");
        //....
    }
}

Source:

http://www.matthewlowrance.com/post/2010/07/14/Logging-to-Trace-Verbose-etc-with-log4net.aspx

Philipp M
  • 1,877
  • 7
  • 27
  • 38
3

Apache log4net has the following log levels:

DEBUG < INFO < WARN < ERROR < FATAL

For messages considered more verbose than informational messages (INFO), the DEBUG level is the option to go for. Writing debug messages should be as simple as:

myLog.Debug("This is a pretty verbose message");

If you write extremely many debug messages and/or the messages are costly to produce (eg involves heavy string concatenation), consider adding a conditional around the logging:

if (myLog.IsDebugEnabled)
{
    myLog.Debug("This is a pretty verbose message");
}

If you find yourself doing this often and want to DRY up your code, consider using extension methods for deferred message formatting, which will turn the above statement into this:

Log.Debug( () => "This is a pretty verbose message" );  
Jørn Schou-Rode
  • 37,718
  • 15
  • 88
  • 122
3

You cannot figure out, because, AFAIK there is no "verbose" level in log4net. Is there one in log4j?

Following are the levels

ALL DEBUG INFO WARN ERROR FATAL OFF

Informational messages are the ones where you specify what you are doing currently in your application. Those messages spit out by OS commands or tools when you say -verbose, would be these kind of messages.

Debug messages are mostly for programmers and they allow you to write information such as variable creation, life-cycle, exception stack traces etc. Something that only the programmer/ support staff would be interested in.

[Edit] Just thought of this. You can very well add a switch or config element to your application named "verbose" and then spit out the informational messages if set to true. Or wrap the logging in a helper method, which will log in log4net as well as send the same message to console. Also, you can use the ConsoleAppender to log messages to console. I have never used it though. Is this what you were looking for?

Hope this helps.

Tanmay
  • 1,527
  • 1
  • 9
  • 7
  • 1
    I updated the question... notice the LoggingEvent has a level property. One possible value is verbose. – JL. Feb 17 '10 at 10:24
  • 1
    Sorry, I don't see that possible value in the SDK. http://logging.apache.org/log4net/release/sdk/log4net.Core.Level.html Could you maybe specify where you are getting it from? – Tanmay Feb 17 '10 at 10:30
  • I think I understand what you are saying. OOB (out of box) Log4net does not have a verbose level per say, rather it refers to anything above Info, which for all practical purposes means debug. this is why you can only check for it, during the layout formatting right? – JL. Feb 17 '10 at 10:30
  • Please also see an edit to my answer that specifies some more detail. Also, could you explain how you differentiate between Info and Verbose? – Tanmay Feb 17 '10 at 10:31
  • @Tanmay sure : Log4net.Core.LoggingEvent.Level = Log4.net.Core.Level – JL. Feb 17 '10 at 10:32
  • Well, the level that you mention in LoggingEvent does not have the "Verbose" option. So is it something that you think it should have, or are we looking at the different sdks? Or different versions? – Tanmay Feb 17 '10 at 10:33
  • log4net.Core.Level does have Verbose as a possible value in v1.2.10. – adrianbanks Feb 17 '10 at 10:35
  • 1
    Sincerely I have the following values : Alert, ALL, Critical, Debug, Emergency, Error, Fatal, Fine, Finer, Finest, Info, Notice, Off, Severe, Trace, Verbose, Warn. My product version is 1.2 – JL. Feb 17 '10 at 10:36
  • @adrianbanks I don't think it does either. That's why I pointed to the SDK. But maybe JL is using a version that does. I still don't understand how it would be different from INFO. – Tanmay Feb 17 '10 at 10:36
  • @JL - That is very interesting to know. Quoting a line from the sdk "Each level has a DisplayName in addition to its Name. The DisplayName is the string that is written into the output log. By default the display name is the same as the level name, but this can be used to alias levels or to localize the log output." So is it an alias? – Tanmay Feb 17 '10 at 10:38
  • @Tanmay: The SDK docs for v1.2.10 (http://logging.apache.org/log4net/release/sdk/log4net.Core.Level.html) do not show all of the levels that I have in my version of 1.2.10. I have the same levels as @JL has mentioned. – adrianbanks Feb 17 '10 at 10:41
  • @Tanmay, problem is the property is read only, so by the time it hits the formatter, you can't set it. But I think for now I'll just log all INFO messages on 1 level. I just thought Log4Net might have OOB functionality to have 2 levels of info. seems like you are right, it simply does not. – JL. Feb 17 '10 at 10:42
3

In case off someone still need the answer (without using System.Reflection) It's not necessary to set DeclaringType, just set null (auto resolve in Lo4Net)

public bool IsVerboseEnable { get { return _log.Logger.IsEnabledFor(Level.Verbose); } }

public string Verbose(string text)
{
    _log.Logger.Log(null, Level.Verbose, text, null);
    return text;
}

Tested & Validated

Code use in log4net

public virtual void Log(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception)
{
    try
    {
        if (this.IsEnabledFor(level))
        {
            this.ForcedLog((callerStackBoundaryDeclaringType != null) ? callerStackBoundaryDeclaringType : Logger.declaringType, level, message, exception);
        }
    }
    catch (Exception exception2)
    {
        LogLog.Error(Logger.declaringType, "Exception while logging", exception2);
    }
}
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
APAUL
  • 31
  • 1
2

I did not try it, but I think it should be quite straight-forward: Internally log4net knows a level "verbose"; it is only the ILog interface that does not expose it. Therefore it should be quite simple to add a IsVerboseEnabled and Verbose() method to this interface. Of course you need to be willing to change the log4net source code...

Stefan Egli
  • 17,398
  • 3
  • 54
  • 75
2

I've tested log4net with BasicConfigurator, and writing log messages generated output for all levels from EMERGENCY down to DEBUG, but not for TRACE or VERBOSE.

I needed to execute the code below for them to start logging.

var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
((Hierarchy)logRepository).Root.Level = Level.All;
Alexandre
  • 1,132
  • 1
  • 10
  • 21