Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using more than one trace listeners

I have 2 WCF services which I am hosting from a single windows host. I use trace listener which logs the data into application logs. I have added following code into the config file.

<system.diagnostics>
<switches>
  <add name="ReaderService.Switch" value="4"/>
  <add name="InfoService.Switch" value="4"/>
</switches>
<trace autoflush="false" indentsize="4">
  <listeners>
    <add name="EventLogTraceListener"
      type="System.Diagnostics.EventLogTraceListener"
      initializeData="ReaderServiceLog" />
  </listeners>
</trace>
</system.diagnostics>

All the logs from both the services appear under source ReaderServiceLog name. What I want to do is, logs from each service should appear under different source name.

For example, Logs from ReaderService should appear under name ReaderServiceLog and logs from InfoService should appear under InfoServiceLog. I modified my config like the following.

<system.diagnostics>
<switches>
  <add name="ReaderService.Switch" value="4"/>
  <add name="InfoService.Switch" value="4"/>
</switches>
<sources>
  <source name="EventLogTraceListener">
    <listeners>
      <add name="EventLogTraceListener"
      type="System.Diagnostics.EventLogTraceListener"
      initializeData="ReaderServiceLog" />
    </listeners>
  </source>
  <source name="InfoService">
    <listeners>
      <add name="EventLogTraceListener"
      type="System.Diagnostics.EventLogTraceListener"
      initializeData="InfoServiceLog" />
    </listeners>
  </source>
</sources>
</system.diagnostics>

and used this code:

private TraceSource ts = new TraceSource("InfoService");
ts.TraceInformation(outputMessage, aslErrorText);
ts.Flush();

But it does not work. It does not log anything at all.

I also tried this. But it does not work.

<system.diagnostics>
<switches>
  <add name="ReaderService.Switch" value="4"/>
  <add name="InfoService.Switch" value="4"/>
</switches>
<sources>
  <source name="ReaderService"
          switchValue="Information, ActivityTracing">
    <listeners>
      <add name="EventLogTraceListener"/>
    </listeners>
  </source>
  <source name="InfoService"
          switchValue="Information, ActivityTracing">
    <listeners>
      <add name="EventLogTraceListener"/>               
    </listeners>
  </source>
</sources>
<sharedListeners>
  <add name="EventLogTraceListener"
       type="System.Diagnostics.EventLogTraceListener"
       initializeData="ServiceLog" />
</sharedListeners>

I used the same c# code as above. This code does the logging properly, but again, It's under the same name for both the services. i.e. ServiceLog.

Am I missing something here? OR Is there any other way around. Please help

like image 486
Newbee Avatar asked Apr 22 '13 12:04

Newbee


1 Answers

This config adds 2 different trace sources (With file listeners; You may want to change listeners and directory path if you like):

<?xml version="1.0"?>
<configuration>
  ...
  <system.diagnostics>
    <switches>
      <add name="data" value="All" />
      <add name="error" value="All" />
    </switches>
    <sources>
      <source name="DataSource" switchName="data" switchType="System.Diagnostics.SourceSwitch">
        <listeners>
          <clear />
          <add name="dataListener" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
             initializeData="FileLogWriter"
             Append="true"
             AutoFlush="true"
             BaseFileName="data"
             CustomLocation="D:\Log\App\Data"
             DiskSpaceExhaustedBehavior="DiscardMessages"
             Encoding="Unicode"
             IncludeHostName="false"
             LogFileCreationSchedule="Daily"
             location="Custom"
             MaxFileSize="900000000000" />
        </listeners>
      </source>
      <source name="ErrorSource" switchName="error" switchType="System.Diagnostics.SourceSwitch">
        <listeners>
          <clear />
          <add name="errorListener" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
             initializeData="FileLogWriter"
             Append="true"
             AutoFlush="true"
             BaseFileName="error"
             CustomLocation="D:\Log\App\Error"
             DiskSpaceExhaustedBehavior="DiscardMessages"
             Encoding="Unicode"
             IncludeHostName="false"
             LogFileCreationSchedule="Daily"
             location="Custom"
             MaxFileSize="900000000000" />
        </listeners>
      </source>
    </sources>
    <trace autoflush="true">
      <listeners>
        <clear />
        <add name="defaultListener" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
             initializeData="FileLogWriter"
             Append="true"
             AutoFlush="true"
             BaseFileName="program"
             CustomLocation="D:\Log\App\Program"
             DiskSpaceExhaustedBehavior="DiscardMessages"
             Encoding="Unicode"
             IncludeHostName="false"
             LogFileCreationSchedule="Daily"
             location="Custom"
             MaxFileSize="900000000000" />
        <add name="programConsoleListener" type="System.Diagnostics.ConsoleTraceListener" />
      </listeners>
    </trace>
  </system.diagnostics>
  ...
</configuration>

And to use it define your TraceSource:

static TraceSource dataSource = new TraceSource("DataSource");
static TraceSource errorSource = new TraceSource("ErrorSource");

To work more easily (for some scenarios) with a TraceSource I've written an extension method:

public static void WriteLine(this TraceSource source, object o)
{
    var str = (o ?? string.Empty).ToString();

    if (source.Listeners == null || source.Listeners.Count == 0) throw new InvalidOperationException(string.Format("TraceSource named {0} has no listeners", source.Name));

    foreach (TraceListener listener in source.Listeners)
        listener.WriteLine(str);
}

That worked for me.

But you can not categorize TraceSource in one app domain based on the code block that is calling it.

like image 52
Kaveh Shahbazian Avatar answered Nov 15 '22 01:11

Kaveh Shahbazian