Skip to content

Commit

Permalink
Support TraceSource to be initialized from the app.config file (#73087)
Browse files Browse the repository at this point in the history
  • Loading branch information
steveharter authored Aug 10, 2022
1 parent 301d8e0 commit 9bd2cb5
Show file tree
Hide file tree
Showing 72 changed files with 2,684 additions and 376 deletions.
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>
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

0 comments on commit 9bd2cb5

Please sign in to comment.