log4net versus TraceSource

18,143

Solution 1

I think that log4net is doing every that you listed for me.

Pluggable listeners sounds like appenders - there are lots of them and in fact I even hacked the rolling log file to always end in .log (for file associations), added a cc field to the email appender, and have finally tuned my favourite values for the colored console appender. If I may be so bold - my colored console happiness:

<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<!-- Can Use:
        Blue
        Green
        Red
        White
        Yellow
        Purple
        Cyan
        HighIntensity
        -->
<mapping>
  <level value="FATAL" />
  <foreColor value="Yellow, HighIntensity" />
  <backColor value="Red" />
</mapping>
<mapping>
  <level value="ERROR" />
  <foreColor value="White" />
  <backColor value="Purple, HighIntensity" />
</mapping>
<mapping>
  <level value="WARN" />
  <backColor value="Blue" />
  <foreColor value="White" />
</mapping>
<mapping>
  <level value="INFO" />
  <backColor value="Green" />
  <foreColor value="White" />
</mapping>
<mapping>
  <level value="DEBUG" />
  <foreColor value="White" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
  <!--<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />-->
  <!--<conversionPattern value="%-5level %file:%line - %message%newline" />-->
  <conversionPattern value="%level %logger:%line %newline     %message%newline" />
</layout>

Customisable trace switches: Log4net only comes with FATAL ERROR WARN INFO DEBUG in order of increasing verbosity. The only one I actually miss is AUDIT for who-did-what logging.

Customisable configuration: I use a log4net.config file which I load up at runtime (or write a log to c:\ whining that I can't find the config.)

    Try
        ' Get log4net configuration from file
        Dim logConfigFile As FileInfo
        logConfigFile = New FileInfo(".\log4net.config")

        If logConfigFile.Exists Then
            XmlConfigurator.Configure(logConfigFile)
        Else
            CreateEmergenceLogFile(logConfigFile.FullName)
        End If

    Catch ex As Exception
        Console.Out.WriteLine("Could not load the log4net config file")
    End Try

just a big set of TraceListeners: sorry skipping that one - I'll take your word for it.

Correlation of activities/scopes: do you mean like every file (read class) gets it's own named log that can have separate log level thresholds. In fact you can segment logging even in a single class (that in truth may have grown to do too much ...)

In a class file:

    Private Shared _logger As log4net.ILog = _
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)

Private Shared _loggerAttribute As log4net.ILog = _
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName & ".Attribute")

Private Shared _loggerCache As log4net.ILog = _
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName & ".Cache")

The Service Trace Viewer: in the log4net.config:

  <logger name="NipissingU.ADWrapper.EntryTools.Attribute">
    <level value="INFO" />
  </logger>
  <logger name="NipissingU.ADWrapper.EntryTools.Cache">
    <level value="WARN" />
  </logger>

All of it is configurable in app.config/web.config: well maybe that is a good thing in ASP.NET, I don't know, but when making rich client bean counting apps I like a separate config file.

Everything here is just my own little usage tricks.

hth, -Mike

Solution 2

In the very early days (.NET 1.0) tracing in the .NET Framework was pretty limited.

For example TraceSource partitioning didn't come until .NET 2.0 and you only had four levels (Error, Warning, Information, Verbose), although you could use half a dozen boolean switches for partitioning if you wanted.

log4j is popular in Java and so got a lot of support for a .NET port, and once it became popular it kind of stayed that way, even though people don't even use it properly (e.g. wrapping it in a singleton logger and losing it's main feature).

Still, I think that log4net and other frameworks (e.g. NLog, Common.Logging, and even EntLib) went the wrong way by implementing their own logging system from the ground up, i.e. changing even the way you write log statements in the first place.

I would have much preferred to see effort, especially since .NET 2.0, put into extending the solid basis of what is already in .NET. For a project that does extend what is already there, have a look at the Essential Diagnostics project on CodePlex (http://essentialdiagnostics.codeplex.com/).

Some strengths of log4net:

  • It is similar to log4j, if you run a mixed environment and want consistent logging.

  • Automatic logger hierarchy that inherits settings is quite neat, compared to how many trace sources you implement and have to configure each. (although probably overkill in some cases).

  • log4net already has around 28 appenders (equivalent to trace listeners), whereas System.Diagnostics only has 10 (but see the Essential.Diagnostics project for more), so if you really think you may need the RemoteSyslogAppender, NetSendAppender, AnsiColorTerminalAppender or TelnetAppender, then you are in luck.

Drawbacks (compared to System.Diagnostics):

  • You need to use different logging syntax, so if you are already using source.TraceEvent(), you need to go through and replace everything.

  • This also extends to different syntax for correlation, so you need to change from CorrelationManager to log4net contexts.

  • Doesn't easily integrate with Framework tracing (e.g. WCF).

  • Poor support for Event ID's (need to use a separate extension project IEventLog).

  • Doesn't yet support Event Tracing for Windows (Vista), or the Service Trace Viewer XML format.

Solution 3

Another reason for using TraceSources instead of Log4Net is Tracing itself: Log4Net can only be used for Logging (messages) but how to trace an Object (multiple informations at the same time)? Of course Log4Net has a lot of Listeners implementd, but do I need all these? In most of cases not. And if I need a special listener, it's not as hard do implement my own one, isn't it? For example i neede a listener to trace into a database (not only messages but different informations {string's, int's, etc.} at the same time).

Are I'm right?

Solution 4

The reason that I prefer Log4Net to using Trace one of targeting - with Log4Net, I can independently instrument different layers of my application (Data Access, Services, Business Logic, etc) and different subsystems (Authentication, Processing, etc) and turn on/off the logging of each subsystem independently.

This flexibilty allows me to configure detailed logging for one subsystem without turning on the firehose for the entire system.

The static methods provided on the Trace class [such as TraceInformation()] don't provide any way to specify which subsystem the logging is from, so this isn't something easily provided by writing my own TraceListener.

Another reason is performance - there are piece of my application that potentially log several thousand messages per second. Log4Net imposes a low overhead. By contrast, last time I looked at it, The Logging Application block reparsed its XML configuration for every message logged, making the block very heavy and slow.

Share:
18,143
Paul Stovell
Author by

Paul Stovell

I live in Brisbane and work full time bootstrapping my own product company around Octopus Deploy, an automated deployment tool for .NET applications. Prior to Octopus Deploy, I worked for an investment bank in London building WPF applications, and before that I worked for Readify, an Australian .NET consulting firm, where I was lucky enough to work with some very talented people. I also worked on a number of open source projects and was an active user group presenter. I've been a Microsoft MVP for WPF since 2006. I have a blog at paulstovell.com.

Updated on June 05, 2022

Comments

  • Paul Stovell
    Paul Stovell almost 2 years

    In this thread many people have indicated that they use log4net. I am a fan of TraceSources and would like to know why log4net is used.

    Here is why I like trace sources:

    • Pluggable listeners - XML, TextFile, Console, EventLog, roll your own
    • Customisable trace switches (error, warning, info, verbose, start, end, custom)
    • Customisable configuration
    • The Logging Application Block is just a big set of TraceListeners
    • Correlation of activities/scopes (e.g., associate all logs within an ASP.NET request with a given customer
    • The Service Trace Viewer allows you to visualize events against these activities individually
    • All of it is configurable in app.config/web.config.

    Since the .NET framework internally uses TraceSources, it also gives me a consistent way of configuring tracing - with log4net, I have to configure log4net as well as TraceSources.

    What does log4net give me that TraceSources don't (or that couldn't be done by writing a couple of custom TraceListeners)?

  • Paul Stovell
    Paul Stovell about 15 years
    Re: performance. I'd be surprised if this is still the case, but it's certainly something I'll investigate. How do people cope with reading a thousand log messages per second? :)
  • Paul Stovell
    Paul Stovell about 15 years
    thanks Mike. Correlation is a little different - you can associate a guid and metadata about a log "context" - all traces from there until the context is "closed" are then related to that context. makes it easy to see all logs related to a particular Order or Customer for example
  • Paul Stovell
    Paul Stovell about 15 years
    by contrast, having different log files per customer/order could be quite annoying
  • Paul Stovell
    Paul Stovell about 15 years
    the contexts also support nesting from what i can tell, though i haven't tried this
  • stimms
    stimms about 15 years
    I knew that speed reading course would come in handy
  • Bevan
    Bevan about 15 years
    Comes down to the blurry gray line between tracing and logging - logging of major events, vs tracing of process details. Sometimes the only way to diagnose a problem with a production system is to trace through a really detailed log with a magnifying glass.
  • Bevan
    Bevan about 15 years
    Looks as though I need to investigate the TraceSource class more closely - thanks for the pointer.
  • Sly Gryphon
    Sly Gryphon over 13 years
    Mike, you pretty much just confirmed that log4net does everything that is already built into TraceSource in the .NET Framework. The question was "What does log4net give me that TraceSources don't?", i.e. what additional things does log4net provide beyond plain .NET.
  • Mike Bonnell
    Mike Bonnell over 13 years
    The source? I have tweaked a couple of things. ... but I'm not trying to sell anyone just saying that I got X to work well but that doesn't dimmish Y
  • Mark
    Mark over 13 years
    Indeed I believe you are (at least on the TraceSource side)
  • Sly Gryphon
    Sly Gryphon almost 13 years
    See the Essential Diagnostics project on Codeplex (essentialdiagnostics.codeplex.com) for a System.Diagnostics TraceListener with pattern/format support, as well as an interface and facade for TraceSource (although you can test by simply attaching a test trace listener).
  • Sergey Berezovskiy
    Sergey Berezovskiy over 12 years
    If you miss AUDIT level, just add it. You can add audit extension for ILog and call there logger.Log(declaringType, new Level(value, "AUDIT"), message, null).
  • Sly Gryphon
    Sly Gryphon about 11 years
    Bevan - the question asked about TraceSource (which does support multiple subsystems) not the static methods on Trace. Also for performance you made a comparison to Logging Application Block (from EntLib), which is again a different thing. The speed of log4net and TraceSource is very comparable (but yes, EntLib/LAB is slow, hence why I prefer TraceSource).