|
|
|
|
|
|
|
|
|
|
The Log4Net mailing list is a great source of information about using log4Net, in this forum we collect all the messages in the log4net user list and some selected threads from the developer list.
| Author |
Messages |
|
shaeney
 |
| 10/22/2007 12:13 PM |
|
Hello all, I have been asked to compare the Log4Net library with the Microsoft patterns & practices Logging Application Block.
I have searched this forum but can't find anyone who has asked this question previously. I would have thought this is a common topic.
Does anyone know if this type of side-by-side comparison has been done? I know that both are very extensible, but I am interested in comparing the core deliverables. In particular, I am interested in using either for both Logging and Auditing purposes.
Audit will require transactions, which is to say that the calling code needs to know if the Audit message has been persisted or not before it can continue.
Cheers, Steve -- View this message in context: http://www.nabble.com/Newbie%3A-Log4Net-or-MS-Logging-Application-Block--tf4669838.html#a13339938 Sent from the Log4net - Users mailing list archive at Nabble.com.
|
|
|
|
|
Walden H. Leverich
 |
| 10/22/2007 3:34 PM |
|
> Audit will require transactions, which is to say that the calling code needs >to know if the Audit message has been persisted or not before it can >continue.
From the log4net FAQ on the Apache site: "Is log4net a reliable logging system?" "No. log4net is not reliable. It is a best-effort and fail-stop logging system."
I don't love the use of the word "reliable" as everyone wants to use something that's reliable, but the point of the statement is, IF something fails in log4net it was designed to NOT stop the application from running. Now, you could probably rework some of the plumbing, but I think log4net is orthogonal to an audit log.
Having said that, you'll have to pry log4net out of my cold dead hands. :)
-Walden
-- Walden H Leverich III Tech Software (516) 627-3800 x3051 WaldenL@TechSoftInc.com http://www.TechSoftInc.com
Quiquid latine dictum sit altum viditur. (Whatever is said in Latin seems profound.)
|
|
|
|
|
Mike Liddell
 |
| 10/23/2007 2:40 AM |
|
For my purposes, Log4net is better in every respect. I wish I knew this two years ago.
I am the architect for a medium-sized distributed project that is perhaps in the 200-300K lines category. We started with EntLib logging but never really enjoyed it - the configs and the lack of built-in filtering options was limiting. During a recent comparison I also found the logging generation rate (eg max number of calls to Logger.Log() can be made, particularly when the messages are being filtered out and not delivered anywhere) is unexpectedly slow.
To cut to the chase, I did a full side-by-side comparison and decided to ditch entlib logging in favour of log4net without any hesitation. The primary considerations were: - log generation rate. the raw speed of log4net is excellent - hierarchical logging. and well implemented too. - cleaner, much more extensible and obvious config format - easier programmatic extensibility - more built in log targets (ie the standard appenders) - generally a much more _professional_ library. Entlib is a good idea.
Every time I use log4net I am happily surprised.
cheers, Mike Liddell
|
|
|
|
|
shaeney
 |
| 10/23/2007 9:53 AM |
|
OK, that very good information.
I see that the MS Logging Application Block (LAB) allows messages to be routed based on "Category" and each message contains a collection of name-value pairs of meta data.
What is the corresponding Log4Net technology? From what little I have seen, messages are routed based on Class Type?
I think that LAB is synchronous by default, with asnyc comms achieved via MSMQ, but Log4Net is async by default?
Cheers, Steve
|
|
|
|
|
Mike Liddell
 |
| 10/23/2007 10:10 AM |
|
I am not a log4net expert... so please consult others too and do your own investigation.
:: Category vs. log4net filtering - Category is a flat filter rule. log4net hierarchy is much more powerful. for additional filtering on other attributes, add info to the properties and/or stacks and filter on them.
- Only use named properties where they are globally relevant as you have to type them verbatim into your configs. - Use a generic property bag otherwise, eg Property{Tags} rather than Property{TagA} + Property{TagB}
Important notes: - for adding custom properties and stacks that are simple data, not thread-state etc, you must avoid using the ThreadContext approach even though it is the obvious first attempt. It is incredibly slow. eg 10K logs/second rather than say 1million logs/second. rather, use a wrapper that performs log.Logger.Log( manualLogEvent).
- also, follow the pattern of creating a static Logger instance once per unit (and their recommendation of one per class seems sound and that is what I am using). it is far too expensive to instantiate a Logger for every log() call. I personally have my own wrapper object that includes a Logger instance and I create a static one of those per code class. I am budgeting about 100bytes per instance at, say, 10K classes max for 1MB working set usage. I'm not sure if this is accurate.
- use Text or Property filters to perform filtering on your custom property
:: MSMQ I don't currently have a need for MSMQ appender. I expect someone already has made it. If the EntLib one is not too tricky, you would be able to reproduce it quickly by extending AppenderSkeleton.
:: Async Log4net is synchronous too. I'm not sure if there is asynch for normal targets.
hope it helps,
Mike.
|
|
|
|
|
shaeney
 |
|
José Joye
 |
| 10/23/2007 1:06 PM |
|
Here are my 2 cents:
About 1 year ago, we had to decide on the same topic. At that stage, based on quick tests and Web information, we decided to use log4net. By the way, ee also had the requirement of using it in Compact Framework. Frankly, we never regreted our choice :-)
However. in order not to be too hardly tight to log4net, we decided to build a facade to abstract the Logging framework. This was done in order to easily switch the logging framework we use behind the scene.
José
|
|
|
|
|
shaeney
 |
| 10/23/2007 2:12 PM |
|
José Joye wrote: > > However. in order not to be too hardly tight to log4net, we decided > to build a facade to abstract the Logging framework. This was done in > order to easily switch the logging framework we use behind the > scene. > > José >
Thanks Jose, I had already decided to take that approach in case we wanted to swap out the underlying framework at some point.
I am going to produce a test-bed app using both frameworks and see how I get on with both synchronous and asynchronous messaging. If I get time, I will move onto logging from different AppDomains etc
Cheers, Steve -- View this message in context: http://www.nabble.com/Newbie%3A-Log4Net-or-MS-Logging-Application-Block--tf4669838.html#a13362856 Sent from the Log4net - Users mailing list archive at Nabble.com.
|
|
|
|
|
Walden H. Leverich
 |
| 10/23/2007 3:09 PM |
|
> I personally have my own wrapper object that includes a Logger instance and I create a
>static one of those per code class. I am budgeting about 100bytes per instance at, say,
>10K classes max for 1MB working set usage. I'm not sure if this is accurate.
I assume you mean 10K instances, not 10K classes, that would be one hell of a class library. J
Assuming it is indeed instances then why are you counting bytes per instance? What instance data are you storing? We’ve gone with the one logger instance per class via a static logger and since it’s static it would not add any storage to the instance, right? What am I missing?
-Walden
--
Walden H Leverich III Tech Software (516) 627-3800 x3051
WaldenL@TechSoftInc.com http://www.TechSoftInc.com
Quiquid latine dictum sit altum viditur. (Whatever is said in Latin seems profound.)
|
|
|
|
|
Peter Drier
 |
| 10/23/2007 4:03 PM |
|
I worked at a financial firm a few years back before the Logging Application Block existed.. Microsoft came to us and asked us what we wanted next from them in the area of Application Blocks.. Logging was one of the choices in their potential near term plans..
Everyone in the room, including those from Microsoft, agreed that log4net was so good that Microsoft should spend it's development time elsewhere. Boy do I wish I had that on video..
A few months later, the Exceptions handling block came out.. Look under the covers, it's the same pattern as log4net.. More months later, and their logging block came out, looking nothing like log4net, or their exception block.. We collectively went WTF, gave up on Microsoft doing anything useful for the Wall Street / Finance community, and moved on..
log4net is still the primary logging mechanism for every dotnet app I've touched in the last 5 years.. Nobody is using Application blocks on a Front office trading platform to the best of my knowledge..
-Peter
|
|
|
|
|
Mike Liddell
 |
| 10/24/2007 6:54 AM |
|
Hi,
it was just my back of the envelope guess at total working set usage when I was considering the one-static-logger-per-code-class approach, which was new to me at the time.
this was my thinking... 10K code classes is definitely an upper limit, and 100-1000 is probably the common range. I might also have some non-code-class loggers and so I assumed that 10K in-memory logger instances is a reasonable upper limit. I haven't yet determined how big a log4net logger instance is, but I though 100bytes for the string name and some ancillary items, with references into a common hierarchy object that I presume isn't particularly heavy for consumption. I couldn't quickly think of a way to determine the byte-count of of per-logger-instance data, and/or the per-application data. On these number I figured that at most 1MB would be devoted to log4net data in a big app, which is totally fine.
Does anyone have some hard data - should I worry about memory footprint?
regards, Mike.
|
|
|
|
|
Peter Drier
 |
| 10/24/2007 4:05 PM |
|
I've seen many people wrap log4net just so they could swap it out down the road..
Doing that, you lose the context sensitivity of having a logger in each class.. one of log4net's greatest strengths..
And I've never ever seen it actually replaced down the road.. It makes much more sense to create a custom appender to write to whatever system you need down the road, while still using log4net as the plumbing within your application.
I'd advise HEAVILY against wrapping log4net to everyone. You will be trading a strength for a sense of flexibility you'll never actually use.
-Peter
|
|
|
|
|
Owen Corpening
 |
| 10/24/2007 4:19 PM |
|
I second that, but beyond “me-too”, the only thing I need that I don’t have currently is aspect-based logging or the equivalent. In general I have concluded that .net aspect technologies are not-there-yet.
I want to be able to add logging at build or runtime, ideally for runtime I can just add a jar with some kind of config file to an existing app and get the logging I need …
Obviously no amount of wrapping will even lead in such a direction …
Or maybe just-in-time logging, where it will somehow without a performance penalty buffer the last bit of logging then when an exception happens start logging 5 minutes ago ….
As for wrapping for “down the road” I have not seen many applications even make it down the road … they all keep getting rewritten or close to it as new technologies keep arriving … so log4net being the best-in-breed I say use it ….
owen
|
|
|
|
|
Michael Schall
 |
| 10/25/2007 12:21 AM |
|
We wrap log4net and have had no issues and we have a logger for each class. I have not swapped it out as your argument suggests, but I don't like to use any library directly. It shields you not only from swapping out a library, but from breaking changes in the library you are wrapping. Most of my wrapper is below... Am I missing something? I'm hopping this would allow me to switch to say nLog if I wanted...
Public Interface ILogger
Sub Debug(ByVal format As String, ByVal ParamArray args() As Object) Sub Info(ByVal format As String, ByVal ParamArray args() As Object) Sub Warn(ByVal format As String, ByVal ParamArray args() As Object) Sub [Error](ByVal format As String, ByVal ParamArray args() As Object) Sub Fatal(ByVal format As String, ByVal ParamArray args() As Object)
Sub Debug(ByVal format As String, ByVal exception As Exception, ByVal ParamArray args() As Object) Sub Info(ByVal format As String, ByVal exception As Exception, ByVal ParamArray args() As Object) Sub Warn(ByVal format As String, ByVal exception As Exception, ByVal ParamArray args() As Object) Sub [Error](ByVal format As String, ByVal exception As Exception, ByVal ParamArray args() As Object) Sub Fatal(ByVal format As String, ByVal exception As Exception, ByVal ParamArray args() As Object)
ReadOnly Property IsDebugEnabled() As Boolean ReadOnly Property IsInfoEnabled() As Boolean ReadOnly Property IsWarnEnabled() As Boolean ReadOnly Property IsErrorEnabled() As Boolean ReadOnly Property IsFatalEnabled() As Boolean
End Interface
Public NotInheritable Class LogManager
Public Shared Sub Configure(ByVal configFile As FileInfo)
If configFile Is Nothing Then Throw New System.ArgumentNullException("configFile") End If
System.Diagnostics.EventLog.WriteEntry( _ String.Format("{0}.LogManager", Process.GetCurrentProcess.ProcessName), _ String.Format("Configuring logging using configuration file {0}", configFile.FullName))
log4net.Config.XmlConfigurator.ConfigureAndWatch (configFile)
GetLogger(GetType(LogManager)).Debug("Configured logging using configuration file {0}", configFile.FullName)
End Sub
Public Shared Function GetLogger(ByVal type As System.Type) As ILogger Dim logger As log4net.ILog = _ log4net.LogManager.GetLogger(System.Reflection.Assembly.GetCallingAssembly(), type) Return New Log4NetAdapter(logger) End Function
End Class
Friend Class Log4NetAdapter Implements ILogger
Private _inner As ILog
Friend Sub New(ByVal log4netLogger As ILog) _inner = log4netLogger End Sub
'Implement interface methods delegating to _inner
End Class
|
|
|
|
|
si
 |
|
|
| You are not authorized to post a reply. |
|
|
|
ActiveForums 3.7
|
|
|
|
|
|
|
|
|
|
Log4Net Dashboard
Log analysis and monitoring made easy!
Log4Net Dashboard is a log viewer that can read log statements from a variety of logging output targets.

Check it out!
On the demonstration site you can try it with live data.
|