Search code examples
c#trace

TraceSource logging creates duplicates of logs


I've implemented TraceSource logging within my application. This log tracks failed login attempts and errors.

When I run the program and generate my first error, my file CommissionLog.log is created and the error is contained within but also another file is created with what appears to be an id example: 62-60ae-3423sfd4534-42342-7sdfsfh4s3c142Commission.

However, if I generate another error the error is added to the original log file but also creates another file, the first duplicated file does not receive the new error.

Obviously I've implemented the TraceSource logging incorrectly, but I can't see why it would be creating duplicate logs. If I generate another error, another file is created.

But the original log file keeps updating, very confused.

Here's a really simple replication without details of my DB/connection as I don't feel it's needed for the recreation

private void Login_Btn_Click(object sender, EventArgs e) 
{
   bool userExists = false;
   // Logging (get users application data path)
           
   var roamingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
   var filePath = Path.Combine(roamingDirectory, "Commission.log");
   Trace.Listeners.Add(new TextWriterTraceListener(filePath, "myListener"));

   try 
   {
      if(!userExists) 
      {
          // Logging
          Trace.TraceInformation(DateTime.Now.ToShortDateString() + " | " + DateTime.Now.ToLongTimeString() + " - User login failed. Exception: User ID not found");
      }

   }
   catch(Exception ex) 
   {
      // Logging
      Trace.Listeners.Add(new TextWriterTraceListener(filePath, "myListener"));
      Trace.TraceInformation(DateTime.Now.ToShortDateString() + " | " + DateTime.Now.ToLongTimeString() + " - " + ex.ToString());
   }


   Trace.Flush();
}

If I run this, I get 2 files, my log file and a duplicate containing

Commission Information: 0 : **/**/**** | **:**:** - User login failed. Exception: User ID not found

Here's where I create the config file to get it all working

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <trace autoflush="false" indentsize="4">
            <listeners>
                <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\\Commission.log" />
                <remove name="Default" />
            </listeners>
        </trace>
        <sources>
            <source name="TraceTest"
              switchName="sourceSwitch"
              switchType="System.Diagnostics.SourceSwitch">
                <listeners>
                    <add name="console"
                      type="System.Diagnostics.ConsoleTraceListener">
                        <filter type="System.Diagnostics.EventTypeFilter"
                          initializeData="Error"/>
                    </add>
                    <add name="myListener"/>
                    <remove name="Default"/>
                </listeners>
            </source>
        </sources>
        <switches>
            <add name="sourceSwitch" value="Error"/>
        </switches>
    </system.diagnostics>
</configuration>


Solution

  • The reason why you are getting files than expected is that you use Trace.Listeners.Add multiple times. Usually you should use that command only once per Listener per app.

    I imagine Listener as a type of logger - you could have Listener to send your logs to file, another one for console, another one for Seq.

    What you are doing is that with every button click you add new instance of file listener so from now on every listed Listener you've added is writing to new file and so on.

    I am guessing because you register it multiple times Trace is generating another file (with guid) to prevent concurrent file writes.