Runtime: System.Diagnostics.TraceSource doesn't read configuration from App.config in .NET Core?

Created on 24 Oct 2017  Â·  24Comments  Â·  Source: dotnet/runtime

The following code outputs "Hello, world!" as a trace message to the console when in a .NET Framework console application. When the same code is used in a .NET Core console application, it outputs nothing.

Program.cs

using System.Diagnostics;

namespace ConsoleApp5
{
    class Program
    {
        private readonly static TraceSource traceSource = new TraceSource("ConsoleApp5", SourceLevels.All);

        static void Main(string[] args)
        {
            traceSource.TraceEvent(TraceEventType.Information, 0, "Hello, world!");
        }
    }
}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="true">
      <listeners>
        <add name="consoleTraceListener" />
        <add name="textWriterTraceListener" />
      </listeners>
    </trace>
    <sharedListeners>
      <add name="consoleTraceListener" type="System.Diagnostics.ConsoleTraceListener" traceOutputOptions="DateTime,ThreadId" />
      <add name="textWriterTraceListener" type="System.Diagnostics.TextWriterTraceListener" traceOutputOptions="DateTime,ThreadId" initializeData="Trace.log" />
    </sharedListeners>
    <sources>
      <source name="ConsoleApp5" switchValue="Verbose">
        <listeners>
          <add name="consoleTraceListener" />
          <add name="textWriterTraceListener" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>

Also, I found that if I try to read a connection string using System.Configuration.ConfigurationManager and I have the system.diagnostics section in the App.config, I receive the following error. I'm assuming that .NET Core doesn't have a machine.config where the system.diagnostics section would normally be defined?

Unhandled Exception: System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize ---> System.Configuration.ConfigurationErrorsException: Unrecognized configuration section system.diagnostics. (C:\Users\jemiller\Documents\Visual Studio 2017\Projects\Library2\LibraryConsoleApplication\bin\Debug\netcoreapp2.0\LibraryConsoleApplication.dll.config line 6)
   at System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean ignoreLocal)
   at System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(ConfigurationSchemaErrors schemaErrors)
   at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey)
   --- End of inner exception stack trace ---
   at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey)
   at System.Configuration.ClientConfigurationSystem.PrepareClientConfigSystem(String sectionName)
   at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.Configuration.ConfigurationManager.get_ConnectionStrings()
   at LibraryLibrary.LibraryContext..ctor(String name) in C:\Users\jemiller\Documents\Visual Studio 2017\Projects\Library2\LibraryLibrary\LibraryContext.cs:line 43
   at LibraryLibrary.LibraryContext..ctor() in C:\Users\jemiller\Documents\Visual Studio 2017\Projects\Library2\LibraryLibrary\LibraryContext.cs:line 39
   at LibraryConsoleApplication.Program.Main(String[] args) in C:\Users\jemiller\Documents\Visual Studio 2017\Projects\Library2\LibraryConsoleApplication\Program.cs:line 13

Is there I way I could specify the section similar to the following to get it to work? That is how it is defined in machine.config for .NET Framework.

  <configSections>
    <section name="system.diagnostics" type="System.Diagnostics.SystemDiagnosticsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  </configSections>

Is there some other way in .NET Core to specify that configuration settings for system.diagnostics?

area-System.Diagnostics.Tracing bug up-for-grabs

Most helpful comment

Because the Close button is too close to the Comment button :)

All 24 comments

I looked at the source code for TraceSource in .NET Core. It appears that the code does not read configuration settings from App.config. In addition, it looks like .NET Core doesn't even have a ConsoleTraceListener. So, it looks like you can't even log to the console using TraceSource even if you programmatically configured it.

@brianrob could you please answer the questions above about trace source?

When TraceSource was written, we did not have configuration API's. Now we do, and TraceSource could presumably be changed to read app.config, but @brianrob note this would presumably mean pulling System.Configuration.ConfigurationManager library into the shared framework, as it is not currently in it.

I can't even get it to work by programmatically adding a TextWriterTraceListener. The following code works with .NET Framework, but, does nothing with .NET Core.

using System.Diagnostics;

namespace ConsoleApp5
{
    class Program
    {
        private readonly static TraceSource traceSource = new TraceSource("ConsoleApp5", SourceLevels.All);

        static void Main(string[] args)
        {
            Trace.AutoFlush = true;
            traceSource.Listeners.Add(new TextWriterTraceListener("Trace.log"));
            traceSource.TraceEvent(TraceEventType.Information, 0, "Hello, world!");
        }
    }
}

As far as I can tell, TraceSource is just flat out broken and unusable in .NET Core.

OK, @brianrob or @vancem need to give guidance...

So, why is this being closed? TraceSource is basically completely non-usable as it stands now.

Because the Close button is too close to the Comment button :)

I'm no expert on tracing but I am currently trying to figure out how to turn on network tracing for sockets - replacing the app.config entries for system.diagnostics with whatever is required to have the same effect in .NET Core.

While looking into this I found that TextWriterTraceListener did not seem to work as expected, but by using DefaultTraceListner I could write the output I expected.

In your example you would simply replace:
traceSource.Listeners.Add(new TextWriterTraceListener("Trace.log"));
with:
traceSource.Listeners.Add(new DefaultTraceListener());
DefaultTraceListener dtl = (DefaultTraceListener) traceSource.Listeners["Default"];
dtl.LogFileName ="Trace.log";

To avoid writing to the debug output window twice add the following before this code:
traceSource.Listeners.Clear();

My guess is that this is not really what you want to do - you are just playing around with a very simplified version of tracing as a means of trying to figure out how this works in Core. If anyone can describe how to configure network tracing in Core I'm sure there would be a lot of folks interested.

Do you know if that applies to all instances of TraceSource? If yes, then, maybe it would be possible to use. Otherwise, you need the configuration file because chances are you have many instances of TraceSource and configuring them programmatically isn't feasible.

In my own test I simply used
Trace.Listeners.Add()
rather than creating my own source so the issue is generic from that point of view.

@danmosemsft @brianrob probably this is asked a million times for a million things, but, any idea when this bug might get picked up? It's a pretty powerful and often undervalued facility that is mostly useless from an operational standpoint because "configuration management" means changing code and redeploying (or we continue sticking to .NET Framework for these features.)

ConfigurationManager is there now. However, it has been lobotomized and only supports things like ConnectionStrings. And App.config doesn't work in certain contexts, like if you have a unit test assembly, it is not read. System.Diagnostics.TraceSource doesn't use App.config in .NET Core. So, you have to programmatically configure every single instance you have, making it for practical purposes unusable.

@jeremykuhne also

From dotnet/runtime#16332: In general, we are not expanding support for TraceSource. However, if there is someone who is interested in contributing support for System.Configuration, I think that is OK.

I am marking this up-for-grabs. Next step is to propose a design.

If/when somebody picks this up feel free to contact me about how to make the relevant changes to System.Configuration. It isn't very easy to navigate.

I have been using TraceSource very successfully in .Net Framework with the initial configuration done through app.config and support for runtime updates on the log levels / listeners etc. Now, I have to write my own logic to handle initial configuration from a config file? This seems wrong.

Is there a logger that can be used for both .Net Framework and .Net Core that would work the same way and have ways to configure initial state from a config file?

  • @jorive as he has picked up diagnostics from @brianrob

I have been using TraceSource very successfully in .Net Framework with the initial configuration done through app.config and support for runtime updates on the log levels / listeners etc. Now, I have to write my own logic to handle initial configuration from a config file? This seems wrong.

Is there a logger that can be used for both .Net Framework and .Net Core that would work the same way and have ways to configure initial state from a config file?

Hi, @igalnassi .
For what it worth, and for your information, using .NET Core 3.0, the configuration at app.config section still does not have effect on System.Diagnostics.Trace class methods (like WriteLine). But, now I am able to manually add, for example, a System.Diagnostics.TextWriterTraceListener, to the Trace.Listeners collection and now the Trace.WriteLine method worked again as traditionally expected.

Best regards,

It would be great if Microsoft would add this functionality back in. The new logging API that requires dependency injection and other third party libraries is a monstrosity. You should not have to rely on third party software for something as fundamental as logging. Also, you shouldn't have to rely on overly complicated design patterns such as dependency injection. TraceSource was straight forward and easy to use. The new way isn't. Maybe it's fine for an ASP.NET application, where it originated. It is not fine for a simple console application.

I should say, maybe I would be fine with configuring it programmatically. That is, if you could configure it globally. The way it stands now, you can't. You have to configure each TraceSource instance, which typically are going to be all over the place. For practical purposes, it makes it unusable. Unfortunately, Microsoft doesn't care. They would rather just push you into using the new piece of garbage.

For what it’s worth, we migrated to NLog and its support to load from
Config files without restarting has helped tremendously. It’s performance
is among the best as well. Very happy with our choice.

On Mon, Oct 28, 2019 at 15:01 Jon Miller notifications@github.com wrote:

I should say, maybe I would be fine with configuring it programmatically.
That is, if you could configure it globally. The way it stands now, you
can't. You have to configure each TraceSource instance, which typically are
going to be all over the place. For practical purposes, it makes it
unusable. Unfortunately, Microsoft doesn't care. They would rather just
push you into using the new piece of garbage.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/24829?email_source=notifications&email_token=ADVNZV4QIZYVW6CVGUQGVLTQQ4ZGXA5CNFSM4EAOHWDKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECOAV7A#issuecomment-547097340,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ADVNZV7AVVNQ5OJFHQL54GLQQ4ZGXANCNFSM4EAOHWDA
.

I agree with @jemiller0 's proposal to allow configuring it programmatically. This would allow us to use TraceSource when the TraceSource instance is not available to the application.

Maybe you find my Wiki page interesting: Logging with .NET Standard 2.0. It describes how to use TraceSource and to expose the TraceSource instance. This way it can be used by .NET Core and it might be combined with 3rd party logger like NLog.

I feel TraceSource should be removed until it works. It is very misleading to put in code that compiles but does not work as expected. It wastes the time of the developer.
Not sure if there are more cases like these - better to include only stuff that actually works.
You could put it in a prerelease/experimental package, but it must be very clear what the deal is.

@obiwanjacobi I agree and disagree. The current implementation is brain dead and I think it should be fixed. However, I'm currently using the current brain dead solution with hacks. So, I would prefer that it stay in there and not be removed. It is better to just fix it.

We are planning to move our asp.net mvc 4.6 code to .net core. In our code we really like logging via TraceSource. It would be really great if you fix this for .net core. Late I found this: https://github.com/dotnet/runtime/blob/master/src/libraries/System.Diagnostics.DiagnosticSource/src/DiagnosticSourceUsersGuide.md

Is DiagnosticSource a replacement of TraceSource?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aggieben picture aggieben  Â·  3Comments

omariom picture omariom  Â·  3Comments

iCodeWebApps picture iCodeWebApps  Â·  3Comments

jzabroski picture jzabroski  Â·  3Comments

GitAntoinee picture GitAntoinee  Â·  3Comments