Class based trace sources for System.Diagnostics

770 Views Asked by At

I'm currently migrating from log4net as a logging framework to the System.Diagnostics namespace in order to use 1) a .net built-in framework already available and b) use it's powerful features like activity tracing.

With log4net, I'm used to request the loggers on a class-based way e.g.

private readonly ILog Logger = LogManager.GetLogger(typeof(MyClass).Name);

However with the TraceSource, it seems like you have to configure each trace source manually in app.config in order to use it. Isn't there a way to create some shared listeners and just use them, with 'global filters' for the TraceEventType etc. (e.g. EventLogListener handles Warning/Error, when property "XY" is set, a console listener is active, else log to file etc.)

2

There are 2 best solutions below

0
On

Here is a sample. You can set up shared listeners. So a given listener only need be configured once. (You still have to map listeners to sources over and over)

The sources can use named switches, and those should be sharable (i.e. two sources use the same switch).

In your question you use the word "filter" which roughly corresponds to a switch value. Filters exist in Systems.Diagnostics trace too, but they are objects that reduce the amount of things a listener responds to based on a variety of criteria, not just the switch value.

 <system.diagnostics>
      <switches>
          <add name="IdentityStuff" value="Verbose"/>
          <add name="OtherStuff" value="Verbose"/>
      </switches>
    <sources>
      <source name="Microsoft.IdentityModel" switchName="IdentityStuff" >
        <listeners>
          <add name="xml"/>
        </listeners>
      </source>
      <source name="SomeOtherSource" switchName="IdentityStuff" >
        <listeners>
          <add name="xml"/>
        </listeners>
      </source>
    </sources>
      <sharedListeners>
          <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="WIFTrace.e2e" />
      </sharedListeners>
  </system.diagnostics>
0
On

I don't think that there is anything available in System.Diagnostics to provide this capability (I am thinking specifically of the ability to not have to explicitly configure each individual TraceSource in the app.config file) out of the box. However, if you don't mind writing a little bit of code, you could write your own wrapper to provide a "hierarchical TraceSource" capability. Take a look at what Castle has done in their TraceLogger:

https://github.com/castleproject/Core/blob/master/src/Castle.Core/Core/Logging/TraceLogger.cs

Let's assume that you have the following classes (and associated namespaces):

Namespace1.Namespace1_1.Class1
Namespace1.Namespace1_1.Class2
Namespace1.Namespace1_2.Class3
Namespace2.Namespace2_1.Class4
Namespace2.Namespace2_2.Class5

Castle's implementation would allow you to configure a TraceSource (in your app.config) using either the full classname or using a subset of the classname (starting from the namespace end).

So, for example, you could configure such that all TraceSources from Namespace1.Namespace1_1 logged at a certain level by specifying "Namespace1.Namespace1_1" as the TraceSource name. In your code, if you create a TraceSource (or, actually, create a wrapped TraceSource) with the full class name of Class1 or Class2, that TraceSource would log at the level configured for Namespace1.Namespace1_1.

Try looking at Castle's TraceLogger implementation and see if you could make something like that work for you.