runtime: System.Diagnostics.TraceSource doesn't read configuration from App.config in .NET Core?
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?
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 15
- Comments: 66 (31 by maintainers)
Because the Close button is too close to the Comment button 😃
I just spent a couple hours trying to figure this out. Why is this not well advertised? Developers are going to beat their heads on this like I did and that’s really bad business for y’all.
I just wanted to chime in as well and say what a loss this is. We used System.Diagnostics.Trace a lot, and it is pretty much the remaining issue in our Framework to Core migration, and a big one.
With System.Diagnostics.Trace:
ILogger can also be set up with the config file, but doesn’t provide anything close to this. For example having a component expose multiple sources, or having specific tracing options (like the HTTP request/response data option). And the scoping seems to be per-log source, rather than carrying through across multiple components. The biggest issue is it can only be used via dependency injection, which is not always practical - e.g. how do you trace out of an extension method? Logging always seemed to be one of those grey areas for dependency injection, but in any case Logging is not quite the same as Tracing.
DiagnosticSource is a bit closer (any component can emit a diagnostic source), but it’s pretty onerous to use and to attach listeners. Everything would have to be done in code, and basically we’ll have to take all the informal Tracing, and put object wrappers on everything, it seems, in order for anything to make sense: It’s more of an event logging framework as far as I can tell. Hence its similarity to EventSource.
I tried wiring things up in code, but that still leaves TraceSwitches - I can configure the trace listeners and whatnot in Startup but there’s no way I can see to set a trace switch, they used to read from the configuration to set their runtime value
So, why is this being closed? TraceSource is basically completely non-usable as it stands now.
Thanks @steveharter for fixing this as a DCR. Hopefully this allows the folks above to migrate from .NET Framework to .NET 7. Commenters above, please let us know if this doesn’t unblock you.
… this is what happens when every few years a group of new developers appear which don’t have adequate exposure to technology, declare it bad, then start removing/replacing things that worked perfectly fine.
after 30+ years of programming i’ve learned that nothing survives, not even good things. sad, but true. everything everyone has worked on in .NET Core these past few years will also, eventually, be undone by some future generation of programmers that don’t have adequate exposure to technology, will declare it bad, then start removing/replacing things that work perfectly fine.
nothing fundamentally changed, but it was still changed. between the lack of backward compatibility (FROM MICROSOFT NO LESS!) and perpetual bugs being introduced to their development tools i’ve decided to retire early. make hay in the sun, watch the cattle graze, etc. i’ll come back if we’re lucky enough to experience another Carrington event and actually need to rebuild the world… but as it is, there are better things to invest precious lifespan into than other people’s messes.
</bittervet-rant>Loosely related, https://github.com/wilson0x4d/diagnostics#bootstrapping-systemdiagnostics-in-net-core
… but it is not maintained, and not the most elegant code I’ve ever written, but if someone is determined to use app.config files and the classic logging framework then you may find some joy there.
such a shame. from DI to logging and everything in between +poof+ gone. what began as a xplat initiative turned into a rewrite from the ground up.
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.
Whenever you see
ConfigurationErrorsException: Unrecognized configuration sectionit means theapp.configused a named section that wasn’t registered. In .NETFramework that would happen inmachine.config. In .NETCore we don’t have a machine.config, instead we have an implicit one https://github.com/dotnet/runtime/blob/cd75ae127698b66821b5a2d364aa5ff7aa1a4a2a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ImplicitMachineConfigHost.cs#L75-L94 Since we don’t have all the same sections supported in .NETCore many of those sections are not registered at all and produce this exception. The right fix in most cases is to remove the unused portion of theapp.config. Perhaps we should improve that exception message so that it lets the developer know what to do.@deeprobin please hold off for now. We need API to fix this.
@RussKie that’s because ConfigurationManager doesn’t have the type registration for the section. I’ve added that in a prototype here; https://github.com/ericstj/runtime/tree/addDiagConfig. We’ll need some more work to refine API on this and test it if we want to make the change. Removing up-for-grabs for now.
The logic to read the TraceSource initialization xml should live in https://github.com/dotnet/runtime/tree/main/src/libraries/System.Configuration.ConfigurationManager/src . Would it make sense to do it implicitly when the ConfigurationManager is initialized (no new method required)?
TraceSource would have to expose a few new public methods to make it possible for System.Configuration.ConfigurationManager to initialize it. For example, a new method to return all TraceSwitches instance. These new public methods would have to go through an API review.
Wait, so you’re telling me that we have win32 forms in .net core 6, but no tracing? Let me repeat that again, are you telling me there isn’t any way to do tracing in .net core??? Someone needs to lay off the crack.
TraceSourceis a very slow tracing mechanism. It was an intentional decision to remove it as the tracing mechanism for the core .NET runtime libraries, not an oversight..NET runtime libraries such as networking or sockets have been unified on
System.Diagnostics.EventSourceas the one and only built-in high-performance tracing mechanism.TraceSource can be configured programmatically as shown above.
Marco, is this a fair summary of your suggestions?
and that as long as Microsoft makes money, there is no reason for them to work out this oversight?
Being honest with yourself, do these seem like particularly constructive suggestions?
I think this got directed to the wrong devs, we want https://github.com/orgs/dotnet/teams/area-system-diagnostics-tracesource for this. Thanks @tarekgh for helping clarify ownership here and I noticed @jkotas fixed the label, appreciate it!
@wilson0x4d What you said is exactly how I feel about it. Looking forward to retirement. I have often theorized that all the original developers at Microsoft who created .NET quit for higher paying jobs elsewhere. Then Microsoft was left with people who didn’t know the existing code base who decided to re-write everything. That might be fine if the result was something that worked better, but, that’s not the case. Web development in particular has taken a turn for the worse. It was better 20 years ago.
The .NET Core geniuses decided config files are bad and got rid of them
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:
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.
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.