2

I want to configure a FileTraceListeners in my application, that ignores 'verbose' level messages but logs 'information' level and above as well as 'start' and 'stop' events.

Everything is configured within the app.config file. However I cannot find the correct syntax for combining these different trace levels. The Syntax for filters is explained here.

Using a single filter for 'information' will correctly filter out everything that is not 'information', 'warning' 'error' or 'critical'. However I also want to include 'start' and 'stop' events.

I tried using 2 filters :

<filter type="System.Diagnostics.EventTypeFilter" initializeData="Information"/>
<filter type="System.Diagnostics.EventTypeFilter" initializeData="ActivityTracing"/>

I tried combining the initializeDate

with commas: initializeData="Information,ActivityTracing"

or semicolons initializeData="Information;ActivityTracing"

everything will just cause a syntax error.

How do I combine these two filters inside app.config?

(I am using the native .net 3.5 logging libraries and do not wish to change to log4net or another framework at this point.)

HugoRune
  • 13,157
  • 7
  • 69
  • 144

4 Answers4

2

My code looks like:

<filter type="System.Diagnostics.EventTypeFilter"   initializeData="Warning,ActivityTracing"/> 

and its works.

KernelPanic
  • 2,328
  • 7
  • 47
  • 90
Markii
  • 21
  • 2
1

I didn't try to use the <filter> but recently setup something similar and was successful by using the <switches> and <sources> elements. Here's how I did it:

 <system.diagnostics>
   <trace autoflush="true" indentsize="2" />
   <sources>
     <source name="SyncService" switchName="infoactivity">
       <listeners>
         <clear />
         <add name="file" />
       </listeners>
     </source>
   </sources>
   <switches>
     <add name="none" value="Off" />
     <add name="infoactivity" value="Information, ActivityTracing" />
     <...>
   </switches>
   <sharedListeners>
     <add name="file" type="System.Diagnostics.TextWriterTraceListener" 
          initializeData="sync.log" />
   </sharedListeners>
 </system.diagnostics>

Just change the switchName value to one of the defined switches to get the appropriate level of logging.

The code used a single static TraceSource wrapped up in a LogEvent smart enum class (I think I found an example on one of Jon Skeet's answers once).

public class LogEvent {
  public static readonly LogEvent SyncStart = new LogEvent(1, 
    "Sync Service started on {0}", TraceEventType.Start);
  public static readonly LogEvent SyncStop = new LogEvent(99, 
    "Sync Service stopped on {0}", TraceEventType.Stop);
  public static readonly LogEvent SyncError = new LogEvent(501, 
    "\r\n=============\r\n{0}\r\n==============\r\n", TraceEventType.Error);
  // etc

  private readonly int id;
  private readonly string format;
  private readonly TraceEventType type;
  private static readonly TraceSource trace = new TraceSource("SyncService");

  private LogEvent(int id, string format, TraceEventType type)
  {
    this.id = id;
    this.format = format;
    this.type = type;
  }

  public void Log(params object[] data)
  {
    var message = String.Format(format, data);
    trace.TraceEvent(type, id, message);
  }
}

and in the service code I liberally sprinkled in logging statements

LogEvent.SyncStart.Log(DateTime.Now);
LogEvent.SyncError.Log("What the??? -- " + e.Message);
LogEvent.SyncStop.Log(DateTime.Now);
Aaron Wagner
  • 5,739
  • 1
  • 31
  • 38
0

It says here that they can be bitwise combined: MSDN.

Have you tried initializeData="Information|ActivityTracing"?

smp
  • 61
  • 4
  • Thanks, it's a good Idea. Sadly, this also causes a ConfigurationErrorsException: "Could not create System.Diagnostics.EventTypeFilter". I think the initializeData is simply passed to the constructor as a string – HugoRune Jul 10 '12 at 13:40
  • Have you tried using 2 listeners? – smp Jul 11 '12 at 08:40
  • This may work for ConsoleTraceListeners (not sure), but two FileTraceListeners cannot write to the same file – HugoRune Jul 11 '12 at 14:08
0

I had the same question. I eventually tried just putting in the decimal value for the bitwise combination of the TraceEventType values I wanted. It worked. In my case I wanted Critical, Error, Information and Warn to go to one listener. I set the value to 1 | 2 | 8 | 4 = 15. I had another listener I wanted just Verbose going to so I set the value to 16. I then set the source's switch to 16 | 15 = 31.

example (snippet):

<filter type="System.Diagnostics.TextWriterTraceListener" initializeData="15"/>

<switches>
    <add name="sourceSwitch" value="31"/>
</switches>

Thanks, Nick