Closed jemiller0 closed 2 years ago
Okay taking a step back - I don't think these comments trying to persuade us that "we're holding it wrong" (i.e. that this isn't an issue) are productive.
So can we brainstorm solutions?
I think we can presume it's not likely that we're going to bring back the app.config model. So what is realistic?
Can we have an app pass in xml-like contents to configure the System.Diagnostics stack? So that even if we're not bringing back app.config per se, an app could still pass through a chunk of configuration XML (e.g. that it may read from a standalone config file...) to configure TraceSource/TraceSwitch?
e.g. some call like System.Diagnostics.ConfigureFromXml(TextReader)
or something along those lines?
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.
- stick on .NET Framework 4.8 forever
Mark S - ACA, no, those points are not a fair summary of that comment of mine: I mentioned the fact that net48 is still fully supported but that would be a temporary condition. My point is that an app could still be using net48 tracing in the meantime you research for the evolution of tracing, e.g., build or buy, for your own app. So, “1. stick on .NET Framework 4.8 forever” is not what I am saying.
@jkotas what you suggest could work, however I don't think anything in the app would force ConfigurationManager to be initialized, so user code could start tracing before any one touches configuration. TraceSouce itself might need some light-up code that probes for Configuration via reflection to force that to load.
The app can explicitly initialize ConfigurationManager in its Main method. Adding a single to Main method should not be prohibitive, and gives the app a full control. I would avoid any magic light-up - it can help as much as it can hurt.
I see what you mean, perhaps an explicit method in Configuration would take some magic out of it - avoid folks relying on someone else initializing config and not realizing it.
The app can explicitly initialize ConfigurationManager in its Main method. Adding a single to Main method should not be prohibitive, and gives the app a full control. I would avoid any magic light-up - it can help as much as it can hurt.
This feels like a sensible workaround, however it appears there's something else is broken if you go down this route:
System.Configuration.ConfigurationErrorsException
HResult=0x80131902
Message=Configuration system failed to initialize
Source=System.Configuration.ConfigurationManager
StackTrace:
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_AppSettings()
at WinFormsApp1.Program.Main() in D:\Development\!Tests\WinFormsApp1\Program.cs:line 16
This exception was originally thrown at this call stack:
System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(bool)
System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(System.Configuration.ConfigurationSchemaErrors)
System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors()
System.Configuration.ClientConfigurationSystem.EnsureInit(string)
Inner Exception 1:
ConfigurationErrorsException: Unrecognized configuration section system.diagnostics. (D:\Development\!Tests\WinFormsApp1\bin\Debug\net6.0-windows\WinFormsApp1.dll.config line 3)
Here's a repro that is working for .NET Framework and is failing for .NET: WinFormsApp1.zip
The latter looks like the root cause of several other issues we thought were caused by the CPS, e.g.: https://github.com/dotnet/project-system/issues/6784 and https://github.com/dotnet/project-system/issues/7448.
The app can explicitly initialize ConfigurationManager in its Main method. Adding a single to Main method should not be prohibitive, and gives the app a full control. I would avoid any magic light-up - it can help as much as it can hurt.
This feels like a sensible workaround, however it appears there's something else is broken if you go down this route:
System.Configuration.ConfigurationErrorsException HResult=0x80131902 Message=Configuration system failed to initialize Source=System.Configuration.ConfigurationManager StackTrace: 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_AppSettings() at WinFormsApp1.Program.Main() in D:\Development\!Tests\WinFormsApp1\Program.cs:line 16 This exception was originally thrown at this call stack: System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(bool) System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(System.Configuration.ConfigurationSchemaErrors) System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors() System.Configuration.ClientConfigurationSystem.EnsureInit(string) Inner Exception 1: ConfigurationErrorsException: Unrecognized configuration section system.diagnostics. (D:\Development\!Tests\WinFormsApp1\bin\Debug\net6.0-windows\WinFormsApp1.dll.config line 3)
Here's a repro that is working for .NET Framework and is failing for .NET: WinFormsApp1.zip
I'll investigate in this.
@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 latter looks like the root cause of several other issues we thought were caused by the CPS
Whenever you see ConfigurationErrorsException: Unrecognized configuration section
it means the app.config
used a named section that wasn't registered. In .NETFramework that would happen in machine.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 the app.config
. Perhaps we should improve that exception message so that it lets the developer know what to do.
In .NETFramework that would happen in
machine.config
. In .NETCore we don't have a machine.config, instead we have an implicit one
Ah, now it starts clicking together. It's been many years since I had to deal with this. Thank you for clarifying this.
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.
@danmoseley please excuse my ignorance, what's DCR?
Design Change Request. It is Microsoft acronym used to describe features that got added after feature complete date. DCRs need some level of approval, the feature teams cannot just go ahead and implement them.
Thank you @jkotas
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
App.config
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?
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.
Is there some other way in .NET Core to specify that configuration settings for system.diagnostics?