Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Diagnostics Traces wildcard for source name

I have my Logging set up to use a different TraceSource for each Class.

Is it possible to Configure a wildcard that writes events for all Sources?

<system.diagnostics>
  <sources>
    <source name ="wildcard" switchValue="Warning">
      <listeners>
        <add name="textlog" />
      </listeners>
    </source>
    <source name="MySpecificClass" switchValue="All">
      <listeners>
        <add name="textlog" />
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add name="textlog"
         type="System.Diagnostics.TextWriterTraceListener"
         initializeData="Log.log">
    </add>
  </sharedListeners> 
  <trace autoflush="true"/>
</system.diagnostics>
like image 939
Jos Vinke Avatar asked Mar 21 '13 17:03

Jos Vinke


1 Answers

I'm not aware of a built in way to do that automatically. However, if you have a look at the TraceLogger in Castle's git repository, you can see that they have essentially wrapped and extended TraceSource to support "hierarichal" naming.

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

I would copy the code here, but it might not be proper to just cut and paste there code into SO.

I can explain how the ideas presented in the class could work for your (without you having to use Castle)

In essence, in your client code (that wants to log stuff), you would create an instance of your "logger" (rather than TraceSource). As input to the logger, you would give, for example, the fully qualified class name. Inside the constructor, use the input name to try to resolve a TraceSource. If there is a TraceSource configured with that name, use that TraceSource to do the work. If not, trim off the rightmost part of the fully qualified name. Try to resolve a TraceSource with that name. If there is a TraceSource configured with that name, use it. And so on. If you don't find any TraceSources, then don't log anything from your "logger". You could add on the ability to recognize a TraceSource that has been configured with a wildcard name (""). If you never find a TraceSource using the name trimming technique and if there is a "" TraceSource, use the "*" TraceSource as the fallback.

So, you might have something like this:

class MyTraceSource
{
  private TraceSource ts;

  public MyTraceSource(string name)
  {
    ResolveTraceSource(name);
  }

  private void ResolveTraceSource(string name)
  {
    //Check for a configured TraceSource from most qualified name (as input) to least qualified ("").
    //Assume name like this:  Namespace1:Namespace2:Class
    //Try to resolve:
    // TraceSource("Namespace1.Namespace2.Class");
    // TraceSource("Namespace1.Namespace2");
    // TraceSource("Namespace1");
    //If you still haven't found one, try to resolve
    // TraceSource("*");
  }

  //Implement either TraceSource API, or whatever API you prefer for logging.

}

I have actually done something like this myself as part of a prototype (that we ended up not using) and it worked pretty well for mimicking the way that you can specify loggers in log4net and NLog.

Good luck!

like image 119
wageoghe Avatar answered Oct 05 '22 23:10

wageoghe