July 13, 2004
I've been doing a comparison of both products recently. Before you read, I must
say that I used log4net
a lot (I even appear as a contributor :o), so I may be biased. On the other hand,
I only evaluated EIF, looked at how it's used in a real world product, and read
the documentation provided, as well as built the examples.
Here are my conclusions.
Conventions:
- x: feature is supported equally.
- -: feature is supported/implemented, but is not as good as the other product
- +: feature is better supported/implemented than the other product
| Feature
|
EIF
|
log4net |
General
|
|
|
Decoupling of event source and event sink
|
x |
x |
Arbitrary target event sinks
|
x |
x |
Number of built-in event sinks supported
|
3 |
20 |
Extensible
|
x
|
x |
Configuration
|
-
(quite complex) |
+
(very simple) |
WMI supported built-in
|
x |
|
Arbitrary log data
|
+ |
-
(built-in just text)
|
Multiple logging "domains" (ability to configure the framework
by modules, i.e. each logical feature has its own config, repository and
sinks)
|
|
+++
(a BIG plus for highly composed and pluggable apps) |
Installation
|
-
(mostly requires admin permissions)
|
+
(xcopy)
|
Support
|
? |
x
(excelent peer support)
|
Source provided |
|
+ |
Supported Platforms
|
.NET
|
.NET, CF, Mono, SSCLI |
| |
|
|
| Runtime |
|
|
Performance with logging enabled
|
x |
x |
Performance with logging disabled for a certain event
|
- |
++
(orders of magnitude faster) |
Reconfiguration
|
-
(only possible with WMI or Windows Trace) |
+
(full configuration monitoring & reloading) |
| |
|
|
API - Dev friendliness |
|
|
Event (source) categorization
|
-
(uses the event Type. leads to increasingly big hierarchies of event types) |
++
(combination of log level + logger name -dotted notation-) |
| Event source inheritance |
|
++
(filters and sinks applied to all descendant sources) |
Customization
|
x |
+
(everything) |
| |
|
|
One of the "distinguishing" features of EIF is request tracing, but
it is mostly irrelevant as it only works using the remoting CallContext, which
reduces its applicability considerably. And remoting is not a long-term platform
to rely on either... For request-like tracing on a single thread (important
when there're multiple components involved in an operation happening on a single
machine/thread) log4net offers similar functionality through its Nested Diagnostics
Context.
For business events that rely on arbitrary objects being send, EIF has a clear
advantage. I wonder, however, how many business notification scenarios are actually
handled through logging... Through customization similar functionality could
be implemented in log4net, however.
Overall: both seem like good logging packages. EIF may be
more manageable as it has strong relationship with WMI. log4net, on the other
hand, clearly wins on simplicity and in my opinion satisfies most common logging
and tracing needs.
Except for the extra WMI stuff (which can also be implemented as custom extensions
to log4net - I've done it) and arbitrary objects publication (also achievable,
but requiring more work), I'd choose log4net.
Side Note
log4net "event source" (loggers): in log4net, you
ask for a logger to the LogManager. Using a simple dotted syntax, you create
hierarchycal loggers that inherit sinks, filters and threshold very easily.
For example, the following code asks for a logger and logs an informational
message:
ILog log = LogManager.GetLogger("Finance.Accounting.Customers.Administration");
if (Log.IsInfoEnabled)
{
log.Info("Adding user " + _userId);
some other component in the same module may use the following:
ILog log = LogManager.GetLogger("Finance.Accounting.Orders");
if (Log.IsInfoEnabled)
{
log.Info("Adding order " + _orderId);
}
All the "Finance" application, or the "Accounting" module
can be configured in a single place, and affect both components. A common use
is to pass the current component type to the GetLogger() method, therefore making
the logger match class full names, which is also an easy way to configure groups
of components or modules in an application. For example:
<!-- Enables all logging events in finance application (both components above) -->
<logger name="Finance ">
<level value="ALL" />
</logger>
<!-- Enables INFO logging events in accounting module (both components above) -->
<logger name="Finance.Accounting">
<level value="INFO" />
</logger>
<!-- Enables INFO logging events in Orders module (only for the last code above) -->
<logger name="Finance.Accounting.Orders">
<level value="INFO" />
</logger>
Custom logger levels can be used directly, without previous definition, for
example "BusinessEvent" or "CriticalOperation". This functionality,
combined with hierarchycal loggers is very flexible and completely removes the
need in EIF for defining custom types for every event. In addition, arbitrary
key-value (only strings) can be logged by using a so-called Mapped Diagnostics
Context. Functionality similar to request tracing in EIF is available through
Nested Diagnostic Context, that is threads-specific.
I'd love to hear arguments in favor of EIF. I may be missing some other features
it has to offer, or I may have misunderstood some of its functionality, as (like
I said) I haven’t used it before.
Have you used both products? What do you think about the points made above?
About the author
Daniel Cazzulino
kzu@aspnet2.com
Blog: http://clariusconsulting.net/blogs/kzu/
Daniel Cazzulino (a.k.a. kzu) lives in Buenos Aires, Argentina, and is a senior architect, developer, and cofounder of Clarius Consulting S.A. He has coauthored several books on Web development and server controls with ASP.NET, written and reviewed many articles for ASP Today and C# Today, and currently enjoys sharing his .NET and XML experiences through his blog at http://clariusconsulting.net/blogs/kzu/.
|