Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support TraceSource to be initialized from the app.config file #73087

Merged
merged 10 commits into from
Aug 10, 2022
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
Microsoft Visual Studio Solution File, Format Version 12.00

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32317.152
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{15012FB4-9C7C-4DE0-AB44-83A64654D738}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Win32.SystemEvents", "..\Microsoft.Win32.SystemEvents\ref\Microsoft.Win32.SystemEvents.csproj", "{C7D1410B-8CF0-48DB-A0DF-C8E3A341FD12}"
Expand Down Expand Up @@ -39,6 +43,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A3B7282E-7D6
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{BFBE3E0E-4E75-4665-A373-132D283D366D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.EventLog", "..\System.Diagnostics.EventLog\ref\System.Diagnostics.EventLog.csproj", "{C70C30E4-56DC-44FA-B621-9BB4C4E365D0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.EventLog", "..\System.Diagnostics.EventLog\src\System.Diagnostics.EventLog.csproj", "{808D1F6A-2605-4BEB-A64B-0D09CDE558C8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -109,27 +117,37 @@ Global
{E34EBFC8-D1BC-4ED7-8335-C183A5994EE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E34EBFC8-D1BC-4ED7-8335-C183A5994EE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E34EBFC8-D1BC-4ED7-8335-C183A5994EE1}.Release|Any CPU.Build.0 = Release|Any CPU
{C70C30E4-56DC-44FA-B621-9BB4C4E365D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C70C30E4-56DC-44FA-B621-9BB4C4E365D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C70C30E4-56DC-44FA-B621-9BB4C4E365D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C70C30E4-56DC-44FA-B621-9BB4C4E365D0}.Release|Any CPU.Build.0 = Release|Any CPU
{808D1F6A-2605-4BEB-A64B-0D09CDE558C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{808D1F6A-2605-4BEB-A64B-0D09CDE558C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{808D1F6A-2605-4BEB-A64B-0D09CDE558C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{808D1F6A-2605-4BEB-A64B-0D09CDE558C8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{15012FB4-9C7C-4DE0-AB44-83A64654D738} = {3393D976-CAF0-47D0-850E-7A44DF892122}
{9476F50F-E44C-4420-96AB-448259A47C4F} = {3393D976-CAF0-47D0-850E-7A44DF892122}
{C7D1410B-8CF0-48DB-A0DF-C8E3A341FD12} = {751DA007-D916-4F22-AF16-85F343C2992C}
{6F662E39-BB56-4BCF-B053-B4A1782A33E1} = {751DA007-D916-4F22-AF16-85F343C2992C}
{6B586A50-5DFE-4FBE-A65B-9152B992C2E1} = {751DA007-D916-4F22-AF16-85F343C2992C}
{1C48B652-BA62-4D46-9CDD-24A1670EE3E3} = {751DA007-D916-4F22-AF16-85F343C2992C}
{CFF7519C-4D41-4713-991D-27777DA2DB21} = {751DA007-D916-4F22-AF16-85F343C2992C}
{3278A0F9-8E0A-42E1-8FE3-1A01851A6248} = {751DA007-D916-4F22-AF16-85F343C2992C}
{D54AFFF7-9BEE-42C8-89C3-96E7228A23FA} = {A3B7282E-7D62-48ED-B5FC-E6AB32DA6F0A}
{6F662E39-BB56-4BCF-B053-B4A1782A33E1} = {751DA007-D916-4F22-AF16-85F343C2992C}
{7C9D7BE4-BF9C-486C-8ADF-53DE282E018A} = {A3B7282E-7D62-48ED-B5FC-E6AB32DA6F0A}
{9476F50F-E44C-4420-96AB-448259A47C4F} = {3393D976-CAF0-47D0-850E-7A44DF892122}
{6B586A50-5DFE-4FBE-A65B-9152B992C2E1} = {751DA007-D916-4F22-AF16-85F343C2992C}
{E49D2841-A288-4B5F-89FC-857CCE0401F0} = {A3B7282E-7D62-48ED-B5FC-E6AB32DA6F0A}
{355B775A-BFE1-4384-BC83-C6B5D1FB77BB} = {BFBE3E0E-4E75-4665-A373-132D283D366D}
{66EC63BC-99DC-40CA-B53B-B4D8BF6D1630} = {BFBE3E0E-4E75-4665-A373-132D283D366D}
{1C48B652-BA62-4D46-9CDD-24A1670EE3E3} = {751DA007-D916-4F22-AF16-85F343C2992C}
{7B2CA04A-9DFB-471E-B4CB-1937D0049B96} = {A3B7282E-7D62-48ED-B5FC-E6AB32DA6F0A}
{CFF7519C-4D41-4713-991D-27777DA2DB21} = {751DA007-D916-4F22-AF16-85F343C2992C}
{2BE20C4A-C20B-4A0C-8E4A-31B681B6967D} = {A3B7282E-7D62-48ED-B5FC-E6AB32DA6F0A}
{3278A0F9-8E0A-42E1-8FE3-1A01851A6248} = {751DA007-D916-4F22-AF16-85F343C2992C}
{E34EBFC8-D1BC-4ED7-8335-C183A5994EE1} = {A3B7282E-7D62-48ED-B5FC-E6AB32DA6F0A}
{355B775A-BFE1-4384-BC83-C6B5D1FB77BB} = {BFBE3E0E-4E75-4665-A373-132D283D366D}
{66EC63BC-99DC-40CA-B53B-B4D8BF6D1630} = {BFBE3E0E-4E75-4665-A373-132D283D366D}
{C70C30E4-56DC-44FA-B621-9BB4C4E365D0} = {751DA007-D916-4F22-AF16-85F343C2992C}
{808D1F6A-2605-4BEB-A64B-0D09CDE558C8} = {A3B7282E-7D62-48ED-B5FC-E6AB32DA6F0A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {942CAD8E-C19B-4B9A-BEDE-09B43F45F535}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<ItemGroup>
<Compile Include="System.Configuration.ConfigurationManager.cs" Condition="'$(TargetFrameworkIdentifier)' != '.NETFramework'" />
<Compile Include="$(CommonPath)System\Obsoletions.cs" Link="Common\System\Obsoletions.cs" Condition="'$(TargetFrameworkIdentifier)' != '.NETFramework'" />
<Compile Include="System.Configuration.ConfigurationManager.netcoreapp.cs" Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))" />
<Compile Include="System.Configuration.ConfigurationManager.netframework.cs" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ------------------------------------------------------------------------------
// Changes to this file must follow the https://aka.ms/api-review process.
// ------------------------------------------------------------------------------

namespace System.Diagnostics
{
public static partial class TraceConfiguration
{
public static void Register() { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -664,4 +664,34 @@
<data name="DuplicateFileName" xml:space="preserve">
<value>The file name '{0}' was already in the collection.</value>
</data>
<data name="Could_not_create_listener" xml:space="preserve">
<value>Could not create listener '{0}'.</value>
</data>
<data name="Could_not_create_type_instance" xml:space="preserve">
<value>Could not create {0}.</value>
</data>
<data name="Could_not_find_type" xml:space="preserve">
<value>Could not find type for class {0}.</value>
</data>
<data name="Could_not_get_constructor" xml:space="preserve">
<value>Could not find constructor for class {0}.</value>
</data>
<data name="EmptyTypeName_NotAllowed" xml:space="preserve">
<value>switchType needs to be a valid class name. It can't be empty.</value>
</data>
<data name="Incorrect_base_type" xml:space="preserve">
<value>The specified type, '{0}' is not derived from the appropriate base type, '{1}'.</value>
</data>
<data name="Only_specify_one" xml:space="preserve">
<value>'switchValue' and 'switchName' cannot both be specified on source '{0}'.</value>
</data>
<data name="Reference_listener_cant_have_properties" xml:space="preserve">
<value>A listener with no type name specified references the sharedListeners section and cannot have any attributes other than 'Name'. Listener: '{0}'.</value>
</data>
<data name="Reference_to_nonexistent_listener" xml:space="preserve">
<value>Listener '{0}' does not exist in the sharedListeners section.</value>
</data>
<data name="TL_InitializeData_NotSpecified" xml:space="preserve">
<value>initializeData needs to be valid for this TraceListener.</value>
</data>
</root>
steveharter marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -252,25 +252,39 @@ System.Configuration.ConfigurationManager</PackageDescription>
<Compile Include="System\Configuration\XmlUtil.cs" />
<Compile Include="System\Configuration\XmlUtilWriter.cs" />
<Compile Include="System\Drawing\Configuration\SystemDrawingSection.cs" />
<Compile Include="$(CommonPath)System\Security\IdentityHelper.cs"
Link="Common\System\Security\IdentityHelper.cs" />
<Compile Include="$(CommonPath)System\Security\IdentityHelper.cs" Link="Common\System\Security\IdentityHelper.cs" />
<Compile Include="System\Configuration\SettingsProperty.cs" />
<Compile Include="System\Configuration\SettingsPropertyValue.cs" />
<Compile Include="System\Configuration\SettingsSerializeAs.cs" />
<Compile Include="System\Configuration\NoSettingsVersionUpgradeAttribute.cs" />
<Compile Include="System\UriIdnScope.cs" />
<Compile Include="$(CommonPath)System\IO\TempFileCollection.cs"
Link="Common\System\IO\TempFileCollection.cs" />
<Compile Include="$(CommonPath)System\IO\TempFileCollection.cs" Link="Common\System\IO\TempFileCollection.cs" />
<Compile Include="$(CommonPath)System\Obsoletions.cs" Link="Common\System\Obsoletions.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs"
Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'" />
</ItemGroup>

<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">
<Compile Include="System\Diagnostics\DiagnosticsConfiguration.cs" />
<Compile Include="System\Diagnostics\FilterElement.cs" />
<Compile Include="System\Diagnostics\ListenerElementsCollection.cs" />
<Compile Include="System\Diagnostics\SourceElementsCollection.cs" />
<Compile Include="System\Diagnostics\SwitchElementsCollection.cs" />
<Compile Include="System\Diagnostics\SystemDiagnosticsSection.cs" />
<Compile Include="System\Diagnostics\TraceConfiguration.cs" />
<Compile Include="System\Diagnostics\TraceSection.cs" />
<Compile Include="System\Diagnostics\TypedElement.cs" />
<Compile Include="System\Diagnostics\TraceUtils.cs" />
</ItemGroup>

<!-- Since this package is compatible with .NETStandard, it must also ensure its .NETFramework and .NETCoreApp behavior is compatible with its .NETStandard behavior.-->
<ItemGroup>
<ProjectReference Include="$(LibrariesProjectRoot)System.Security.Permissions\src\System.Security.Permissions.csproj" />
</ItemGroup>

<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">
<ProjectReference Include="$(LibrariesProjectRoot)System.Diagnostics.EventLog\src\System.Diagnostics.EventLog.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
<ProjectReference Include="$(LibrariesProjectRoot)System.Security.Cryptography.ProtectedData\src\System.Security.Cryptography.ProtectedData.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public override Stream OpenStreamForRead(string streamName)
<section name='assemblyBinding' type='System.Configuration.IgnoreSection, System.Configuration.ConfigurationManager' allowLocation='false' />
<section name='satelliteassemblies' type='System.Configuration.IgnoreSection, System.Configuration.ConfigurationManager' allowLocation='false' />
<section name='startup' type='System.Configuration.IgnoreSection, System.Configuration.ConfigurationManager' allowLocation='false' />
<section name='system.diagnostics' type='System.Diagnostics.SystemDiagnosticsSection, System.Configuration.ConfigurationManager' allowLocation='false' />
</configSections>
<configProtectedData defaultProvider='RsaProtectedConfigurationProvider'>
<providers>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Configuration;
using System.Runtime.Versioning;

namespace System.Diagnostics
{
internal static class DiagnosticsConfiguration
{
private static volatile SystemDiagnosticsSection s_configSection;
private static volatile InitState s_initState = InitState.NotInitialized;

// Setting for Switch.switchSetting
internal static SwitchElementsCollection SwitchSettings
{
get
{
Initialize();
SystemDiagnosticsSection configSectionSav = s_configSection;
return configSectionSav?.Switches;
}
}

internal static string ConfigFilePath
{
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get
{
Initialize();
SystemDiagnosticsSection configSectionSav = s_configSection;
if (configSectionSav != null)
{
return configSectionSav.ElementInformation.Source;
}

return string.Empty; // the default
}
}

// Setting for TraceInternal.AutoFlush
internal static bool AutoFlush
{
get
{
Initialize();
SystemDiagnosticsSection configSectionSav = s_configSection;
if (configSectionSav != null && configSectionSav.Trace != null)
{
return configSectionSav.Trace.AutoFlush;
}

return false; // the default
}
}

// Setting for TraceInternal.UseGlobalLock
internal static bool UseGlobalLock
{
get
{
Initialize();
SystemDiagnosticsSection configSectionSav = s_configSection;
if (configSectionSav != null && configSectionSav.Trace != null)
{
return configSectionSav.Trace.UseGlobalLock;
}

return true; // the default
}
}

// Setting for TraceInternal.IndentSize
internal static int IndentSize
{
get
{
Initialize();
SystemDiagnosticsSection configSectionSav = s_configSection;
if (configSectionSav != null && configSectionSav.Trace != null)
{
return configSectionSav.Trace.IndentSize;
}

return 4; // the default
}
}

internal static ListenerElementsCollection SharedListeners
{
get
{
Initialize();
SystemDiagnosticsSection configSectionSav = s_configSection;
return configSectionSav?.SharedListeners;
}
}

internal static SourceElementsCollection Sources
{
get
{
Initialize();
SystemDiagnosticsSection configSectionSav = s_configSection;
return configSectionSav?.Sources;
}
}

internal static SystemDiagnosticsSection SystemDiagnosticsSection
{
get
{
Initialize();
return s_configSection;
}
}

private static SystemDiagnosticsSection GetConfigSection()
{
return s_configSection ??= (SystemDiagnosticsSection)PrivilegedConfigurationManager.GetSection("system.diagnostics");
}

internal static bool IsInitializing() => s_initState == InitState.Initializing;
internal static bool IsInitialized() => s_initState == InitState.Initialized;

internal static bool CanInitialize() => (s_initState != InitState.Initializing) &&
!ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress;

internal static void Initialize()
{
// Ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/DiagnosticsConfiguration.cs,188
// This port removed the lock on TraceInternal.critSec since that is now in a separate assembly and TraceInternal
// is internal and because GetConfigSection() is not locked elsewhere such as for connection strings.

// Because some of the code used to load config also uses diagnostics
// we can't block them while we initialize from config. Therefore we just
// return immediately and they just use the default values.
if (s_initState != InitState.NotInitialized ||
ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress)
{
return;
}

s_initState = InitState.Initializing; // used for preventing recursion
try
{
s_configSection = GetConfigSection();
}
finally
{
s_initState = InitState.Initialized;
}
}

internal static void Refresh()
{
ConfigurationManager.RefreshSection("system.diagnostics");

// There might still be some persistant state left behind for
// ConfigPropertyCollection (for ex, swtichelements), probably for perf.
// We need to explicitly cleanup any unrecognized attributes that we
// have added during last deserialization, so that they are re-added
// during the next Config.GetSection properly and we get a chance to
// populate the Attributes collection for re-deserialization.
// Another alternative could be to expose the properties collection
// directly as Attributes collection (currently we keep a local
// hashtable which we explicitly need to keep in sycn and hence the
// cleanup logic below) but the down side of that would be we need to
// explicitly compute what is recognized Vs unrecognized from that
// collection when we expose the unrecognized Attributes publically
SystemDiagnosticsSection configSectionSav = s_configSection;
if (configSectionSav != null)
{
if (configSectionSav.Switches != null)
{
foreach (SwitchElement swelem in configSectionSav.Switches)
{
swelem.ResetProperties();
}
}

if (configSectionSav.SharedListeners != null)
{
foreach (ListenerElement lnelem in configSectionSav.SharedListeners)
{
lnelem.ResetProperties();
}
}

if (configSectionSav.Sources != null)
{
foreach (SourceElement srelem in configSectionSav.Sources)
{
srelem.ResetProperties();
}
}
}

s_configSection = null;

s_initState = InitState.NotInitialized;
Initialize();
}

private enum InitState
{
NotInitialized,
Initializing,
Initialized
}
}
}
Loading