2

I've written a library that gets called by several applications all residing in the same folder. Currently it's using log4net with the log4net.config file for event logging which works well. But log4net is now a dormant project with no foreseeable updates, and it appears that EventLogTraceListener can accomplish much the same thing without relying on a 3rd party library. However, I'm not sure there's a way to use an app.config file (out of the box) with a DLL. For example, the app.config file below works in a console app (MyApp.exe.config) but won't work when only using my DLL (MyLibrary.dll.config):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
    </startup>
  <system.diagnostics>
    <trace autoflush="true" indentsize="0">
      <listeners>
        <add name="MyListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="MyListener.log"/>
        <add name="MyEventListener" type="System.Diagnostics.EventLogTraceListener" initializeData="MyLog"/>
      </listeners>
    </trace>
    <switches>
      <add name="MySwitch" value="Verbose"/>
    </switches>
  </system.diagnostics>
</configuration>

From doing some research it appears that config files for DLLs aren't really viable since the calling app's config file is normally used. But I don't want to have to edit the config file of multiple applications to change logging level, etc. I realize I could roll my own but it's nice that .NET has all this functionality built-in. Just need to know if there's a way to make it work using a DLL.config file?

var log = Trace.Listeners.OfType<EventLogTraceListener>().First(); // Works for an app but not a DLL (no listener)
log.TraceEvent(new TraceEventCache(), "Delme1", TraceEventType.Verbose, 123, "Testing");

UPDATE #1

Based on the answers here it doesn't look like this is supported by design. There also doesn't appear to be any user available objects for manipulating the systems.diagnostic entries. I think I'm going to just create my own XML file for storing the info I need.

UPDATE #2

Per Microsoft's recommendation, I switched to using the TraceSource class and updated my config file to match. I found a way to dynamically load the file from a DLL but that doesn't appear to update the TraceSource class settings, even after issuing a Trace.Refresh(). Everything works when I create a config file with the same settings at the application level, but that's not what I want. Is there any way to load a config file as shown below and also have its settings update the TraceSource class with Listeners, etc.? I find it curious that SystemDiagnosticsSection is marked internal and not accessible to user apps. Seems Microsoft has made this nearly(?) impossible (but I'm so close!)

Config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="MyExceptionLibrary" switchName="MySwitch" switchType="System.Diagnostics.SourceSwitch">
        <listeners>
          <remove name="Default"/>
          <add name="MyListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Logger.log">
            <filter type="System.Diagnostics.EventTypeFilter" initializeData="Off"/>
          </add>
          <add name="MyEventListener" type="System.Diagnostics.EventLogTraceListener" initializeData="Blah">
            <filter type="System.Diagnostics.EventTypeFilter" initializeData="Verbose"/>
          </add>
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="MySwitch" value="Verbose"/>
    </switches>
  </system.diagnostics>
</configuration>

Code:

public static class Logger
{
    private static readonly TraceSource s_traceSource = new TraceSource("MyExceptionLibrary");

    static Logger()
    {
        var config = ConfigurationManager.OpenExeConfiguration("MyExceptionLibrary.dll"); // Confirmed config loaded
        ConfigurationManager.RefreshSection("system.diagnostics"); // Doesn't seem to make any difference
        Debug.WriteLine($"Config file: {config.FilePath}"); // Points to new config file
        var section = config.GetSection("system.diagnostics"); // Contains data from file
        Debug.Write(section.SectionInformation.Type); // SystemDiagnosticSection

        Trace.Refresh(); // Doesn't seem to make any difference
        Debug.WriteLine(s_traceSource.Listeners[0].Name); // Still shows Default
        s_traceSource.TraceEvent(TraceEventType.Verbose, 123, "Testing"); // No event log entry is created
     }
}
Mike Lowery
  • 2,630
  • 4
  • 34
  • 44
  • I guess, that trace listener config should be placed in `app.config` of startup assembly. You can also config everything via code, it should be fine, if you have the same config all the time – Pavel Anikhouski Jul 29 '20 at 07:20

0 Answers0