-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Background and motivation
Original issue: #23937
This helps adoption from those moving from .NET Framework who use TraceSource
for logging. There is currently no support for automatically reading the app.config
and applying those settings to TraceSource
and associated TraceFilter
and TraceSwitch
instances. Support for Trace.Refresh()
based on .NET Framework is also added which allows the application to update existing TraceSource
and Switch
instances when the config file changes.
The TraceSource
code lives in System.Diagnostics.TraceSource.dll
which is shipped inbox but the processing of the app.config
is done in System.Configuration.ConfigurationManager.dll
which is OOB.
The proposed APIs essentially allow interaction between these two separate assemblies and these APIs are used internally and not intended for general use. The one exception is the TraceConfiguration.Register()
method to light-up the config side.
Although not a stated goal in the issue above, these new APIs make it possible to support reading from another format, such as a JSON file, by using a similar approach as done in System.Configuration.ConfigurationManager.dll
which reads from the app.config
XML file.
API Proposal
These live in System.Diagnostics.TraceSource.dll:
namespace System.Diagnostics
{
public abstract class Switch
{
// Needed to reset Value if this Switch is removed from config and Trace.Refresh is called.
+ public string DefaultValue { get { throw null; } }
- protected string Value { get; set; }
+ public string Value { get; set; }
// Called by the config system when Trace.Refresh() is called.
+ public void Refresh();
// Invoke the config system to initialize the switch from the config file.
+ public static event EventHandler<InitializingSwitchEventArgs>? Initializing { add; remove; }
}
public sealed class Trace
{
// Invoke the config system to refresh TraceSources from the config file
+ public static event EventHandler? Refreshing{ add; remove; }
}
public class TraceSource
{
// Needed to reset Level if removed from config and Trace.Refresh is called.
+ public SourceLevels DefaultLevel { get; }
// Invoke the config system to initialize a TraceSource.
+ public static event EventHandler<InitializingTraceSourceEventArgs>? Initializing { add; remove; }
}
+ public sealed class InitializingSwitchEventArgs : EventArgs
+ {
+ public InitializingSwitchEventArgs(Switch @switch);
+ public System.Diagnostics.Switch Switch { get; }
+ }
+ public sealed class InitializingTraceSourceEventArgs : EventArgs
+ {
+ public InitializingTraceSourceEventArgs(TraceSource traceSource) { }
+ public System.Diagnostics.TraceSource TraceSource { get; }
+ public bool WasInitialized { get; set; }
+ }
}
These live in System.Configuration.ConfigurationManager.dll:
// Use the Diagnostics namespace even though in config
namespace System.Diagnostics
{
+ public static class TraceConfiguration
+ {
+ // Subscribe to the new events and create TraceSources etc. from the config file.
+ // This is really the only new API that is called by the user; the rest are for internal use.
+ // Is there a better name here? Such as "EnableConfigurationFiles()"
+ public static void Register();
+ }
}
API Usage
Given the app.config
file:
<configuration>
<system.diagnostics>
<sources>
<source name="TestTraceSource">
<listeners>
<add name = "listener" type="System.Diagnostics.TextWriterTraceListener" initializeData="listener.log" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
Then code using TraceSource
will be initialized to the values in the app.config
:
TraceConfiguration.Register(); // Needed to light up the config system (not necessary in .NET Framework)
TraceSource trace = new("TestTraceSource");
int i = trace.Listeners.Count; // Returns 2; one for the default, and one for the entry in the app.config
Alternative Designs
No response
Risks
No response