From 4727084f18892e5c31a47a4f7c2f580f82410397 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Fri, 8 Jul 2022 10:34:36 -0700 Subject: [PATCH 1/9] Adding NetFx System.Diagnostics config section types --- .../Diagnostics/DiagnosticsConfiguration.cs | 257 ++++++++++++ .../src/System/Diagnostics/FilterElement.cs | 32 ++ .../Diagnostics/ListenerElementsCollection.cs | 374 ++++++++++++++++++ .../Diagnostics/SourceElementsCollection.cs | 187 +++++++++ .../Diagnostics/SwitchElementsCollection.cs | 138 +++++++ .../Diagnostics/SystemDiagnosticsSection.cs | 81 ++++ .../src/System/Diagnostics/TraceSection.cs | 60 +++ .../src/System/Diagnostics/TypedElement.cs | 64 +++ .../src/System/Diagnostics/traceutils.cs | 147 +++++++ 9 files changed, 1340 insertions(+) create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs new file mode 100644 index 00000000000000..43b34530b29d79 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs @@ -0,0 +1,257 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ + +namespace System.Diagnostics { + using System; + using System.Reflection; + using System.Collections; + using System.Configuration; + using System.Threading; + using System.Runtime.Versioning; + + internal enum InitState { + NotInitialized, + Initializing, + Initialized + } + + internal static class DiagnosticsConfiguration { + private static volatile SystemDiagnosticsSection configSection; + private static volatile InitState initState = InitState.NotInitialized; + + // setting for Switch.switchSetting + internal static SwitchElementsCollection SwitchSettings { + get { + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null) + return configSectionSav.Switches; + else + return null; + } + } + + // setting for DefaultTraceListener.AssertUIEnabled + internal static bool AssertUIEnabled { + get { + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null && configSectionSav.Assert != null) + return configSectionSav.Assert.AssertUIEnabled; + else + return true; // the default + } + } + + internal static string ConfigFilePath { + [ResourceExposure(ResourceScope.Machine)] + [ResourceConsumption(ResourceScope.Machine)] + get { + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null) + return configSectionSav.ElementInformation.Source; + else + return string.Empty; // the default + } + } + + // setting for DefaultTraceListener.LogFileName + internal static string LogFileName { + [ResourceExposure(ResourceScope.Machine)] + [ResourceConsumption(ResourceScope.Machine)] + get { + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null && configSectionSav.Assert != null) + return configSectionSav.Assert.LogFileName; + else + return string.Empty; // the default + } + } + + // setting for TraceInternal.AutoFlush + internal static bool AutoFlush { + get { + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null && configSectionSav.Trace != null) + return configSectionSav.Trace.AutoFlush; + else + return false; // the default + } + } + + // setting for TraceInternal.UseGlobalLock + internal static bool UseGlobalLock { + get { + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null && configSectionSav.Trace != null) + return configSectionSav.Trace.UseGlobalLock; + else + return true; // the default + } + } + + // setting for TraceInternal.IndentSize + internal static int IndentSize { + get { + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null && configSectionSav.Trace != null) + return configSectionSav.Trace.IndentSize; + else + return 4; // the default + } + } + +#if !FEATURE_PAL // perfcounter + internal static int PerfomanceCountersFileMappingSize { + get { + for (int retryCount = 0; !CanInitialize() && retryCount <= 5; ++retryCount) { + if (retryCount == 5) + return SharedPerformanceCounter.DefaultCountersFileMappingSize; + + System.Threading.Thread.Sleep(200); + } + + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null && configSectionSav.PerfCounters != null) { + int size = configSectionSav.PerfCounters.FileMappingSize; + if (size < SharedPerformanceCounter.MinCountersFileMappingSize) + size = SharedPerformanceCounter.MinCountersFileMappingSize; + + if (size > SharedPerformanceCounter.MaxCountersFileMappingSize) + size = SharedPerformanceCounter.MaxCountersFileMappingSize; + + return size; + } + else + return SharedPerformanceCounter.DefaultCountersFileMappingSize; + } + } +#endif // !FEATURE_PAL + + internal static ListenerElementsCollection SharedListeners { + get { + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null) + return configSectionSav.SharedListeners; + else + return null; + } + } + + internal static SourceElementsCollection Sources { + get { + Initialize(); + SystemDiagnosticsSection configSectionSav = configSection; + if (configSectionSav != null && configSectionSav.Sources != null) + return configSectionSav.Sources; + else + return null; + } + } + + internal static SystemDiagnosticsSection SystemDiagnosticsSection { + get { + Initialize(); + return configSection; + } + } + + private static SystemDiagnosticsSection GetConfigSection() { + SystemDiagnosticsSection configSection = (SystemDiagnosticsSection) PrivilegedConfigurationManager.GetSection("system.diagnostics"); + return configSection; + } + + internal static bool IsInitializing() { + return initState == InitState.Initializing; + } + + internal static bool IsInitialized() { + return initState == InitState.Initialized; + } + + + internal static bool CanInitialize() { + return (initState != InitState.Initializing) && + !ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress; + } + + internal static void Initialize() { + // Initialize() is also called by other components outside of Trace (such as PerformanceCounter) + // as a result using one lock for this critical section and another for Trace API critical sections + // (such as Trace.WriteLine) could potentially lead to deadlock between 2 threads that are + // executing these critical sections (and consequently obtaining the 2 locks) in the reverse order. + // Using the same lock for DiagnosticsConfiguration as well as TraceInternal avoids this issue. + // Sequential locks on TraceInternal.critSec by the same thread is a non issue for this critical section. + lock (TraceInternal.critSec) { + + // 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 ( initState != InitState.NotInitialized || + ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress) { + + return; + } + + initState = InitState.Initializing; // used for preventing recursion + try { + configSection = GetConfigSection(); + } + finally { + 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 = 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(); + } + } + + configSection = null; + + initState = InitState.NotInitialized; + Initialize(); + } + } +} + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs new file mode 100644 index 00000000000000..6b01e8a7f38153 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs @@ -0,0 +1,32 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ +using System.Configuration; +using System; + +namespace System.Diagnostics { + internal class FilterElement : TypedElement { + public FilterElement() : base(typeof(TraceFilter)) {} + + public TraceFilter GetRuntimeObject() { + TraceFilter newFilter = (TraceFilter) BaseGetRuntimeObject(); + newFilter.initializeData = InitData; + return newFilter; + } + + internal TraceFilter RefreshRuntimeObject(TraceFilter filter) { + if (Type.GetType(TypeName) != filter.GetType() || InitData != filter.initializeData) { + // type or initdata changed + _runtimeObject = null; + return GetRuntimeObject(); + } + else { + return filter; + } + } + } +} + + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs new file mode 100644 index 00000000000000..810c3c2c4bc052 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs @@ -0,0 +1,374 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ +using System.Configuration; +using System; +using System.Reflection; +using System.Globalization; +using System.Xml; +using System.Collections.Specialized; +using System.Collections; +using System.Security; +using System.Security.Permissions; + +namespace System.Diagnostics { + [ConfigurationCollection(typeof(ListenerElement))] + internal class ListenerElementsCollection : ConfigurationElementCollection { + + new public ListenerElement this[string name] { + get { + return (ListenerElement) BaseGet(name); + } + } + + public override ConfigurationElementCollectionType CollectionType { + get { + return ConfigurationElementCollectionType.AddRemoveClearMap; + } + } + + protected override ConfigurationElement CreateNewElement() { + return new ListenerElement(true); + } + + protected override Object GetElementKey(ConfigurationElement element) { + return ((ListenerElement) element).Name; + } + + public TraceListenerCollection GetRuntimeObject() { + TraceListenerCollection listeners = new TraceListenerCollection(); + bool _isDemanded = false; + + foreach(ListenerElement element in this) { + + // At some point, we need to pull out adding/removing the 'default' DefaultTraceListener + // code from here in favor of adding/not-adding after we load the config (in TraceSource + // and in static Trace) + + if (!_isDemanded && !element._isAddedByDefault) { + // Do a full damand; This will disable partially trusted code from hooking up listeners + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); + _isDemanded = true; + } + + + + listeners.Add(element.GetRuntimeObject()); + } + + return listeners; + } + + protected override void InitializeDefault() { + InitializeDefaultInternal(); + } + + internal void InitializeDefaultInternal() { + ListenerElement defaultListener = new ListenerElement(false); + defaultListener.Name = "Default"; + defaultListener.TypeName = typeof(DefaultTraceListener).FullName; + defaultListener._isAddedByDefault = true; + + this.BaseAdd(defaultListener); + } + + protected override void BaseAdd(ConfigurationElement element) { + ListenerElement listenerElement = element as ListenerElement; + + Debug.Assert((listenerElement != null), "adding elements other than ListenerElement to ListenerElementsCollection?"); + + if (listenerElement.Name.Equals("Default") && listenerElement.TypeName.Equals(typeof(DefaultTraceListener).FullName)) + BaseAdd(listenerElement, false); + else + BaseAdd(listenerElement, ThrowOnDuplicate); + } + } + + // This is the collection used by the sharedListener section. It is only slightly different from ListenerElementsCollection. + // The differences are that it does not allow remove and clear, and that the ListenerElements it creates do not allow + // references. + [ConfigurationCollection(typeof(ListenerElement), AddItemName = "add", + CollectionType = ConfigurationElementCollectionType.BasicMap)] + internal class SharedListenerElementsCollection : ListenerElementsCollection { + + public override ConfigurationElementCollectionType CollectionType { + get { + return ConfigurationElementCollectionType.BasicMap; + } + } + + protected override ConfigurationElement CreateNewElement() { + return new ListenerElement(false); + } + + protected override string ElementName { + get { + return "add"; + } + } + } + + internal class ListenerElement : TypedElement { + private static readonly ConfigurationProperty _propFilter = new ConfigurationProperty("filter", typeof(FilterElement), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); + private static readonly ConfigurationProperty _propOutputOpts = new ConfigurationProperty("traceOutputOptions", typeof(TraceOptions), TraceOptions.None, ConfigurationPropertyOptions.None); + + private ConfigurationProperty _propListenerTypeName; + private bool _allowReferences; + private Hashtable _attributes; + internal bool _isAddedByDefault; + + static ListenerElement() { + } + + public ListenerElement(bool allowReferences) : base(typeof(TraceListener)) { + _allowReferences = allowReferences; + + ConfigurationPropertyOptions flags = ConfigurationPropertyOptions.None; + if (!_allowReferences) + flags |= ConfigurationPropertyOptions.IsRequired; + + _propListenerTypeName = new ConfigurationProperty("type", typeof(string), null, flags); + + _properties.Remove("type"); + _properties.Add(_propListenerTypeName); + _properties.Add(_propFilter); + _properties.Add(_propName); + _properties.Add(_propOutputOpts); + } + + public Hashtable Attributes { + get { + if (_attributes == null) + _attributes = new Hashtable(StringComparer.OrdinalIgnoreCase); + return _attributes; + } + } + + [ConfigurationProperty("filter")] + public FilterElement Filter { + get { + return (FilterElement) this[_propFilter]; + } + } + + [ConfigurationProperty("name", IsRequired = true, IsKey = true)] + public string Name { + get { + return (string) this[_propName]; + } + set { + this[_propName] = value; + } + } + + [ConfigurationProperty("traceOutputOptions", DefaultValue = (TraceOptions) TraceOptions.None)] + public TraceOptions TraceOutputOptions { + get { + return (TraceOptions) this[_propOutputOpts]; + } + // This is useful when the OM becomes public. In the meantime, this can be utilized via reflection + set { + this[_propOutputOpts] = value; + } + + } + + [ConfigurationProperty("type")] + public override string TypeName { + get { + return (string) this[_propListenerTypeName]; + } + set { + this[_propListenerTypeName] = value; + } + } + + public override bool Equals(object compareTo) { + if (this.Name.Equals("Default") && this.TypeName.Equals(typeof(DefaultTraceListener).FullName)) { + // This is a workaround to treat all DefaultTraceListener named 'Default' the same. + // This is needed for the Config.Save to work properly as otherwise config base layers + // above us would run into duplicate 'Default' listener element and perceive it as + // error. + ListenerElement compareToElem = compareTo as ListenerElement; + return (compareToElem != null) && compareToElem.Name.Equals("Default") + && compareToElem.TypeName.Equals(typeof(DefaultTraceListener).FullName); + } + else + return base.Equals(compareTo); + } + + public override int GetHashCode() { + return base.GetHashCode(); + } + + public TraceListener GetRuntimeObject() { + if (_runtimeObject != null) + return (TraceListener) _runtimeObject; + + try { + string className = TypeName; + if (String.IsNullOrEmpty(className)) { + // Look it up in SharedListeners + Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null"); + + if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !String.IsNullOrEmpty(InitData)) + throw new ConfigurationErrorsException(SR.GetString(SR.Reference_listener_cant_have_properties, Name)); + + if (DiagnosticsConfiguration.SharedListeners == null) + throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name)); + + ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name]; + if (sharedListener == null) + throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name)); + else { + _runtimeObject = sharedListener.GetRuntimeObject(); + return (TraceListener) _runtimeObject; + } + } + else { + // create a new one + TraceListener newListener = (TraceListener) BaseGetRuntimeObject(); + newListener.initializeData = InitData; + newListener.Name = Name; + newListener.SetAttributes(Attributes); + newListener.TraceOutputOptions = TraceOutputOptions; + + if ((Filter != null) && (Filter.TypeName != null) && (Filter.TypeName.Length != 0)) { + newListener.Filter = Filter.GetRuntimeObject(); + XmlWriterTraceListener listerAsXmlWriter = newListener as XmlWriterTraceListener; + if (listerAsXmlWriter != null) { + // This filter was added via configuration, which means we want the listener + // to respect it for TraceTransfer events. + listerAsXmlWriter.shouldRespectFilterOnTraceTransfer = true; + } + } + + _runtimeObject = newListener; + return newListener; + } + } + catch (ArgumentException e) { + throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_create_listener, Name), e); + } + } + + // Our optional attributes implementation is little convoluted as there is + // no such firsclass mechanism from the config system. We basically cache + // any "unrecognized" attribute here and serialize it out later. + protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) { + Attributes.Add(name, value); + return true; + } + + // We need to serialize optional attributes here, a better place would have + // been inside SerializeElement but the base class implementation from + // ConfigurationElement doesn't take into account for derived class doing + // extended serialization, it basically writes out child element that + // forces the element closing syntax, so any attribute serialization needs + // to happen before normal element serialization from ConfigurationElement. + // This means we would write out custom attributes ahead of normal ones. + // The other alternative would be to re-implement the entire routine here + // which is an overkill and a maintenance issue. + protected override void PreSerialize(XmlWriter writer) { + if (_attributes != null) { + IDictionaryEnumerator e = _attributes.GetEnumerator(); + while (e.MoveNext()) { + string xmlValue = (string)e.Value; + string xmlName = (string)e.Key; + + if ((xmlValue != null) && (writer != null)) { + writer.WriteAttributeString(xmlName, xmlValue); + } + } + } + } + + // Account for optional attributes from custom listeners. + protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) { + bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey); + DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0)); + return DataToWrite; + } + + protected override void Unmerge(ConfigurationElement sourceElement, + ConfigurationElement parentElement, + ConfigurationSaveMode saveMode) { + base.Unmerge(sourceElement, parentElement, saveMode); + + // Unmerge the optional attributes cache as well + ListenerElement le = sourceElement as ListenerElement; + if ((le != null) && (le._attributes != null)) + this._attributes = le._attributes; + } + + internal void ResetProperties() + { + // blow away any UnrecognizedAttributes that we have deserialized earlier + if (_attributes != null) { + _attributes.Clear(); + _properties.Clear(); + _properties.Add(_propListenerTypeName); + _properties.Add(_propFilter); + _properties.Add(_propName); + _properties.Add(_propOutputOpts); + } + } + + internal TraceListener RefreshRuntimeObject(TraceListener listener) { + _runtimeObject = null; + try { + string className = TypeName; + if (String.IsNullOrEmpty(className)) { + // Look it up in SharedListeners and ask the sharedListener to refresh. + Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null"); + + if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !String.IsNullOrEmpty(InitData)) + throw new ConfigurationErrorsException(SR.GetString(SR.Reference_listener_cant_have_properties, Name)); + + if (DiagnosticsConfiguration.SharedListeners == null) + throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name)); + + ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name]; + if (sharedListener == null) + throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name)); + else { + _runtimeObject = sharedListener.RefreshRuntimeObject(listener); + return (TraceListener) _runtimeObject; + } + } + else { + // We're the element with the type and initializeData info. First see if those two are the same as they were. + // If not, create a whole new object, otherwise, just update the other properties. + if (Type.GetType(className) != listener.GetType() || InitData != listener.initializeData) { + // type or initdata changed + return GetRuntimeObject(); + } + else { + listener.SetAttributes(Attributes); + listener.TraceOutputOptions = TraceOutputOptions; + + if (listener.Filter != null ) { + if (ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || + ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.Inherited) + listener.Filter = Filter.RefreshRuntimeObject(listener.Filter); + else + listener.Filter = null; + } + + _runtimeObject = listener; + return listener; + } + } + } + catch (ArgumentException e) { + throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_create_listener, Name), e); + } + + } + + } +} + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs new file mode 100644 index 00000000000000..a8a606a0ea9831 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs @@ -0,0 +1,187 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ +using System.Configuration; +using System.Collections; +using System.Collections.Specialized; +using System.Xml; + +namespace System.Diagnostics { + [ConfigurationCollection(typeof(SourceElement), AddItemName = "source", + CollectionType = ConfigurationElementCollectionType.BasicMap)] + internal class SourceElementsCollection : ConfigurationElementCollection { + + new public SourceElement this[string name] { + get { + return (SourceElement) BaseGet(name); + } + } + + protected override string ElementName { + get { + return "source"; + } + } + + public override ConfigurationElementCollectionType CollectionType { + get { + return ConfigurationElementCollectionType.BasicMap; + } + } + + protected override ConfigurationElement CreateNewElement() { + SourceElement se = new SourceElement(); + se.Listeners.InitializeDefaultInternal(); + return se; + } + + protected override Object GetElementKey(ConfigurationElement element) { + return ((SourceElement) element).Name; + } + } + + + internal class SourceElement : ConfigurationElement { + private static readonly ConfigurationPropertyCollection _properties; + private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired); + private static readonly ConfigurationProperty _propSwitchName = new ConfigurationProperty("switchName", typeof(string), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propSwitchValue = new ConfigurationProperty("switchValue", typeof(string), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propSwitchType = new ConfigurationProperty("switchType", typeof(string), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), new ListenerElementsCollection(), ConfigurationPropertyOptions.None); + + private Hashtable _attributes; + + static SourceElement() { + _properties = new ConfigurationPropertyCollection(); + _properties.Add(_propName); + _properties.Add(_propSwitchName); + _properties.Add(_propSwitchValue); + _properties.Add(_propSwitchType); + _properties.Add(_propListeners); + } + + public Hashtable Attributes { + get { + if (_attributes == null) + _attributes = new Hashtable(StringComparer.OrdinalIgnoreCase); + return _attributes; + } + } + + [ConfigurationProperty("listeners")] + public ListenerElementsCollection Listeners { + get { + return (ListenerElementsCollection) this[_propListeners]; + } + } + + [ConfigurationProperty("name", IsRequired=true, DefaultValue="")] + public string Name { + get { + return (string) this[_propName]; + } + } + + protected override ConfigurationPropertyCollection Properties { + get { + return _properties; + } + } + + [ConfigurationProperty("switchName")] + public string SwitchName { + get { + return (string) this[_propSwitchName]; + } + } + + [ConfigurationProperty("switchValue")] + public string SwitchValue { + get { + return (string) this[_propSwitchValue]; + } + } + + [ConfigurationProperty("switchType")] + public string SwitchType { + get { + return (string) this[_propSwitchType]; + } + } + + protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) + { + base.DeserializeElement(reader, serializeCollectionKey); + + if (!String.IsNullOrEmpty(SwitchName) && !String.IsNullOrEmpty(SwitchValue)) + throw new ConfigurationErrorsException(SR.GetString(SR.Only_specify_one, Name)); + } + + // Our optional attributes implementation is little convoluted as there is + // no such firsclass mechanism from the config system. We basically cache + // any "unrecognized" attribute here and serialize it out later. + protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) { + Attributes.Add(name, value); + return true; + } + + // We need to serialize optional attributes here, a better place would have + // been inside SerializeElement but the base class implementation from + // ConfigurationElement doesn't take into account for derived class doing + // extended serialization, it basically writes out child element that + // forces the element closing syntax, so any attribute serialization needs + // to happen before normal element serialization from ConfigurationElement. + // This means we would write out custom attributes ahead of normal ones. + // The other alternative would be to re-implement the entire routine here + // which is an overkill and a maintenance issue. + protected override void PreSerialize(XmlWriter writer) { + if (_attributes != null) { + IDictionaryEnumerator e = _attributes.GetEnumerator(); + while (e.MoveNext()) { + string xmlValue = (string)e.Value; + string xmlName = (string)e.Key; + + if ((xmlValue != null) && (writer != null)) { + writer.WriteAttributeString(xmlName, xmlValue); + } + } + } + } + + // Account for optional attributes from custom listeners. + protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) { + bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey); + DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0)); + return DataToWrite; + } + + protected override void Unmerge(ConfigurationElement sourceElement, + ConfigurationElement parentElement, + ConfigurationSaveMode saveMode) { + base.Unmerge(sourceElement, parentElement, saveMode); + + // Unmerge the optional attributes cache as well + SourceElement le = sourceElement as SourceElement; + if ((le != null) && (le._attributes != null)) + this._attributes = le._attributes; + } + + internal void ResetProperties() + { + // blow away any UnrecognizedAttributes that we have deserialized earlier + if (_attributes != null) { + _attributes.Clear(); + _properties.Clear(); + _properties.Add(_propName); + _properties.Add(_propSwitchName); + _properties.Add(_propSwitchValue); + _properties.Add(_propSwitchType); + _properties.Add(_propListeners); + } + } + } + +} + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs new file mode 100644 index 00000000000000..414b03e338c500 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs @@ -0,0 +1,138 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ +using System.Configuration; +using System.Collections; +using System.Collections.Specialized; +using System.Xml; + +namespace System.Diagnostics { + [ConfigurationCollection(typeof(SwitchElement))] + internal class SwitchElementsCollection : ConfigurationElementCollection { + + new public SwitchElement this[string name] { + get { + return (SwitchElement) BaseGet(name); + } + } + + public override ConfigurationElementCollectionType CollectionType { + get { + return ConfigurationElementCollectionType.AddRemoveClearMap; + } + } + + protected override ConfigurationElement CreateNewElement() { + return new SwitchElement(); + } + + protected override Object GetElementKey(ConfigurationElement element) { + return ((SwitchElement) element).Name; + } + } + + internal class SwitchElement : ConfigurationElement { + private static readonly ConfigurationPropertyCollection _properties; + private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); + private static readonly ConfigurationProperty _propValue = new ConfigurationProperty("value", typeof(string), null, ConfigurationPropertyOptions.IsRequired); + + private Hashtable _attributes; + + static SwitchElement(){ + _properties = new ConfigurationPropertyCollection(); + _properties.Add(_propName); + _properties.Add(_propValue); + } + + public Hashtable Attributes { + get { + if (_attributes == null) + _attributes = new Hashtable(StringComparer.OrdinalIgnoreCase); + return _attributes; + } + } + + [ConfigurationProperty("name", DefaultValue = "", IsRequired = true, IsKey = true)] + public string Name { + get { + return (string) this[_propName]; + } + } + + protected override ConfigurationPropertyCollection Properties { + get { + return _properties; + } + } + + [ConfigurationProperty("value", IsRequired = true)] + public string Value { + get { + return (string) this[_propValue]; + } + } + + // Our optional attributes implementation is little convoluted as there is + // no such firsclass mechanism from the config system. We basically cache + // any "unrecognized" attribute here and serialize it out later. + protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) { + Attributes.Add(name, value); + return true; + } + + // We need to serialize optional attributes here, a better place would have + // been inside SerializeElement but the base class implementation from + // ConfigurationElement doesn't take into account for derived class doing + // extended serialization, it basically writes out child element that + // forces the element closing syntax, so any attribute serialization needs + // to happen before normal element serialization from ConfigurationElement. + // This means we would write out custom attributes ahead of normal ones. + // The other alternative would be to re-implement the entire routine here + // which is an overkill and a maintenance issue. + protected override void PreSerialize(XmlWriter writer) { + if (_attributes != null) { + IDictionaryEnumerator e = _attributes.GetEnumerator(); + while (e.MoveNext()) { + string xmlValue = (string)e.Value; + string xmlName = (string)e.Key; + + if ((xmlValue != null) && (writer != null)) { + writer.WriteAttributeString(xmlName, xmlValue); + } + } + } + } + + // Account for optional attributes from custom listeners. + protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) { + bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey); + DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0)); + return DataToWrite; + } + + protected override void Unmerge(ConfigurationElement sourceElement, + ConfigurationElement parentElement, + ConfigurationSaveMode saveMode) { + base.Unmerge(sourceElement, parentElement, saveMode); + + // Unmerge the optional attributes cache as well + SwitchElement le = sourceElement as SwitchElement; + if ((le != null) && (le._attributes != null)) + this._attributes = le._attributes; + } + + internal void ResetProperties() + { + // blow away any UnrecognizedAttributes that we have deserialized earlier + if (_attributes != null) { + _attributes.Clear(); + _properties.Clear(); + _properties.Add(_propName); + _properties.Add(_propValue); + } + } + } +} + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs new file mode 100644 index 00000000000000..29c47a8d2e6ff6 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs @@ -0,0 +1,81 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ +using System.Configuration; + +namespace System.Diagnostics { + internal class SystemDiagnosticsSection : ConfigurationSection { + private static readonly ConfigurationPropertyCollection _properties; + private static readonly ConfigurationProperty _propAssert = new ConfigurationProperty("assert", typeof(AssertSection), new AssertSection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propPerfCounters = new ConfigurationProperty("performanceCounters", typeof(PerfCounterSection), new PerfCounterSection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propSources = new ConfigurationProperty("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propSharedListeners = new ConfigurationProperty("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propSwitches = new ConfigurationProperty("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propTrace = new ConfigurationProperty("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); + + static SystemDiagnosticsSection() { + _properties = new ConfigurationPropertyCollection(); + _properties.Add(_propAssert); + _properties.Add(_propPerfCounters); + _properties.Add(_propSources); + _properties.Add(_propSharedListeners); + _properties.Add(_propSwitches); + _properties.Add(_propTrace); + } + + [ConfigurationProperty("assert")] + public AssertSection Assert { + get { + return (AssertSection) base[_propAssert]; + } + } + + [ConfigurationProperty("performanceCounters")] + public PerfCounterSection PerfCounters { + get { + return (PerfCounterSection) base[_propPerfCounters]; + } + } + + protected override ConfigurationPropertyCollection Properties { + get { + return _properties; + } + } + + [ConfigurationProperty("sources")] + public SourceElementsCollection Sources { + get { + return (SourceElementsCollection ) base[_propSources]; + } + } + + [ConfigurationProperty("sharedListeners")] + public ListenerElementsCollection SharedListeners { + get { + return (ListenerElementsCollection) base[_propSharedListeners]; + } + } + + [ConfigurationProperty("switches")] + public SwitchElementsCollection Switches { + get { + return (SwitchElementsCollection) base[_propSwitches]; + } + } + + [ConfigurationProperty("trace")] + public TraceSection Trace { + get { + return (TraceSection) base[_propTrace]; + } + } + + protected override void InitializeDefault() { + Trace.Listeners.InitializeDefaultInternal(); + } + } +} + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs new file mode 100644 index 00000000000000..3641201e78d3d7 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs @@ -0,0 +1,60 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ + +using System.Configuration; + +namespace System.Diagnostics { + internal class TraceSection : ConfigurationElement { + private static readonly ConfigurationPropertyCollection _properties; + private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), new ListenerElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propAutoFlush = new ConfigurationProperty("autoflush", typeof(bool), false, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propIndentSize = new ConfigurationProperty("indentsize", typeof(int), 4, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propUseGlobalLock = new ConfigurationProperty("useGlobalLock", typeof(bool), true, ConfigurationPropertyOptions.None); + + static TraceSection() { + _properties = new ConfigurationPropertyCollection(); + _properties.Add(_propListeners); + _properties.Add(_propAutoFlush); + _properties.Add(_propIndentSize); + _properties.Add(_propUseGlobalLock); + } + + [ConfigurationProperty( "autoflush", DefaultValue=false )] + public bool AutoFlush { + get { + return (bool) this[_propAutoFlush]; + } + } + + [ConfigurationProperty( "indentsize", DefaultValue=4 )] + public int IndentSize { + get { + return (int) this[_propIndentSize]; + } + } + + [ConfigurationProperty( "listeners" )] + public ListenerElementsCollection Listeners { + get { + return (ListenerElementsCollection) this[_propListeners]; + } + } + + [ConfigurationProperty( "useGlobalLock", DefaultValue = true)] + public bool UseGlobalLock { + get { + return (bool) this[_propUseGlobalLock]; + } + } + + protected override ConfigurationPropertyCollection Properties { + get { + return _properties; + } + } + } +} + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs new file mode 100644 index 00000000000000..1128db6a9db5de --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs @@ -0,0 +1,64 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ +using System.Configuration; +using System; +using System.Reflection; +using System.Globalization; + +namespace System.Diagnostics { + internal class TypedElement : ConfigurationElement { + protected static readonly ConfigurationProperty _propTypeName = new ConfigurationProperty("type", typeof(string), String.Empty, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsTypeStringTransformationRequired); + protected static readonly ConfigurationProperty _propInitData = new ConfigurationProperty("initializeData", typeof(string), String.Empty, ConfigurationPropertyOptions.None); + + protected ConfigurationPropertyCollection _properties; + protected object _runtimeObject = null; + private Type _baseType; + + public TypedElement(Type baseType) : base() { + _properties = new ConfigurationPropertyCollection(); + _properties.Add(_propTypeName); + _properties.Add(_propInitData); + + _baseType = baseType; + } + + [ConfigurationProperty("initializeData", DefaultValue = "")] + public string InitData { + get { + return (string) this[_propInitData]; + } + // This is useful when the OM becomes public. In the meantime, this can be utilized via reflection + set { + this[_propInitData] = value; + } + + } + + protected override ConfigurationPropertyCollection Properties { + get { + return _properties; + } + } + + [ConfigurationProperty("type", IsRequired = true, DefaultValue = "")] + public virtual string TypeName { + get { + return (string) this[_propTypeName]; + } + set { + this[_propTypeName] = value; + } + } + + protected object BaseGetRuntimeObject() { + if (_runtimeObject == null) + _runtimeObject = TraceUtils.GetRuntimeObject(TypeName, _baseType, InitData); + + return _runtimeObject; + } + + } +} diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs new file mode 100644 index 00000000000000..d7a641a219e378 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs @@ -0,0 +1,147 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ +using System.Configuration; +using System; +using System.IO; +using System.Reflection; +using System.Globalization; +using System.Collections; +using System.Collections.Specialized; +using System.Runtime.Versioning; + +namespace System.Diagnostics { + internal static class TraceUtils { + + [ResourceExposure(ResourceScope.None)] + [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] + internal static object GetRuntimeObject(string className, Type baseType, string initializeData) { + Object newObject = null; + Type objectType = null; + + if (className.Length == 0) { + throw new ConfigurationErrorsException(SR.GetString(SR.EmptyTypeName_NotAllowed)); + } + + objectType = Type.GetType(className); + + if (objectType == null) { + throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_find_type, className)); + } + + if (!baseType.IsAssignableFrom(objectType)) + throw new ConfigurationErrorsException(SR.GetString(SR.Incorrect_base_type, className, baseType.FullName)); + + Exception innerException = null; + try { + if (String.IsNullOrEmpty(initializeData)) { + if (IsOwnedTL(objectType)) + throw new ConfigurationErrorsException(SR.GetString(SR.TL_InitializeData_NotSpecified)); + + // create an object with parameterless constructor + ConstructorInfo ctorInfo = objectType.GetConstructor(new Type[] {}); + if (ctorInfo == null) + throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_get_constructor, className)); + newObject = SecurityUtils.ConstructorInfoInvoke(ctorInfo, new object[] { }); + } + else { + // create an object with a one-string constructor + // first look for a string constructor + ConstructorInfo ctorInfo = objectType.GetConstructor(new Type[] { typeof(string) }); + if (ctorInfo != null) { + // Special case to enable specifying relative path to trace file from config for + // our own TextWriterTraceListener derivatives. We will prepend it with fullpath + // prefix from config file location + if (IsOwnedTextWriterTL(objectType)) { + if ((initializeData[0] != Path.DirectorySeparatorChar) && (initializeData[0] != Path.AltDirectorySeparatorChar) && !Path.IsPathRooted(initializeData)) { + string filePath = DiagnosticsConfiguration.ConfigFilePath; + + if (!String.IsNullOrEmpty(filePath)) { + string dirPath = Path.GetDirectoryName(filePath); + + if (dirPath != null) + initializeData = Path.Combine(dirPath, initializeData); + } + } + } + newObject = SecurityUtils.ConstructorInfoInvoke(ctorInfo, new object[] { initializeData }); + } + else { + // now look for another 1 param constructor. + ConstructorInfo[] ctorInfos = objectType.GetConstructors(); + if (ctorInfos == null) + throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_get_constructor, className)); + for (int i=0; i Date: Fri, 8 Jul 2022 13:52:18 -0700 Subject: [PATCH 2/9] WIP : Add API to configure Diagnostics.Tracing --- ...tem.Configuration.ConfigurationManager.sln | 36 +- ...stem.Configuration.ConfigurationManager.cs | 9 + .../src/Resources/Strings.resx | 36 +- ....Configuration.ConfigurationManager.csproj | 28 +- .../ImplicitMachineConfigHost.cs | 1 + .../Diagnostics/DiagnosticsConfiguration.cs | 231 +++++------ .../src/System/Diagnostics/FilterElement.cs | 41 +- .../Diagnostics/ListenerElementsCollection.cs | 368 ++++++++++-------- .../Diagnostics/SourceElementsCollection.cs | 185 +++++---- .../Diagnostics/SwitchElementsCollection.cs | 149 ++++--- .../Diagnostics/SystemDiagnosticsSection.cs | 81 ++-- .../System/Diagnostics/TraceConfiguration.cs | 151 +++++++ .../src/System/Diagnostics/TraceSection.cs | 74 ++-- .../src/System/Diagnostics/TypedElement.cs | 56 +-- .../src/System/Diagnostics/traceutils.cs | 147 ++++--- .../ref/System.Diagnostics.TraceSource.cs | 14 +- .../src/Resources/Strings.resx | 3 + .../src/System.Diagnostics.TraceSource.csproj | 1 + .../src/System/Diagnostics/Switch.cs | 38 +- .../src/System/Diagnostics/Trace.cs | 21 + .../src/System/Diagnostics/TraceInternal.cs | 13 + .../src/System/Diagnostics/TraceListener.cs | 10 +- .../src/System/Diagnostics/TraceSource.cs | 10 + .../src/System/Diagnostics/TraceUtils.cs | 38 ++ 24 files changed, 1077 insertions(+), 664 deletions(-) create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs create mode 100644 src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs diff --git a/src/libraries/System.Configuration.ConfigurationManager/System.Configuration.ConfigurationManager.sln b/src/libraries/System.Configuration.ConfigurationManager/System.Configuration.ConfigurationManager.sln index 88ac5e88510295..1e57b6f6cba176 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/System.Configuration.ConfigurationManager.sln +++ b/src/libraries/System.Configuration.ConfigurationManager/System.Configuration.ConfigurationManager.sln @@ -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}" @@ -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 @@ -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} diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs index 6d21ab559b502d..7c754beb6ae33f 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs @@ -1578,6 +1578,15 @@ public ProviderException(string message) { } public ProviderException(string message, System.Exception innerException) { } } } +#if NET7_0_OR_GREATER +namespace System.Diagnostics +{ + public static partial class TraceConfiguration + { + public static void Register() { } + } +} +#endif namespace System.Drawing.Configuration { public sealed partial class SystemDrawingSection : System.Configuration.ConfigurationSection diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx b/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx index 29f880277d1335..ebb19d0a9a4794 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx +++ b/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx @@ -664,4 +664,38 @@ The file name '{0}' was already in the collection. - + + + Couldn't create listener '{0}'. + + + Could not create {0}. + + + Couldn't find type for class {0}. + + + Couldn't find constructor for class {0}. + + + switchType needs to be a valid class name. It can't be empty. + + + The specified type, '{0}' is not derived from the appropriate base type, '{1}'. + + + 'switchValue' and 'switchName' cannot both be specified on source '{0}'. + + + A listener with no type name specified references the sharedListeners section and cannot have any attributes other than 'Name'. Listener: '{0}'. + + + Listener '{0}' does not exist in the sharedListeners section. + + + initializeData needs to be valid for this TraceListener. + + + Couldn't find method {0} on class {1}. + + \ No newline at end of file diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj index 48fab46deb39fb..509bf0bcc8fd02 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) disable @@ -251,18 +251,28 @@ System.Configuration.ConfigurationManager - + - + - + + + + + + + + + + + + + + @@ -270,6 +280,10 @@ System.Configuration.ConfigurationManager + + + + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ImplicitMachineConfigHost.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ImplicitMachineConfigHost.cs index 36e4cd1786f3b3..665ef24e47c262 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ImplicitMachineConfigHost.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ImplicitMachineConfigHost.cs @@ -81,6 +81,7 @@ public override Stream OpenStreamForRead(string streamName)
+
diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs index 43b34530b29d79..4c3e2268a2471f 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs @@ -1,30 +1,28 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. -namespace System.Diagnostics { - using System; - using System.Reflection; - using System.Collections; - using System.Configuration; - using System.Threading; - using System.Runtime.Versioning; - - internal enum InitState { +using System.Configuration; +using System.Runtime.Versioning; + +namespace System.Diagnostics +{ + internal enum InitState + { NotInitialized, Initializing, Initialized } - internal static class DiagnosticsConfiguration { + internal static class DiagnosticsConfiguration + { private static volatile SystemDiagnosticsSection configSection; private static volatile InitState initState = InitState.NotInitialized; // setting for Switch.switchSetting - internal static SwitchElementsCollection SwitchSettings { - get { + internal static SwitchElementsCollection SwitchSettings + { + get + { Initialize(); SystemDiagnosticsSection configSectionSav = configSection; if (configSectionSav != null) @@ -34,48 +32,26 @@ internal static SwitchElementsCollection SwitchSettings { } } - // setting for DefaultTraceListener.AssertUIEnabled - internal static bool AssertUIEnabled { - get { - Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; - if (configSectionSav != null && configSectionSav.Assert != null) - return configSectionSav.Assert.AssertUIEnabled; - else - return true; // the default - } - } - - internal static string ConfigFilePath { + internal static string ConfigFilePath + { [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] - get { + get + { Initialize(); SystemDiagnosticsSection configSectionSav = configSection; - if (configSectionSav != null) + if (configSectionSav != null) return configSectionSav.ElementInformation.Source; else return string.Empty; // the default } } - // setting for DefaultTraceListener.LogFileName - internal static string LogFileName { - [ResourceExposure(ResourceScope.Machine)] - [ResourceConsumption(ResourceScope.Machine)] - get { - Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; - if (configSectionSav != null && configSectionSav.Assert != null) - return configSectionSav.Assert.LogFileName; - else - return string.Empty; // the default - } - } - // setting for TraceInternal.AutoFlush - internal static bool AutoFlush { - get { + internal static bool AutoFlush + { + get + { Initialize(); SystemDiagnosticsSection configSectionSav = configSection; if (configSectionSav != null && configSectionSav.Trace != null) @@ -86,8 +62,10 @@ internal static bool AutoFlush { } // setting for TraceInternal.UseGlobalLock - internal static bool UseGlobalLock { - get { + internal static bool UseGlobalLock + { + get + { Initialize(); SystemDiagnosticsSection configSectionSav = configSection; if (configSectionSav != null && configSectionSav.Trace != null) @@ -98,8 +76,10 @@ internal static bool UseGlobalLock { } // setting for TraceInternal.IndentSize - internal static int IndentSize { - get { + internal static int IndentSize + { + get + { Initialize(); SystemDiagnosticsSection configSectionSav = configSection; if (configSectionSav != null && configSectionSav.Trace != null) @@ -109,36 +89,10 @@ internal static int IndentSize { } } -#if !FEATURE_PAL // perfcounter - internal static int PerfomanceCountersFileMappingSize { - get { - for (int retryCount = 0; !CanInitialize() && retryCount <= 5; ++retryCount) { - if (retryCount == 5) - return SharedPerformanceCounter.DefaultCountersFileMappingSize; - - System.Threading.Thread.Sleep(200); - } - - Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; - if (configSectionSav != null && configSectionSav.PerfCounters != null) { - int size = configSectionSav.PerfCounters.FileMappingSize; - if (size < SharedPerformanceCounter.MinCountersFileMappingSize) - size = SharedPerformanceCounter.MinCountersFileMappingSize; - - if (size > SharedPerformanceCounter.MaxCountersFileMappingSize) - size = SharedPerformanceCounter.MaxCountersFileMappingSize; - - return size; - } - else - return SharedPerformanceCounter.DefaultCountersFileMappingSize; - } - } -#endif // !FEATURE_PAL - - internal static ListenerElementsCollection SharedListeners { - get { + internal static ListenerElementsCollection SharedListeners + { + get + { Initialize(); SystemDiagnosticsSection configSectionSav = configSection; if (configSectionSav != null) @@ -148,8 +102,10 @@ internal static ListenerElementsCollection SharedListeners { } } - internal static SourceElementsCollection Sources { - get { + internal static SourceElementsCollection Sources + { + get + { Initialize(); SystemDiagnosticsSection configSectionSav = configSection; if (configSectionSav != null && configSectionSav.Sources != null) @@ -159,99 +115,114 @@ internal static SourceElementsCollection Sources { } } - internal static SystemDiagnosticsSection SystemDiagnosticsSection { - get { + internal static SystemDiagnosticsSection SystemDiagnosticsSection + { + get + { Initialize(); return configSection; } } - - private static SystemDiagnosticsSection GetConfigSection() { - SystemDiagnosticsSection configSection = (SystemDiagnosticsSection) PrivilegedConfigurationManager.GetSection("system.diagnostics"); + + private static SystemDiagnosticsSection GetConfigSection() + { + SystemDiagnosticsSection configSection = (SystemDiagnosticsSection)PrivilegedConfigurationManager.GetSection("system.diagnostics"); return configSection; } - internal static bool IsInitializing() { + internal static bool IsInitializing() + { return initState == InitState.Initializing; } - internal static bool IsInitialized() { + internal static bool IsInitialized() + { return initState == InitState.Initialized; } - - internal static bool CanInitialize() { - return (initState != InitState.Initializing) && + internal static bool CanInitialize() + { + return (initState != InitState.Initializing) && !ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress; } - - internal static void Initialize() { + + internal static void Initialize() + { // Initialize() is also called by other components outside of Trace (such as PerformanceCounter) - // as a result using one lock for this critical section and another for Trace API critical sections - // (such as Trace.WriteLine) could potentially lead to deadlock between 2 threads that are - // executing these critical sections (and consequently obtaining the 2 locks) in the reverse order. - // Using the same lock for DiagnosticsConfiguration as well as TraceInternal avoids this issue. + // as a result using one lock for this critical section and another for Trace API critical sections + // (such as Trace.WriteLine) could potentially lead to deadlock between 2 threads that are + // executing these critical sections (and consequently obtaining the 2 locks) in the reverse order. + // Using the same lock for DiagnosticsConfiguration as well as TraceInternal avoids this issue. // Sequential locks on TraceInternal.critSec by the same thread is a non issue for this critical section. - lock (TraceInternal.critSec) { - // 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 ( initState != InitState.NotInitialized || - ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress) { + // TODO -- determine if locking here is still important + // lock (TraceInternal.critSec) { - return; - } + // 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 (initState != InitState.NotInitialized || + ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress) + { - initState = InitState.Initializing; // used for preventing recursion - try { - configSection = GetConfigSection(); - } - finally { - initState = InitState.Initialized; - } + return; + } + + initState = InitState.Initializing; // used for preventing recursion + try + { + configSection = GetConfigSection(); + } + finally + { + initState = InitState.Initialized; } + //} } - internal static void Refresh() { + 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 + // 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. + // 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 + // 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 + // explicitly compute what is recognized Vs unrecognized from that // collection when we expose the unrecognized Attributes publically SystemDiagnosticsSection configSectionSav = configSection; - if (configSectionSav != null) { + if (configSectionSav != null) + { - if (configSectionSav.Switches != null) { + if (configSectionSav.Switches != null) + { foreach (SwitchElement swelem in configSectionSav.Switches) swelem.ResetProperties(); } - if (configSectionSav.SharedListeners != null) { + if (configSectionSav.SharedListeners != null) + { foreach (ListenerElement lnelem in configSectionSav.SharedListeners) lnelem.ResetProperties(); } - if (configSectionSav.Sources != null) { + if (configSectionSav.Sources != null) + { foreach (SourceElement srelem in configSectionSav.Sources) srelem.ResetProperties(); } } configSection = null; - + initState = InitState.NotInitialized; Initialize(); } } } - diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs index 6b01e8a7f38153..b29480490e5cf8 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs @@ -1,32 +1,37 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ -using System.Configuration; -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. -namespace System.Diagnostics { - internal class FilterElement : TypedElement { - public FilterElement() : base(typeof(TraceFilter)) {} +using System.Runtime.CompilerServices; - public TraceFilter GetRuntimeObject() { - TraceFilter newFilter = (TraceFilter) BaseGetRuntimeObject(); - newFilter.initializeData = InitData; +namespace System.Diagnostics +{ + internal sealed class FilterElement : TypedElement + { + private static ConditionalWeakTable s_initData = new(); + + public FilterElement() : base(typeof(TraceFilter)) { } + + public TraceFilter GetRuntimeObject() + { + TraceFilter newFilter = (TraceFilter)BaseGetRuntimeObject(); + s_initData.AddOrUpdate(newFilter, InitData); return newFilter; } - internal TraceFilter RefreshRuntimeObject(TraceFilter filter) { - if (Type.GetType(TypeName) != filter.GetType() || InitData != filter.initializeData) { + internal TraceFilter RefreshRuntimeObject(TraceFilter filter) + { + if (Type.GetType(TypeName) != filter.GetType() || InitDataChanged(filter)) + { // type or initdata changed _runtimeObject = null; return GetRuntimeObject(); } - else { + else + { return filter; } } + + private bool InitDataChanged(TraceFilter filter) => !s_initData.TryGetValue(filter, out string previousInitData) || InitData != previousInitData; } } - - diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs index 810c3c2c4bc052..502233465f1b42 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs @@ -1,59 +1,56 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; using System.Configuration; -using System; using System.Reflection; -using System.Globalization; +using System.Runtime.CompilerServices; using System.Xml; -using System.Collections.Specialized; -using System.Collections; -using System.Security; -using System.Security.Permissions; -namespace System.Diagnostics { +namespace System.Diagnostics +{ [ConfigurationCollection(typeof(ListenerElement))] - internal class ListenerElementsCollection : ConfigurationElementCollection { + internal class ListenerElementsCollection : ConfigurationElementCollection + { - new public ListenerElement this[string name] { - get { - return (ListenerElement) BaseGet(name); + public new ListenerElement this[string name] + { + get + { + return (ListenerElement)BaseGet(name); } } - public override ConfigurationElementCollectionType CollectionType { - get { + public override ConfigurationElementCollectionType CollectionType + { + get + { return ConfigurationElementCollectionType.AddRemoveClearMap; } } - protected override ConfigurationElement CreateNewElement() { + protected override ConfigurationElement CreateNewElement() + { return new ListenerElement(true); } - protected override Object GetElementKey(ConfigurationElement element) { - return ((ListenerElement) element).Name; + protected override object GetElementKey(ConfigurationElement element) + { + return ((ListenerElement)element).Name; } - public TraceListenerCollection GetRuntimeObject() { - TraceListenerCollection listeners = new TraceListenerCollection(); - bool _isDemanded = false; - - foreach(ListenerElement element in this) { - - // At some point, we need to pull out adding/removing the 'default' DefaultTraceListener - // code from here in favor of adding/not-adding after we load the config (in TraceSource - // and in static Trace) - - if (!_isDemanded && !element._isAddedByDefault) { - // Do a full damand; This will disable partially trusted code from hooking up listeners - new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); - _isDemanded = true; - } + public IEnumerable GetRuntimeObject() + { + List listeners = new(); + foreach (ListenerElement element in this) + { + // At some point, we need to pull out adding/removing the 'default' DefaultTraceListener + // code from here in favor of adding/not-adding after we load the config (in TraceSource + // and in static Trace) listeners.Add(element.GetRuntimeObject()); } @@ -61,11 +58,10 @@ public TraceListenerCollection GetRuntimeObject() { return listeners; } - protected override void InitializeDefault() { - InitializeDefaultInternal(); - } - - internal void InitializeDefaultInternal() { + protected internal override void InitializeDefault() => InitializeDefaultInternal(); + + internal void InitializeDefaultInternal() + { ListenerElement defaultListener = new ListenerElement(false); defaultListener.Name = "Default"; defaultListener.TypeName = typeof(DefaultTraceListener).FullName; @@ -73,63 +69,71 @@ internal void InitializeDefaultInternal() { this.BaseAdd(defaultListener); } - - protected override void BaseAdd(ConfigurationElement element) { + + protected override void BaseAdd(ConfigurationElement element) + { ListenerElement listenerElement = element as ListenerElement; - + Debug.Assert((listenerElement != null), "adding elements other than ListenerElement to ListenerElementsCollection?"); - + if (listenerElement.Name.Equals("Default") && listenerElement.TypeName.Equals(typeof(DefaultTraceListener).FullName)) BaseAdd(listenerElement, false); - else + else BaseAdd(listenerElement, ThrowOnDuplicate); } } // This is the collection used by the sharedListener section. It is only slightly different from ListenerElementsCollection. - // The differences are that it does not allow remove and clear, and that the ListenerElements it creates do not allow - // references. + // The differences are that it does not allow remove and clear, and that the ListenerElements it creates do not allow + // references. [ConfigurationCollection(typeof(ListenerElement), AddItemName = "add", - CollectionType = ConfigurationElementCollectionType.BasicMap)] - internal class SharedListenerElementsCollection : ListenerElementsCollection { + CollectionType = ConfigurationElementCollectionType.BasicMap)] + internal sealed class SharedListenerElementsCollection : ListenerElementsCollection + { - public override ConfigurationElementCollectionType CollectionType { - get { + public override ConfigurationElementCollectionType CollectionType + { + get + { return ConfigurationElementCollectionType.BasicMap; } } - protected override ConfigurationElement CreateNewElement() { + protected override ConfigurationElement CreateNewElement() + { return new ListenerElement(false); } - - protected override string ElementName { - get { + + protected override string ElementName + { + get + { return "add"; } } } - internal class ListenerElement : TypedElement { + internal sealed class ListenerElement : TypedElement + { private static readonly ConfigurationProperty _propFilter = new ConfigurationProperty("filter", typeof(FilterElement), null, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); private static readonly ConfigurationProperty _propOutputOpts = new ConfigurationProperty("traceOutputOptions", typeof(TraceOptions), TraceOptions.None, ConfigurationPropertyOptions.None); private ConfigurationProperty _propListenerTypeName; private bool _allowReferences; - private Hashtable _attributes; + private StringDictionary _attributes; internal bool _isAddedByDefault; - static ListenerElement() { - } + private static ConditionalWeakTable s_initData = new(); - public ListenerElement(bool allowReferences) : base(typeof(TraceListener)) { + public ListenerElement(bool allowReferences) : base(typeof(TraceListener)) + { _allowReferences = allowReferences; ConfigurationPropertyOptions flags = ConfigurationPropertyOptions.None; if (!_allowReferences) flags |= ConfigurationPropertyOptions.IsRequired; - + _propListenerTypeName = new ConfigurationProperty("type", typeof(string), null, flags); _properties.Remove("type"); @@ -139,175 +143,195 @@ public ListenerElement(bool allowReferences) : base(typeof(TraceListener)) { _properties.Add(_propOutputOpts); } - public Hashtable Attributes { - get { + public StringDictionary Attributes + { + get + { if (_attributes == null) - _attributes = new Hashtable(StringComparer.OrdinalIgnoreCase); + _attributes = new StringDictionary(); return _attributes; } } [ConfigurationProperty("filter")] - public FilterElement Filter { - get { - return (FilterElement) this[_propFilter]; + public FilterElement Filter + { + get + { + return (FilterElement)this[_propFilter]; } } [ConfigurationProperty("name", IsRequired = true, IsKey = true)] - public string Name { - get { - return (string) this[_propName]; + public string Name + { + get + { + return (string)this[_propName]; } - set { + set + { this[_propName] = value; } } - [ConfigurationProperty("traceOutputOptions", DefaultValue = (TraceOptions) TraceOptions.None)] - public TraceOptions TraceOutputOptions { - get { - return (TraceOptions) this[_propOutputOpts]; + [ConfigurationProperty("traceOutputOptions", DefaultValue = (TraceOptions)TraceOptions.None)] + public TraceOptions TraceOutputOptions + { + get + { + return (TraceOptions)this[_propOutputOpts]; } // This is useful when the OM becomes public. In the meantime, this can be utilized via reflection - set { + set + { this[_propOutputOpts] = value; } } - + [ConfigurationProperty("type")] - public override string TypeName { - get { - return (string) this[_propListenerTypeName]; + public override string TypeName + { + get + { + return (string)this[_propListenerTypeName]; } - set { + set + { this[_propListenerTypeName] = value; } } - public override bool Equals(object compareTo) { - if (this.Name.Equals("Default") && this.TypeName.Equals(typeof(DefaultTraceListener).FullName)) { - // This is a workaround to treat all DefaultTraceListener named 'Default' the same. - // This is needed for the Config.Save to work properly as otherwise config base layers + public override bool Equals(object compareTo) + { + if (this.Name.Equals("Default") && this.TypeName.Equals(typeof(DefaultTraceListener).FullName)) + { + // This is a workaround to treat all DefaultTraceListener named 'Default' the same. + // This is needed for the Config.Save to work properly as otherwise config base layers // above us would run into duplicate 'Default' listener element and perceive it as - // error. + // error. ListenerElement compareToElem = compareTo as ListenerElement; - return (compareToElem != null) && compareToElem.Name.Equals("Default") + return (compareToElem != null) && compareToElem.Name.Equals("Default") && compareToElem.TypeName.Equals(typeof(DefaultTraceListener).FullName); } - else + else return base.Equals(compareTo); } - public override int GetHashCode() { + public override int GetHashCode() + { return base.GetHashCode(); } - - public TraceListener GetRuntimeObject() { + + public TraceListener GetRuntimeObject() + { if (_runtimeObject != null) - return (TraceListener) _runtimeObject; + return (TraceListener)_runtimeObject; - try { + try + { string className = TypeName; - if (String.IsNullOrEmpty(className)) { + if (string.IsNullOrEmpty(className)) + { // Look it up in SharedListeners Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null"); - if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !String.IsNullOrEmpty(InitData)) - throw new ConfigurationErrorsException(SR.GetString(SR.Reference_listener_cant_have_properties, Name)); - + if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !string.IsNullOrEmpty(InitData)) + throw new ConfigurationErrorsException(SR.Format(SR.Reference_listener_cant_have_properties, Name)); + if (DiagnosticsConfiguration.SharedListeners == null) - throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name)); - + throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); + ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name]; if (sharedListener == null) - throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name)); - else { + throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); + else + { _runtimeObject = sharedListener.GetRuntimeObject(); - return (TraceListener) _runtimeObject; + return (TraceListener)_runtimeObject; } } - else { + else + { // create a new one - TraceListener newListener = (TraceListener) BaseGetRuntimeObject(); - newListener.initializeData = InitData; + TraceListener newListener = (TraceListener)BaseGetRuntimeObject(); + s_initData.AddOrUpdate(newListener, InitData); newListener.Name = Name; - newListener.SetAttributes(Attributes); + newListener.Attributes = Attributes; newListener.TraceOutputOptions = TraceOutputOptions; - if ((Filter != null) && (Filter.TypeName != null) && (Filter.TypeName.Length != 0)) { - newListener.Filter = Filter.GetRuntimeObject(); - XmlWriterTraceListener listerAsXmlWriter = newListener as XmlWriterTraceListener; - if (listerAsXmlWriter != null) { - // This filter was added via configuration, which means we want the listener - // to respect it for TraceTransfer events. - listerAsXmlWriter.shouldRespectFilterOnTraceTransfer = true; - } - } - _runtimeObject = newListener; return newListener; } } - catch (ArgumentException e) { - throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_create_listener, Name), e); + catch (ArgumentException e) + { + throw new ConfigurationErrorsException(SR.Format(SR.Could_not_create_listener, Name), e); } } - - // Our optional attributes implementation is little convoluted as there is - // no such firsclass mechanism from the config system. We basically cache - // any "unrecognized" attribute here and serialize it out later. - protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) { + + // Our optional attributes implementation is little convoluted as there is + // no such firsclass mechanism from the config system. We basically cache + // any "unrecognized" attribute here and serialize it out later. + protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) + { Attributes.Add(name, value); - return true; + return true; } - // We need to serialize optional attributes here, a better place would have + // We need to serialize optional attributes here, a better place would have // been inside SerializeElement but the base class implementation from // ConfigurationElement doesn't take into account for derived class doing - // extended serialization, it basically writes out child element that + // extended serialization, it basically writes out child element that // forces the element closing syntax, so any attribute serialization needs // to happen before normal element serialization from ConfigurationElement. - // This means we would write out custom attributes ahead of normal ones. - // The other alternative would be to re-implement the entire routine here - // which is an overkill and a maintenance issue. - protected override void PreSerialize(XmlWriter writer) { - if (_attributes != null) { - IDictionaryEnumerator e = _attributes.GetEnumerator(); - while (e.MoveNext()) { + // This means we would write out custom attributes ahead of normal ones. + // The other alternative would be to re-implement the entire routine here + // which is an overkill and a maintenance issue. + protected override void PreSerialize(XmlWriter writer) + { + if (_attributes != null) + { + IDictionaryEnumerator e = (IDictionaryEnumerator)_attributes.GetEnumerator(); + while (e.MoveNext()) + { string xmlValue = (string)e.Value; string xmlName = (string)e.Key; - if ((xmlValue != null) && (writer != null)) { + if ((xmlValue != null) && (writer != null)) + { writer.WriteAttributeString(xmlName, xmlValue); } } } } - // Account for optional attributes from custom listeners. - protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) { + // Account for optional attributes from custom listeners. + protected internal override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) + { bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey); DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0)); return DataToWrite; } - protected override void Unmerge(ConfigurationElement sourceElement, - ConfigurationElement parentElement, - ConfigurationSaveMode saveMode) { + protected internal override void Unmerge(ConfigurationElement sourceElement, + ConfigurationElement parentElement, + ConfigurationSaveMode saveMode) + { base.Unmerge(sourceElement, parentElement, saveMode); - + // Unmerge the optional attributes cache as well - ListenerElement le = sourceElement as ListenerElement; - if ((le != null) && (le._attributes != null)) - this._attributes = le._attributes; + ListenerElement le = sourceElement as ListenerElement; + if ((le != null) && (le._attributes != null)) + this._attributes = le._attributes; } - internal void ResetProperties() + internal void ResetProperties() { - // blow away any UnrecognizedAttributes that we have deserialized earlier - if (_attributes != null) { + // blow away any UnrecognizedAttributes that we have deserialized earlier + if (_attributes != null) + { _attributes.Clear(); _properties.Clear(); _properties.Add(_propListenerTypeName); @@ -317,43 +341,51 @@ internal void ResetProperties() } } - internal TraceListener RefreshRuntimeObject(TraceListener listener) { + internal TraceListener RefreshRuntimeObject(TraceListener listener) + { _runtimeObject = null; - try { + try + { string className = TypeName; - if (String.IsNullOrEmpty(className)) { + if (string.IsNullOrEmpty(className)) + { // Look it up in SharedListeners and ask the sharedListener to refresh. Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null"); - if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !String.IsNullOrEmpty(InitData)) - throw new ConfigurationErrorsException(SR.GetString(SR.Reference_listener_cant_have_properties, Name)); + if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !string.IsNullOrEmpty(InitData)) + throw new ConfigurationErrorsException(SR.Format(SR.Reference_listener_cant_have_properties, Name)); if (DiagnosticsConfiguration.SharedListeners == null) - throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name)); - + throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); + ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name]; if (sharedListener == null) - throw new ConfigurationErrorsException(SR.GetString(SR.Reference_to_nonexistent_listener, Name)); - else { + throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); + else + { _runtimeObject = sharedListener.RefreshRuntimeObject(listener); - return (TraceListener) _runtimeObject; + return (TraceListener)_runtimeObject; } } - else { + else + { // We're the element with the type and initializeData info. First see if those two are the same as they were. // If not, create a whole new object, otherwise, just update the other properties. - if (Type.GetType(className) != listener.GetType() || InitData != listener.initializeData) { + if (Type.GetType(className) != listener.GetType() || InitDataChanged(listener)) + { // type or initdata changed return GetRuntimeObject(); } - else { - listener.SetAttributes(Attributes); + else + { + listener.Attributes = Attributes; listener.TraceOutputOptions = TraceOutputOptions; - - if (listener.Filter != null ) { + + if (listener.Filter != null) + { if (ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.Inherited) - listener.Filter = Filter.RefreshRuntimeObject(listener.Filter); + listener.Filter = Filter.RefreshRuntimeObject(listener.Filter); else listener.Filter = null; } @@ -363,12 +395,12 @@ internal TraceListener RefreshRuntimeObject(TraceListener listener) { } } } - catch (ArgumentException e) { - throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_create_listener, Name), e); + catch (ArgumentException e) + { + throw new ConfigurationErrorsException(SR.Format(SR.Could_not_create_listener, Name), e); } - } + private bool InitDataChanged(TraceListener listener) => !s_initData.TryGetValue(listener, out string previousInitData) || InitData != previousInitData; } } - diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs index a8a606a0ea9831..c510ae83e47ae2 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs @@ -1,60 +1,68 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// 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.Collections; using System.Collections.Specialized; using System.Xml; -namespace System.Diagnostics { +namespace System.Diagnostics +{ [ConfigurationCollection(typeof(SourceElement), AddItemName = "source", CollectionType = ConfigurationElementCollectionType.BasicMap)] - internal class SourceElementsCollection : ConfigurationElementCollection { + internal sealed class SourceElementsCollection : ConfigurationElementCollection + { - new public SourceElement this[string name] { - get { - return (SourceElement) BaseGet(name); + public new SourceElement this[string name] + { + get + { + return (SourceElement)BaseGet(name); } } - - protected override string ElementName { - get { + + protected override string ElementName + { + get + { return "source"; } } - public override ConfigurationElementCollectionType CollectionType { - get { + public override ConfigurationElementCollectionType CollectionType + { + get + { return ConfigurationElementCollectionType.BasicMap; } } - protected override ConfigurationElement CreateNewElement() { + protected override ConfigurationElement CreateNewElement() + { SourceElement se = new SourceElement(); se.Listeners.InitializeDefaultInternal(); return se; } - protected override Object GetElementKey(ConfigurationElement element) { - return ((SourceElement) element).Name; + protected override object GetElementKey(ConfigurationElement element) + { + return ((SourceElement)element).Name; } } - internal class SourceElement : ConfigurationElement { - private static readonly ConfigurationPropertyCollection _properties; + internal sealed class SourceElement : ConfigurationElement + { + private static readonly ConfigurationPropertyCollection _properties = new(); private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired); private static readonly ConfigurationProperty _propSwitchName = new ConfigurationProperty("switchName", typeof(string), null, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propSwitchValue = new ConfigurationProperty("switchValue", typeof(string), null, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propSwitchType = new ConfigurationProperty("switchType", typeof(string), null, ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), new ListenerElementsCollection(), ConfigurationPropertyOptions.None); - private Hashtable _attributes; + private StringDictionary _attributes; - static SourceElement() { - _properties = new ConfigurationPropertyCollection(); + static SourceElement() + { _properties.Add(_propName); _properties.Add(_propSwitchName); _properties.Add(_propSwitchValue); @@ -62,116 +70,138 @@ static SourceElement() { _properties.Add(_propListeners); } - public Hashtable Attributes { - get { + public StringDictionary Attributes + { + get + { if (_attributes == null) - _attributes = new Hashtable(StringComparer.OrdinalIgnoreCase); + _attributes = new StringDictionary(); return _attributes; } } [ConfigurationProperty("listeners")] - public ListenerElementsCollection Listeners { - get { - return (ListenerElementsCollection) this[_propListeners]; + public ListenerElementsCollection Listeners + { + get + { + return (ListenerElementsCollection)this[_propListeners]; } } - [ConfigurationProperty("name", IsRequired=true, DefaultValue="")] - public string Name { - get { - return (string) this[_propName]; + [ConfigurationProperty("name", IsRequired = true, DefaultValue = "")] + public string Name + { + get + { + return (string)this[_propName]; } } - - protected override ConfigurationPropertyCollection Properties { - get { + + protected internal override ConfigurationPropertyCollection Properties + { + get + { return _properties; } } [ConfigurationProperty("switchName")] - public string SwitchName { - get { - return (string) this[_propSwitchName]; + public string SwitchName + { + get + { + return (string)this[_propSwitchName]; } } [ConfigurationProperty("switchValue")] - public string SwitchValue { - get { - return (string) this[_propSwitchValue]; + public string SwitchValue + { + get + { + return (string)this[_propSwitchValue]; } } [ConfigurationProperty("switchType")] - public string SwitchType { - get { - return (string) this[_propSwitchType]; + public string SwitchType + { + get + { + return (string)this[_propSwitchType]; } } - - protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) + + protected internal override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) { base.DeserializeElement(reader, serializeCollectionKey); - if (!String.IsNullOrEmpty(SwitchName) && !String.IsNullOrEmpty(SwitchValue)) - throw new ConfigurationErrorsException(SR.GetString(SR.Only_specify_one, Name)); + if (!string.IsNullOrEmpty(SwitchName) && !string.IsNullOrEmpty(SwitchValue)) + throw new ConfigurationErrorsException(SR.Format(SR.Only_specify_one, Name)); } - // Our optional attributes implementation is little convoluted as there is - // no such firsclass mechanism from the config system. We basically cache - // any "unrecognized" attribute here and serialize it out later. - protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) { + // Our optional attributes implementation is little convoluted as there is + // no such firsclass mechanism from the config system. We basically cache + // any "unrecognized" attribute here and serialize it out later. + protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) + { Attributes.Add(name, value); - return true; + return true; } - // We need to serialize optional attributes here, a better place would have + // We need to serialize optional attributes here, a better place would have // been inside SerializeElement but the base class implementation from // ConfigurationElement doesn't take into account for derived class doing - // extended serialization, it basically writes out child element that + // extended serialization, it basically writes out child element that // forces the element closing syntax, so any attribute serialization needs // to happen before normal element serialization from ConfigurationElement. - // This means we would write out custom attributes ahead of normal ones. - // The other alternative would be to re-implement the entire routine here - // which is an overkill and a maintenance issue. - protected override void PreSerialize(XmlWriter writer) { - if (_attributes != null) { - IDictionaryEnumerator e = _attributes.GetEnumerator(); - while (e.MoveNext()) { + // This means we would write out custom attributes ahead of normal ones. + // The other alternative would be to re-implement the entire routine here + // which is an overkill and a maintenance issue. + protected override void PreSerialize(XmlWriter writer) + { + if (_attributes != null) + { + IDictionaryEnumerator e = (IDictionaryEnumerator)_attributes.GetEnumerator(); + while (e.MoveNext()) + { string xmlValue = (string)e.Value; string xmlName = (string)e.Key; - if ((xmlValue != null) && (writer != null)) { + if ((xmlValue != null) && (writer != null)) + { writer.WriteAttributeString(xmlName, xmlValue); } } } } - // Account for optional attributes from custom listeners. - protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) { + // Account for optional attributes from custom listeners. + protected internal override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) + { bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey); DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0)); return DataToWrite; } - protected override void Unmerge(ConfigurationElement sourceElement, - ConfigurationElement parentElement, - ConfigurationSaveMode saveMode) { + protected internal override void Unmerge(ConfigurationElement sourceElement, + ConfigurationElement parentElement, + ConfigurationSaveMode saveMode) + { base.Unmerge(sourceElement, parentElement, saveMode); - + // Unmerge the optional attributes cache as well - SourceElement le = sourceElement as SourceElement; - if ((le != null) && (le._attributes != null)) - this._attributes = le._attributes; + SourceElement le = sourceElement as SourceElement; + if ((le != null) && (le._attributes != null)) + this._attributes = le._attributes; } - internal void ResetProperties() + internal void ResetProperties() { - // blow away any UnrecognizedAttributes that we have deserialized earlier - if (_attributes != null) { + // blow away any UnrecognizedAttributes that we have deserialized earlier + if (_attributes != null) + { _attributes.Clear(); _properties.Clear(); _properties.Add(_propName); @@ -182,6 +212,5 @@ internal void ResetProperties() } } } - -} +} diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs index 414b03e338c500..4829943ae2e660 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs @@ -1,132 +1,154 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// 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.Collections; using System.Collections.Specialized; using System.Xml; -namespace System.Diagnostics { +namespace System.Diagnostics +{ [ConfigurationCollection(typeof(SwitchElement))] - internal class SwitchElementsCollection : ConfigurationElementCollection { + internal sealed class SwitchElementsCollection : ConfigurationElementCollection + { - new public SwitchElement this[string name] { - get { - return (SwitchElement) BaseGet(name); + public new SwitchElement this[string name] + { + get + { + return (SwitchElement)BaseGet(name); } } - - public override ConfigurationElementCollectionType CollectionType { - get { + + public override ConfigurationElementCollectionType CollectionType + { + get + { return ConfigurationElementCollectionType.AddRemoveClearMap; } } - - protected override ConfigurationElement CreateNewElement() { + + protected override ConfigurationElement CreateNewElement() + { return new SwitchElement(); } - - protected override Object GetElementKey(ConfigurationElement element) { - return ((SwitchElement) element).Name; + + protected override object GetElementKey(ConfigurationElement element) + { + return ((SwitchElement)element).Name; } } - - internal class SwitchElement : ConfigurationElement { - private static readonly ConfigurationPropertyCollection _properties; + + internal sealed class SwitchElement : ConfigurationElement + { + private static readonly ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection(); private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); private static readonly ConfigurationProperty _propValue = new ConfigurationProperty("value", typeof(string), null, ConfigurationPropertyOptions.IsRequired); - private Hashtable _attributes; + private StringDictionary _attributes; - static SwitchElement(){ - _properties = new ConfigurationPropertyCollection(); + static SwitchElement() + { _properties.Add(_propName); _properties.Add(_propValue); } - public Hashtable Attributes { - get { + public StringDictionary Attributes + { + get + { if (_attributes == null) - _attributes = new Hashtable(StringComparer.OrdinalIgnoreCase); + _attributes = new StringDictionary(); return _attributes; } } [ConfigurationProperty("name", DefaultValue = "", IsRequired = true, IsKey = true)] - public string Name { - get { - return (string) this[_propName]; + public string Name + { + get + { + return (string)this[_propName]; } } - - protected override ConfigurationPropertyCollection Properties { - get { + + protected internal override ConfigurationPropertyCollection Properties + { + get + { return _properties; } } [ConfigurationProperty("value", IsRequired = true)] - public string Value { - get { - return (string) this[_propValue]; + public string Value + { + get + { + return (string)this[_propValue]; } } - // Our optional attributes implementation is little convoluted as there is - // no such firsclass mechanism from the config system. We basically cache - // any "unrecognized" attribute here and serialize it out later. - protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) { + // Our optional attributes implementation is little convoluted as there is + // no such firsclass mechanism from the config system. We basically cache + // any "unrecognized" attribute here and serialize it out later. + protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) + { Attributes.Add(name, value); - return true; + return true; } - // We need to serialize optional attributes here, a better place would have + // We need to serialize optional attributes here, a better place would have // been inside SerializeElement but the base class implementation from // ConfigurationElement doesn't take into account for derived class doing - // extended serialization, it basically writes out child element that + // extended serialization, it basically writes out child element that // forces the element closing syntax, so any attribute serialization needs // to happen before normal element serialization from ConfigurationElement. - // This means we would write out custom attributes ahead of normal ones. - // The other alternative would be to re-implement the entire routine here - // which is an overkill and a maintenance issue. - protected override void PreSerialize(XmlWriter writer) { - if (_attributes != null) { - IDictionaryEnumerator e = _attributes.GetEnumerator(); - while (e.MoveNext()) { + // This means we would write out custom attributes ahead of normal ones. + // The other alternative would be to re-implement the entire routine here + // which is an overkill and a maintenance issue. + protected override void PreSerialize(XmlWriter writer) + { + if (_attributes != null) + { + IDictionaryEnumerator e = (IDictionaryEnumerator)_attributes.GetEnumerator(); + while (e.MoveNext()) + { string xmlValue = (string)e.Value; string xmlName = (string)e.Key; - if ((xmlValue != null) && (writer != null)) { + if ((xmlValue != null) && (writer != null)) + { writer.WriteAttributeString(xmlName, xmlValue); } } } } - // Account for optional attributes from custom listeners. - protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) { + // Account for optional attributes from custom listeners. + protected internal override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) + { bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey); DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0)); return DataToWrite; } - protected override void Unmerge(ConfigurationElement sourceElement, - ConfigurationElement parentElement, - ConfigurationSaveMode saveMode) { + protected internal override void Unmerge(ConfigurationElement sourceElement, + ConfigurationElement parentElement, + ConfigurationSaveMode saveMode) + { base.Unmerge(sourceElement, parentElement, saveMode); - + // Unmerge the optional attributes cache as well - SwitchElement le = sourceElement as SwitchElement; - if ((le != null) && (le._attributes != null)) - this._attributes = le._attributes; + SwitchElement le = sourceElement as SwitchElement; + if ((le != null) && (le._attributes != null)) + this._attributes = le._attributes; } - internal void ResetProperties() + internal void ResetProperties() { - // blow away any UnrecognizedAttributes that we have deserialized earlier - if (_attributes != null) { + // blow away any UnrecognizedAttributes that we have deserialized earlier + if (_attributes != null) + { _attributes.Clear(); _properties.Clear(); _properties.Add(_propName); @@ -135,4 +157,3 @@ internal void ResetProperties() } } } - diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs index 29c47a8d2e6ff6..f7e837591f006d 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs @@ -1,81 +1,72 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// 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; -namespace System.Diagnostics { - internal class SystemDiagnosticsSection : ConfigurationSection { - private static readonly ConfigurationPropertyCollection _properties; - private static readonly ConfigurationProperty _propAssert = new ConfigurationProperty("assert", typeof(AssertSection), new AssertSection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propPerfCounters = new ConfigurationProperty("performanceCounters", typeof(PerfCounterSection), new PerfCounterSection(), ConfigurationPropertyOptions.None); +namespace System.Diagnostics +{ + internal sealed class SystemDiagnosticsSection : ConfigurationSection + { + private static readonly ConfigurationPropertyCollection _properties = new(); private static readonly ConfigurationProperty _propSources = new ConfigurationProperty("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propSharedListeners = new ConfigurationProperty("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propSwitches = new ConfigurationProperty("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); private static readonly ConfigurationProperty _propTrace = new ConfigurationProperty("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); - static SystemDiagnosticsSection() { - _properties = new ConfigurationPropertyCollection(); - _properties.Add(_propAssert); - _properties.Add(_propPerfCounters); + static SystemDiagnosticsSection() + { _properties.Add(_propSources); _properties.Add(_propSharedListeners); _properties.Add(_propSwitches); _properties.Add(_propTrace); } - [ConfigurationProperty("assert")] - public AssertSection Assert { - get { - return (AssertSection) base[_propAssert]; - } - } - - [ConfigurationProperty("performanceCounters")] - public PerfCounterSection PerfCounters { - get { - return (PerfCounterSection) base[_propPerfCounters]; - } - } - - protected override ConfigurationPropertyCollection Properties { - get { + protected internal override ConfigurationPropertyCollection Properties + { + get + { return _properties; } } [ConfigurationProperty("sources")] - public SourceElementsCollection Sources { - get { - return (SourceElementsCollection ) base[_propSources]; + public SourceElementsCollection Sources + { + get + { + return (SourceElementsCollection)base[_propSources]; } } [ConfigurationProperty("sharedListeners")] - public ListenerElementsCollection SharedListeners { - get { - return (ListenerElementsCollection) base[_propSharedListeners]; + public ListenerElementsCollection SharedListeners + { + get + { + return (ListenerElementsCollection)base[_propSharedListeners]; } } [ConfigurationProperty("switches")] - public SwitchElementsCollection Switches { - get { - return (SwitchElementsCollection) base[_propSwitches]; + public SwitchElementsCollection Switches + { + get + { + return (SwitchElementsCollection)base[_propSwitches]; } } [ConfigurationProperty("trace")] - public TraceSection Trace { - get { - return (TraceSection) base[_propTrace]; + public TraceSection Trace + { + get + { + return (TraceSection)base[_propTrace]; } } - protected override void InitializeDefault() { - Trace.Listeners.InitializeDefaultInternal(); + protected internal override void InitializeDefault() + { + Trace.Listeners?.InitializeDefaultInternal(); } } } - diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs new file mode 100644 index 00000000000000..b9c549a6b7b595 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs @@ -0,0 +1,151 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System.Collections; + +namespace System.Diagnostics +{ + public static class TraceConfiguration + { + public static void Register() + { + // register callbacks + Trace.ConfigureSwitch += ConfigureSwitch; + Trace.ConfigureTrace += ConfigureTraceSettings; + Trace.ConfigureTraceSource += ConfigureTraceSource; + } + + private static void ConfigureTraceSource(TraceSource traceSource) + { + // ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceSource.cs,176 + SourceElementsCollection sources = DiagnosticsConfiguration.Sources; + + if (sources != null) + { + SourceElement sourceElement = sources[traceSource.Name]; + if (sourceElement != null) + { + // first check if the type changed + if ((string.IsNullOrEmpty(sourceElement.SwitchType) && traceSource.Switch.GetType() != typeof(SourceSwitch)) || + (sourceElement.SwitchType != traceSource.Switch.GetType().AssemblyQualifiedName)) + { + + if (!string.IsNullOrEmpty(sourceElement.SwitchName)) + { + CreateSwitch(sourceElement.SwitchType, sourceElement.SwitchName); + } + else + { + CreateSwitch(sourceElement.SwitchType, traceSource.Name); + + if (!string.IsNullOrEmpty(sourceElement.SwitchValue)) + traceSource.Switch.Level = (SourceLevels)Enum.Parse(typeof(SourceLevels), sourceElement.SwitchValue); + } + } + else if (!string.IsNullOrEmpty(sourceElement.SwitchName)) + { + // create a new switch if the name changed, otherwise just refresh. + if (sourceElement.SwitchName != traceSource.Switch.DisplayName) + CreateSwitch(sourceElement.SwitchType, sourceElement.SwitchName); + else + { + traceSource.Switch.Refresh(); + } + } + else + { + // the switchValue changed. Just update our internalSwitch. + if (!string.IsNullOrEmpty(sourceElement.SwitchValue)) + traceSource.Switch.Level = (SourceLevels)Enum.Parse(typeof(SourceLevels), sourceElement.SwitchValue); + else + traceSource.Switch.Level = SourceLevels.Off; + } + + TraceListener[] newListenerCollection = new TraceListener[sourceElement.Listeners.Count]; + int listnerOffset = 0; + foreach (ListenerElement listenerElement in sourceElement.Listeners) + { + TraceListener listener = traceSource.Listeners[listenerElement.Name]; + if (listener != null) + { + newListenerCollection[listnerOffset++] = listenerElement.RefreshRuntimeObject(listener); + } + else + { + newListenerCollection[listnerOffset++] = listenerElement.GetRuntimeObject(); + } + } + + traceSource.Attributes = sourceElement.Attributes; + + traceSource.Listeners.Clear(); + traceSource.Listeners.AddRange(newListenerCollection); + } + else + { + // there was no config, so clear whatever we have. + traceSource.Switch.Level = traceSource.DefaultLevel; + traceSource.Listeners.Clear(); + traceSource.Attributes.Clear(); + } + } + + void CreateSwitch(string typeName, string name) + { + if (!string.IsNullOrEmpty(typeName)) + traceSource.Switch = (SourceSwitch)TraceUtils.GetRuntimeObject(typeName, typeof(SourceSwitch), name); + else + traceSource.Switch = new SourceSwitch(name, traceSource.DefaultLevel.ToString()); + } + } + + private static void ConfigureTraceSettings() + { + // ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,06360b4de5e221c2, https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,37 + + TraceSection traceSection = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace; + + if (traceSection != null) + { + Trace.UseGlobalLock = traceSection.UseGlobalLock; + Trace.AutoFlush = traceSection.AutoFlush; + Trace.IndentSize = traceSection.IndentSize; + + ListenerElementsCollection listeners = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace.Listeners; + if (listeners != null) + { + // If listeners were configured, replace the defaults with these + Trace.Listeners.Clear(); + foreach (var listener in listeners.GetRuntimeObject()) + { + Trace.Listeners.Add(listener); + } + } + } + } + + private static void ConfigureSwitch(Switch @switch) + { + // ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/Switch.cs,173 + SwitchElementsCollection switchSettings = DiagnosticsConfiguration.SwitchSettings; + if (switchSettings != null) + { + SwitchElement mySettings = switchSettings[@switch.DisplayName]; + + if (mySettings != null) + { + if (mySettings.Value != null) + { + @switch.Value = mySettings.Value; + } + else + { + @switch.Value = @switch.DefaultValue; + } + + @switch.Attributes = mySettings.Attributes; + } + } + + } + } +} diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs index 3641201e78d3d7..11a260175c23a3 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs @@ -1,60 +1,68 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// 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; -namespace System.Diagnostics { - internal class TraceSection : ConfigurationElement { - private static readonly ConfigurationPropertyCollection _properties; - private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), new ListenerElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propAutoFlush = new ConfigurationProperty("autoflush", typeof(bool), false, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propIndentSize = new ConfigurationProperty("indentsize", typeof(int), 4, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propUseGlobalLock = new ConfigurationProperty("useGlobalLock", typeof(bool), true, ConfigurationPropertyOptions.None); +namespace System.Diagnostics +{ + internal sealed class TraceSection : ConfigurationElement + { + private static readonly ConfigurationPropertyCollection _properties = new(); + private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propAutoFlush = new ConfigurationProperty("autoflush", typeof(bool), false, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propIndentSize = new ConfigurationProperty("indentsize", typeof(int), 4, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propUseGlobalLock = new ConfigurationProperty("useGlobalLock", typeof(bool), true, ConfigurationPropertyOptions.None); - static TraceSection() { - _properties = new ConfigurationPropertyCollection(); + static TraceSection() + { _properties.Add(_propListeners); _properties.Add(_propAutoFlush); _properties.Add(_propIndentSize); _properties.Add(_propUseGlobalLock); } - [ConfigurationProperty( "autoflush", DefaultValue=false )] - public bool AutoFlush { - get { - return (bool) this[_propAutoFlush]; + [ConfigurationProperty("autoflush", DefaultValue = false)] + public bool AutoFlush + { + get + { + return (bool)this[_propAutoFlush]; } } - [ConfigurationProperty( "indentsize", DefaultValue=4 )] - public int IndentSize { - get { - return (int) this[_propIndentSize]; + [ConfigurationProperty("indentsize", DefaultValue = 4)] + public int IndentSize + { + get + { + return (int)this[_propIndentSize]; } } - [ConfigurationProperty( "listeners" )] - public ListenerElementsCollection Listeners { - get { - return (ListenerElementsCollection) this[_propListeners]; + [ConfigurationProperty("listeners")] + public ListenerElementsCollection Listeners + { + get + { + return (ListenerElementsCollection)this[_propListeners]; } } - [ConfigurationProperty( "useGlobalLock", DefaultValue = true)] - public bool UseGlobalLock { - get { - return (bool) this[_propUseGlobalLock]; + [ConfigurationProperty("useGlobalLock", DefaultValue = true)] + public bool UseGlobalLock + { + get + { + return (bool)this[_propUseGlobalLock]; } } - protected override ConfigurationPropertyCollection Properties { - get { + protected internal override ConfigurationPropertyCollection Properties + { + get + { return _properties; } } } } - diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs index 1128db6a9db5de..6a281101271f84 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs @@ -1,23 +1,20 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// 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; -using System.Reflection; -using System.Globalization; -namespace System.Diagnostics { - internal class TypedElement : ConfigurationElement { - protected static readonly ConfigurationProperty _propTypeName = new ConfigurationProperty("type", typeof(string), String.Empty, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsTypeStringTransformationRequired); - protected static readonly ConfigurationProperty _propInitData = new ConfigurationProperty("initializeData", typeof(string), String.Empty, ConfigurationPropertyOptions.None); +namespace System.Diagnostics +{ + internal class TypedElement : ConfigurationElement + { + protected static readonly ConfigurationProperty _propTypeName = new ConfigurationProperty("type", typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsTypeStringTransformationRequired); + protected static readonly ConfigurationProperty _propInitData = new ConfigurationProperty("initializeData", typeof(string), string.Empty, ConfigurationPropertyOptions.None); protected ConfigurationPropertyCollection _properties; - protected object _runtimeObject = null; + protected object _runtimeObject; private Type _baseType; - public TypedElement(Type baseType) : base() { + public TypedElement(Type baseType) : base() + { _properties = new ConfigurationPropertyCollection(); _properties.Add(_propTypeName); _properties.Add(_propInitData); @@ -26,34 +23,43 @@ public TypedElement(Type baseType) : base() { } [ConfigurationProperty("initializeData", DefaultValue = "")] - public string InitData { - get { - return (string) this[_propInitData]; + public string InitData + { + get + { + return (string)this[_propInitData]; } // This is useful when the OM becomes public. In the meantime, this can be utilized via reflection - set { + set + { this[_propInitData] = value; } } - protected override ConfigurationPropertyCollection Properties { - get { + protected internal override ConfigurationPropertyCollection Properties + { + get + { return _properties; } } [ConfigurationProperty("type", IsRequired = true, DefaultValue = "")] - public virtual string TypeName { - get { - return (string) this[_propTypeName]; + public virtual string TypeName + { + get + { + return (string)this[_propTypeName]; } - set { + set + { this[_propTypeName] = value; } } - protected object BaseGetRuntimeObject() { + protected object BaseGetRuntimeObject() + { if (_runtimeObject == null) _runtimeObject = TraceUtils.GetRuntimeObject(TypeName, _baseType, InitData); diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs index d7a641a219e378..51bc4c3f6d67fb 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs @@ -1,92 +1,102 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//------------------------------------------------------------------------------ +// 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; using System.IO; using System.Reflection; using System.Globalization; using System.Collections; -using System.Collections.Specialized; using System.Runtime.Versioning; -namespace System.Diagnostics { - internal static class TraceUtils { +namespace System.Diagnostics +{ + internal static class TraceUtils + { + internal static object GetRuntimeObject(string className, Type baseType, string initializeData) + { + object newObject = null; + Type objectType; - [ResourceExposure(ResourceScope.None)] - [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] - internal static object GetRuntimeObject(string className, Type baseType, string initializeData) { - Object newObject = null; - Type objectType = null; - - if (className.Length == 0) { - throw new ConfigurationErrorsException(SR.GetString(SR.EmptyTypeName_NotAllowed)); + if (className.Length == 0) + { + throw new ConfigurationErrorsException(SR.EmptyTypeName_NotAllowed); } - + objectType = Type.GetType(className); - if (objectType == null) { - throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_find_type, className)); + if (objectType == null) + { + throw new ConfigurationErrorsException(SR.Format(SR.Could_not_find_type, className)); } if (!baseType.IsAssignableFrom(objectType)) - throw new ConfigurationErrorsException(SR.GetString(SR.Incorrect_base_type, className, baseType.FullName)); - + throw new ConfigurationErrorsException(SR.Format(SR.Incorrect_base_type, className, baseType.FullName)); + Exception innerException = null; - try { - if (String.IsNullOrEmpty(initializeData)) { + try + { + if (string.IsNullOrEmpty(initializeData)) + { if (IsOwnedTL(objectType)) - throw new ConfigurationErrorsException(SR.GetString(SR.TL_InitializeData_NotSpecified)); + throw new ConfigurationErrorsException(SR.TL_InitializeData_NotSpecified); // create an object with parameterless constructor - ConstructorInfo ctorInfo = objectType.GetConstructor(new Type[] {}); + ConstructorInfo ctorInfo = objectType.GetConstructor(Array.Empty()); if (ctorInfo == null) - throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_get_constructor, className)); - newObject = SecurityUtils.ConstructorInfoInvoke(ctorInfo, new object[] { }); + throw new ConfigurationErrorsException(SR.Format(SR.Could_not_get_constructor, className)); + newObject = ctorInfo.Invoke(Array.Empty()); } - else { + else + { // create an object with a one-string constructor // first look for a string constructor ConstructorInfo ctorInfo = objectType.GetConstructor(new Type[] { typeof(string) }); - if (ctorInfo != null) { - // Special case to enable specifying relative path to trace file from config for - // our own TextWriterTraceListener derivatives. We will prepend it with fullpath + if (ctorInfo != null) + { + // Special case to enable specifying relative path to trace file from config for + // our own TextWriterTraceListener derivatives. We will prepend it with fullpath // prefix from config file location - if (IsOwnedTextWriterTL(objectType)) { - if ((initializeData[0] != Path.DirectorySeparatorChar) && (initializeData[0] != Path.AltDirectorySeparatorChar) && !Path.IsPathRooted(initializeData)) { + if (IsOwnedTextWriterTL(objectType)) + { + if ((initializeData[0] != Path.DirectorySeparatorChar) && (initializeData[0] != Path.AltDirectorySeparatorChar) && !Path.IsPathRooted(initializeData)) + { string filePath = DiagnosticsConfiguration.ConfigFilePath; - if (!String.IsNullOrEmpty(filePath)) { + if (!string.IsNullOrEmpty(filePath)) + { string dirPath = Path.GetDirectoryName(filePath); - if (dirPath != null) + if (dirPath != null) initializeData = Path.Combine(dirPath, initializeData); } } } - newObject = SecurityUtils.ConstructorInfoInvoke(ctorInfo, new object[] { initializeData }); + newObject = ctorInfo.Invoke(new object[] { initializeData }); } - else { + else + { // now look for another 1 param constructor. ConstructorInfo[] ctorInfos = objectType.GetConstructors(); if (ctorInfos == null) - throw new ConfigurationErrorsException(SR.GetString(SR.Could_not_get_constructor, className)); - for (int i=0; i? ConfigureTraceSource { add { } remove { } } + public static event Action? ConfigureSwitch { add { } remove { } } public static void Refresh() { } [System.Diagnostics.ConditionalAttribute("TRACE")] public static void TraceError(string? message) { } @@ -208,7 +213,7 @@ public abstract partial class TraceListener : System.MarshalByRefObject, System. { protected TraceListener() { } protected TraceListener(string? name) { } - public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } } + public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } set { } } public System.Diagnostics.TraceFilter? Filter { get { throw null; } set { } } public int IndentLevel { get { throw null; } set { } } public int IndentSize { get { throw null; } set { } } @@ -285,7 +290,8 @@ public partial class TraceSource { public TraceSource(string name) { } public TraceSource(string name, System.Diagnostics.SourceLevels defaultLevel) { } - public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } } + public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } set { } } + public SourceLevels DefaultLevel { get { throw null; } } public System.Diagnostics.TraceListenerCollection Listeners { get { throw null; } } public string Name { get { throw null; } } public System.Diagnostics.SourceSwitch Switch { get { throw null; } set { } } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/Resources/Strings.resx b/src/libraries/System.Diagnostics.TraceSource/src/Resources/Strings.resx index 4062db3292bae6..36fd421db660e4 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/Resources/Strings.resx +++ b/src/libraries/System.Diagnostics.TraceSource/src/Resources/Strings.resx @@ -58,6 +58,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + '{0}' is not a valid attribute for type '{1}'. + An exception occurred while writing to the log file {0}: {1}. diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj b/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj index 0cd26b1f5e6c70..6d81fba9c23025 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj @@ -24,6 +24,7 @@ + diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs index 1b50f00c1cea4e..081f99606865ea 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs @@ -23,7 +23,7 @@ public abstract class Switch private int _switchSetting; private volatile bool _initialized; private bool _initializing; - private volatile string _switchValueString = string.Empty; + private volatile string? _switchValueString = string.Empty; private readonly string _defaultValue; private object? _initializedLock; @@ -123,6 +123,11 @@ public StringDictionary Attributes Initialize(); return _attributes ??= new StringDictionary(); } + set + { + TraceUtils.VerifyAttributes(value, GetSupportedAttributes(), this); + _attributes = value; + } } /// @@ -163,12 +168,14 @@ protected int SwitchSetting protected internal virtual string[]? GetSupportedAttributes() => null; - protected string Value + public string DefaultValue => _defaultValue; + + public string Value { get { Initialize(); - return _switchValueString; + return _switchValueString!; } set { @@ -194,12 +201,29 @@ private bool InitializeWithStatus() return false; } - // This method is re-entrent during initialization, since calls to OnValueChanged() in subclasses could end up having InitializeWithStatus() + // This method is re-entrant during initialization, since calls to OnValueChanged() in subclasses could end up having InitializeWithStatus() // called again, we don't want to get caught in an infinite loop. _initializing = true; - _switchValueString = _defaultValue; - OnValueChanged(); + _switchValueString = null; + + try + { + Trace.OnConfigureSwitch(this); + } + catch (Exception) + { + _initialized = false; + _initializing = false; + throw; + } + + if (_switchValueString == null) + { + _switchValueString = _defaultValue; + OnValueChanged(); + } + _initialized = true; _initializing = false; } @@ -238,7 +262,7 @@ internal static void RefreshAll() } } - internal void Refresh() + public void Refresh() { lock (InitializedLock) { diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs index 40c31c7769bc2b..705cde0d6e52d5 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs @@ -159,6 +159,27 @@ public static void Fail(string? message, string? detailMessage) TraceInternal.Fail(message, detailMessage); } + public static event Action? ConfigureTrace; + + internal static void OnConfigureTrace() + { + Trace.ConfigureTrace?.Invoke(); + } + + public static event Action? ConfigureTraceSource; + + internal static void OnConfigureTraceSource(TraceSource traceSource) + { + Trace.ConfigureTraceSource?.Invoke(traceSource); + } + + public static event Action? ConfigureSwitch; + + internal static void OnConfigureSwitch(Switch @switch) + { + Trace.ConfigureSwitch?.Invoke(@switch); + } + public static void Refresh() { Switch.RefreshAll(); diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs index 0ebc7fe389045f..5c3983e16e74d6 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs @@ -46,6 +46,7 @@ public override void OnIndentSizeChanged(int indentSize) private static volatile bool s_autoFlush; private static volatile bool s_useGlobalLock; private static volatile bool s_settingsInitialized; + private static volatile bool s_settingsInitializing; // this is internal so TraceSource can use it. We want to lock on the same object because both TraceInternal and @@ -288,11 +289,23 @@ private static void InitializeSettings() // though it may not be strictly necessary at present lock (critSec) { + // prevent re-entrance + if (s_settingsInitializing) + { + return; + } + + s_settingsInitializing = true; + if (!s_settingsInitialized) { s_autoFlush = DiagnosticsConfiguration.AutoFlush; s_useGlobalLock = DiagnosticsConfiguration.UseGlobalLock; + + Trace.OnConfigureTrace(); + s_settingsInitialized = true; + s_settingsInitializing = false; } } } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs index 87944a1f1c9cf5..9b40d62eea53f7 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs @@ -42,7 +42,15 @@ protected TraceListener(string? name) _listenerName = name; } - public StringDictionary Attributes => _attributes ??= new StringDictionary(); + public StringDictionary Attributes + { + get => _attributes ??= new StringDictionary(); + set + { + TraceUtils.VerifyAttributes(value, GetSupportedAttributes(), this); + _attributes = value; + } + } /// /// Gets or sets a name for this . diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs index d8d2a397a6da51..fc4dca99fdb096 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs @@ -78,6 +78,8 @@ private void Initialize() NoConfigInit(); + Trace.OnConfigureTraceSource(this); + _initCalled = true; } } @@ -472,8 +474,16 @@ public StringDictionary Attributes return _attributes ??= new StringDictionary(); } + + set + { + TraceUtils.VerifyAttributes(value, GetSupportedAttributes(), this); + _attributes = value; + } } + public SourceLevels DefaultLevel => _switchLevel; + public string Name { get diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs new file mode 100644 index 00000000000000..3f207e1d206754 --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs @@ -0,0 +1,38 @@ +// 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.IO; +using System.Reflection; +using System.Globalization; +using System.Collections; +using System.Collections.Specialized; +using System.Runtime.Versioning; + +namespace System.Diagnostics +{ + internal static class TraceUtils + { + internal static void VerifyAttributes(StringDictionary? attributes, string[]? supportedAttributes, object parent) + { + if (attributes == null) + { + throw new ArgumentNullException(nameof(attributes)); + } + + foreach (string key in attributes.Keys) + { + bool found = false; + if (supportedAttributes != null) + { + for (int i = 0; i < supportedAttributes.Length; i++) + { + if (supportedAttributes[i] == key) + found = true; + } + } + if (!found) + throw new ArgumentException(SR.Format(SR.AttributeNotSupported, key, parent.GetType().FullName)); + } + } + } +} From 7885a77bd9a36eb77672b6fefad602f8a963713e Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Tue, 26 Jul 2022 15:49:58 -0500 Subject: [PATCH 3/9] Get running; add tests --- ....Configuration.ConfigurationManager.csproj | 4 +- .../Diagnostics/DiagnosticsConfiguration.cs | 129 +++---- .../src/System/Diagnostics/FilterElement.cs | 2 +- .../Diagnostics/ListenerElementsCollection.cs | 176 ++++----- .../Diagnostics/SourceElementsCollection.cs | 97 +---- .../Diagnostics/SwitchElementsCollection.cs | 67 +--- .../Diagnostics/SystemDiagnosticsSection.cs | 59 +-- .../System/Diagnostics/TraceConfiguration.cs | 87 +++-- .../src/System/Diagnostics/TraceSection.cs | 58 +-- .../{traceutils.cs => TraceUtils.cs} | 92 ++++- .../src/System/Diagnostics/TypedElement.cs | 28 +- ...guration.ConfigurationManager.Tests.csproj | 30 +- .../System/Diagnostics/DiagnosticsTestData.cs | 37 ++ .../TraceSourceConfigurationTests.cs | 78 ++++ .../System.Diagnostics.TraceSource.sln | 336 ++++++++++-------- .../ref/System.Diagnostics.TraceSource.cs | 18 +- .../src/System.Diagnostics.TraceSource.csproj | 4 +- .../Diagnostics/ConfigureSwitchEventArgs.cs | 18 + .../ConfigureTraceSourceEventArgs.cs | 19 + .../src/System/Diagnostics/Switch.cs | 3 + .../src/System/Diagnostics/Trace.cs | 22 +- .../src/System/Diagnostics/TraceListeners.cs | 4 +- .../src/System/Diagnostics/TraceSource.cs | 53 +-- .../src/System/Diagnostics/TraceSwitch.cs | 35 +- .../AssemblyInfo.cs | 0 .../StringTraceListener.cs | 51 +++ ...iagnostics.TraceSource.Config.Tests.csproj | 28 ++ .../TraceSourceWithConfigurationTests.cs | 233 ++++++++++++ .../testhost_AllTypes.dll.config | 62 ++++ .../testhost_ConfigWithRuntime.dll.config | 32 ++ .../testhost_RefreshSwitch_after.dll.config | 16 + .../testhost_RefreshSwitch_before.dll.config | 16 + .../testhost_refresh.dll.config | 20 ++ .../AssemblyInfo.cs | 6 + .../BooleanSwitchClassTests.cs | 0 .../CorrelationManagerTests.cs | 0 .../DefaultTraceListenerClassTests.cs | 0 .../EventTypeFilterClassTests.cs | 0 .../SourceFilterClassTests.cs | 0 .../SwitchClassTests.cs | 0 ...ystem.Diagnostics.TraceSource.Tests.csproj | 7 + .../TestTextTraceListener.cs | 0 .../TestTraceFilter.cs | 0 .../TestTraceListener.cs | 0 .../TraceClassTests.cs | 0 .../TraceEventCacheClassTests.cs | 0 .../TraceFilterClassTests.cs | 0 .../TraceInternalClassTests.cs | 0 .../TraceListenerClassTests.cs | 0 .../TraceListenerCollectionClassTests.cs | 0 .../TraceSourceClassTests.cs | 3 +- .../TraceSwitchClassTests.cs | 0 .../TraceTestHelper.cs | 0 53 files changed, 1238 insertions(+), 692 deletions(-) rename src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/{traceutils.cs => TraceUtils.cs} (65%) create mode 100644 src/libraries/System.Configuration.ConfigurationManager/tests/System/Diagnostics/DiagnosticsTestData.cs create mode 100644 src/libraries/System.Configuration.ConfigurationManager/tests/System/Diagnostics/TraceSourceConfigurationTests.cs create mode 100644 src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureSwitchEventArgs.cs create mode 100644 src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureTraceSourceEventArgs.cs rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Config.Tests}/AssemblyInfo.cs (100%) create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_AllTypes.dll.config create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ConfigWithRuntime.dll.config create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_after.dll.config create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_before.dll.config create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_refresh.dll.config create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/AssemblyInfo.cs rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/BooleanSwitchClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/CorrelationManagerTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/DefaultTraceListenerClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/EventTypeFilterClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/SourceFilterClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/SwitchClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/System.Diagnostics.TraceSource.Tests.csproj (76%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TestTextTraceListener.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TestTraceFilter.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TestTraceListener.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TraceClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TraceEventCacheClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TraceFilterClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TraceInternalClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TraceListenerClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TraceListenerCollectionClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TraceSourceClassTests.cs (99%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TraceSwitchClassTests.cs (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/{ => System.Diagnostics.TraceSource.Tests}/TraceTestHelper.cs (100%) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj index 509bf0bcc8fd02..c82eff9018d4ff 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) disable @@ -272,7 +272,7 @@ System.Configuration.ConfigurationManager - + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs index 4c3e2268a2471f..8cbdae295e4ae4 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs @@ -6,29 +6,26 @@ namespace System.Diagnostics { - internal enum InitState - { - NotInitialized, - Initializing, - Initialized - } - internal static class DiagnosticsConfiguration { - private static volatile SystemDiagnosticsSection configSection; - private static volatile InitState initState = InitState.NotInitialized; + private static volatile SystemDiagnosticsSection s_configSection; + private static volatile InitState s_initState = InitState.NotInitialized; - // setting for Switch.switchSetting + // Setting for Switch.switchSetting internal static SwitchElementsCollection SwitchSettings { get { Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; + SystemDiagnosticsSection configSectionSav = s_configSection; if (configSectionSav != null) + { return configSectionSav.Switches; + } else + { return null; + } } } @@ -39,53 +36,61 @@ internal static string ConfigFilePath get { Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; + SystemDiagnosticsSection configSectionSav = s_configSection; if (configSectionSav != null) + { return configSectionSav.ElementInformation.Source; - else - return string.Empty; // the default + } + + return string.Empty; // the default } } - // setting for TraceInternal.AutoFlush + // Setting for TraceInternal.AutoFlush internal static bool AutoFlush { get { Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; + SystemDiagnosticsSection configSectionSav = s_configSection; if (configSectionSav != null && configSectionSav.Trace != null) + { return configSectionSav.Trace.AutoFlush; - else - return false; // the default + } + + return false; // the default } } - // setting for TraceInternal.UseGlobalLock + // Setting for TraceInternal.UseGlobalLock internal static bool UseGlobalLock { get { Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; + SystemDiagnosticsSection configSectionSav = s_configSection; if (configSectionSav != null && configSectionSav.Trace != null) + { return configSectionSav.Trace.UseGlobalLock; - else - return true; // the default + } + + return true; // the default } } - // setting for TraceInternal.IndentSize + // Setting for TraceInternal.IndentSize internal static int IndentSize { get { Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; + SystemDiagnosticsSection configSectionSav = s_configSection; if (configSectionSav != null && configSectionSav.Trace != null) + { return configSectionSav.Trace.IndentSize; - else - return 4; // the default + } + + return 4; // the default } } @@ -94,11 +99,13 @@ internal static ListenerElementsCollection SharedListeners get { Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; + SystemDiagnosticsSection configSectionSav = s_configSection; if (configSectionSav != null) + { return configSectionSav.SharedListeners; - else - return null; + } + + return null; } } @@ -107,11 +114,13 @@ internal static SourceElementsCollection Sources get { Initialize(); - SystemDiagnosticsSection configSectionSav = configSection; + SystemDiagnosticsSection configSectionSav = s_configSection; if (configSectionSav != null && configSectionSav.Sources != null) + { return configSectionSav.Sources; - else - return null; + } + + return null; } } @@ -120,31 +129,21 @@ internal static SystemDiagnosticsSection SystemDiagnosticsSection get { Initialize(); - return configSection; + return s_configSection; } } private static SystemDiagnosticsSection GetConfigSection() { - SystemDiagnosticsSection configSection = (SystemDiagnosticsSection)PrivilegedConfigurationManager.GetSection("system.diagnostics"); - return configSection; - } - - internal static bool IsInitializing() - { - return initState == InitState.Initializing; + SystemDiagnosticsSection s_configSection = (SystemDiagnosticsSection)PrivilegedConfigurationManager.GetSection("system.diagnostics"); + return s_configSection; } - internal static bool IsInitialized() - { - return initState == InitState.Initialized; - } + internal static bool IsInitializing() => s_initState == InitState.Initializing; + internal static bool IsInitialized() => s_initState == InitState.Initialized; - internal static bool CanInitialize() - { - return (initState != InitState.Initializing) && - !ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress; - } + internal static bool CanInitialize() => (s_initState != InitState.Initializing) && + !ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress; internal static void Initialize() { @@ -161,23 +160,21 @@ internal static void Initialize() // 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 (initState != InitState.NotInitialized || - ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress) + if (s_initState != InitState.NotInitialized || + ConfigurationManagerInternalFactory.Instance.SetConfigurationSystemInProgress) { - return; } - initState = InitState.Initializing; // used for preventing recursion + s_initState = InitState.Initializing; // used for preventing recursion try { - configSection = GetConfigSection(); + s_configSection = GetConfigSection(); } finally { - initState = InitState.Initialized; + s_initState = InitState.Initialized; } - //} } internal static void Refresh() @@ -196,33 +193,45 @@ internal static void Refresh() // 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 = configSection; + 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(); + } } } - configSection = null; + s_configSection = null; - initState = InitState.NotInitialized; + s_initState = InitState.NotInitialized; Initialize(); } + + private enum InitState + { + NotInitialized, + Initializing, + Initialized + } } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs index b29480490e5cf8..6067c06dc5a6e2 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/FilterElement.cs @@ -22,7 +22,7 @@ internal TraceFilter RefreshRuntimeObject(TraceFilter filter) { if (Type.GetType(TypeName) != filter.GetType() || InitDataChanged(filter)) { - // type or initdata changed + // Type or initdata changed. _runtimeObject = null; return GetRuntimeObject(); } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs index 502233465f1b42..fc792347400daa 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs @@ -14,32 +14,13 @@ namespace System.Diagnostics [ConfigurationCollection(typeof(ListenerElement))] internal class ListenerElementsCollection : ConfigurationElementCollection { + public new ListenerElement this[string name] => (ListenerElement)BaseGet(name); - public new ListenerElement this[string name] - { - get - { - return (ListenerElement)BaseGet(name); - } - } + public override ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.AddRemoveClearMap; - public override ConfigurationElementCollectionType CollectionType - { - get - { - return ConfigurationElementCollectionType.AddRemoveClearMap; - } - } - - protected override ConfigurationElement CreateNewElement() - { - return new ListenerElement(true); - } + protected override ConfigurationElement CreateNewElement() => new ListenerElement(true); - protected override object GetElementKey(ConfigurationElement element) - { - return ((ListenerElement)element).Name; - } + protected override object GetElementKey(ConfigurationElement element) => ((ListenerElement)element).Name; public IEnumerable GetRuntimeObject() { @@ -47,10 +28,9 @@ public IEnumerable GetRuntimeObject() foreach (ListenerElement element in this) { - // At some point, we need to pull out adding/removing the 'default' DefaultTraceListener // code from here in favor of adding/not-adding after we load the config (in TraceSource - // and in static Trace) + // and in static Trace). listeners.Add(element.GetRuntimeObject()); } @@ -67,7 +47,7 @@ internal void InitializeDefaultInternal() defaultListener.TypeName = typeof(DefaultTraceListener).FullName; defaultListener._isAddedByDefault = true; - this.BaseAdd(defaultListener); + BaseAdd(defaultListener); } protected override void BaseAdd(ConfigurationElement element) @@ -86,38 +66,21 @@ protected override void BaseAdd(ConfigurationElement element) // This is the collection used by the sharedListener section. It is only slightly different from ListenerElementsCollection. // The differences are that it does not allow remove and clear, and that the ListenerElements it creates do not allow // references. - [ConfigurationCollection(typeof(ListenerElement), AddItemName = "add", - CollectionType = ConfigurationElementCollectionType.BasicMap)] + [ConfigurationCollection(typeof(ListenerElement), + AddItemName = "add", + CollectionType = ConfigurationElementCollectionType.BasicMap)] internal sealed class SharedListenerElementsCollection : ListenerElementsCollection { - - public override ConfigurationElementCollectionType CollectionType - { - get - { - return ConfigurationElementCollectionType.BasicMap; - } - } - - protected override ConfigurationElement CreateNewElement() - { - return new ListenerElement(false); - } - - protected override string ElementName - { - get - { - return "add"; - } - } + public override ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.BasicMap; + protected override ConfigurationElement CreateNewElement() => new ListenerElement(false); + protected override string ElementName => "add"; } internal sealed class ListenerElement : TypedElement { - private static readonly ConfigurationProperty _propFilter = new ConfigurationProperty("filter", typeof(FilterElement), null, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); - private static readonly ConfigurationProperty _propOutputOpts = new ConfigurationProperty("traceOutputOptions", typeof(TraceOptions), TraceOptions.None, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propFilter = new ConfigurationProperty("filter", typeof(FilterElement), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propName = new ConfigurationProperty("name", typeof(string), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); + private static readonly ConfigurationProperty s_propOutputOpts = new ConfigurationProperty("traceOutputOptions", typeof(TraceOptions), TraceOptions.None, ConfigurationPropertyOptions.None); private ConfigurationProperty _propListenerTypeName; private bool _allowReferences; @@ -138,40 +101,26 @@ public ListenerElement(bool allowReferences) : base(typeof(TraceListener)) _properties.Remove("type"); _properties.Add(_propListenerTypeName); - _properties.Add(_propFilter); - _properties.Add(_propName); - _properties.Add(_propOutputOpts); + _properties.Add(s_propFilter); + _properties.Add(s_propName); + _properties.Add(s_propOutputOpts); } - public StringDictionary Attributes - { - get - { - if (_attributes == null) - _attributes = new StringDictionary(); - return _attributes; - } - } + public StringDictionary Attributes => _attributes ?? new StringDictionary(); [ConfigurationProperty("filter")] - public FilterElement Filter - { - get - { - return (FilterElement)this[_propFilter]; - } - } + public FilterElement Filter => (FilterElement)this[s_propFilter]; [ConfigurationProperty("name", IsRequired = true, IsKey = true)] public string Name { get { - return (string)this[_propName]; + return (string)this[s_propName]; } set { - this[_propName] = value; + this[s_propName] = value; } } @@ -180,12 +129,12 @@ public TraceOptions TraceOutputOptions { get { - return (TraceOptions)this[_propOutputOpts]; + return (TraceOptions)this[s_propOutputOpts]; } - // This is useful when the OM becomes public. In the meantime, this can be utilized via reflection + // This is useful when the OM becomes public. In the meantime, this can be utilized via reflection. set { - this[_propOutputOpts] = value; + this[s_propOutputOpts] = value; } } @@ -205,7 +154,7 @@ public override string TypeName public override bool Equals(object compareTo) { - if (this.Name.Equals("Default") && this.TypeName.Equals(typeof(DefaultTraceListener).FullName)) + if (Name.Equals("Default") && TypeName.Equals(typeof(DefaultTraceListener).FullName)) { // This is a workaround to treat all DefaultTraceListener named 'Default' the same. // This is needed for the Config.Save to work properly as otherwise config base layers @@ -215,15 +164,12 @@ public override bool Equals(object compareTo) return (compareToElem != null) && compareToElem.Name.Equals("Default") && compareToElem.TypeName.Equals(typeof(DefaultTraceListener).FullName); } - else - return base.Equals(compareTo); - } - public override int GetHashCode() - { - return base.GetHashCode(); + return base.Equals(compareTo); } + public override int GetHashCode() => base.GetHashCode(); + public TraceListener GetRuntimeObject() { if (_runtimeObject != null) @@ -234,33 +180,42 @@ public TraceListener GetRuntimeObject() string className = TypeName; if (string.IsNullOrEmpty(className)) { - // Look it up in SharedListeners + // Look it up in SharedListeners. Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null"); - if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !string.IsNullOrEmpty(InitData)) + if (_attributes != null || ElementInformation.Properties[s_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !string.IsNullOrEmpty(InitData)) + { throw new ConfigurationErrorsException(SR.Format(SR.Reference_listener_cant_have_properties, Name)); + } if (DiagnosticsConfiguration.SharedListeners == null) + { throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); + } ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name]; if (sharedListener == null) - throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); - else { - _runtimeObject = sharedListener.GetRuntimeObject(); - return (TraceListener)_runtimeObject; + throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); } + + _runtimeObject = sharedListener.GetRuntimeObject(); + return (TraceListener)_runtimeObject; } else { - // create a new one + // Create a new one. TraceListener newListener = (TraceListener)BaseGetRuntimeObject(); s_initData.AddOrUpdate(newListener, InitData); newListener.Name = Name; newListener.Attributes = Attributes; newListener.TraceOutputOptions = TraceOutputOptions; + if (Filter != null && !string.IsNullOrEmpty(Filter.TypeName)) + { + newListener.Filter = Filter.GetRuntimeObject(); + } + _runtimeObject = newListener; return newListener; } @@ -324,20 +279,22 @@ protected internal override void Unmerge(ConfigurationElement sourceElement, // Unmerge the optional attributes cache as well ListenerElement le = sourceElement as ListenerElement; if ((le != null) && (le._attributes != null)) - this._attributes = le._attributes; + { + _attributes = le._attributes; + } } internal void ResetProperties() { - // blow away any UnrecognizedAttributes that we have deserialized earlier + // Blow away any UnrecognizedAttributes that we have deserialized earlier. if (_attributes != null) { _attributes.Clear(); _properties.Clear(); _properties.Add(_propListenerTypeName); - _properties.Add(_propFilter); - _properties.Add(_propName); - _properties.Add(_propOutputOpts); + _properties.Add(s_propFilter); + _properties.Add(s_propName); + _properties.Add(s_propOutputOpts); } } @@ -352,20 +309,24 @@ internal TraceListener RefreshRuntimeObject(TraceListener listener) // Look it up in SharedListeners and ask the sharedListener to refresh. Debug.Assert(_allowReferences, "_allowReferences must be true if type name is null"); - if (_attributes != null || ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !string.IsNullOrEmpty(InitData)) + if (_attributes != null || ElementInformation.Properties[s_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || TraceOutputOptions != TraceOptions.None || !string.IsNullOrEmpty(InitData)) + { throw new ConfigurationErrorsException(SR.Format(SR.Reference_listener_cant_have_properties, Name)); + } if (DiagnosticsConfiguration.SharedListeners == null) + { throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); + } ListenerElement sharedListener = DiagnosticsConfiguration.SharedListeners[Name]; if (sharedListener == null) - throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); - else { - _runtimeObject = sharedListener.RefreshRuntimeObject(listener); - return (TraceListener)_runtimeObject; + throw new ConfigurationErrorsException(SR.Format(SR.Reference_to_nonexistent_listener, Name)); } + + _runtimeObject = sharedListener.RefreshRuntimeObject(listener); + return (TraceListener)_runtimeObject; } else { @@ -373,7 +334,7 @@ internal TraceListener RefreshRuntimeObject(TraceListener listener) // If not, create a whole new object, otherwise, just update the other properties. if (Type.GetType(className) != listener.GetType() || InitDataChanged(listener)) { - // type or initdata changed + // Type or initdata changed. return GetRuntimeObject(); } else @@ -383,11 +344,15 @@ internal TraceListener RefreshRuntimeObject(TraceListener listener) if (listener.Filter != null) { - if (ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || - ElementInformation.Properties[_propFilter.Name].ValueOrigin == PropertyValueOrigin.Inherited) + if (ElementInformation.Properties[s_propFilter.Name].ValueOrigin == PropertyValueOrigin.SetHere || + ElementInformation.Properties[s_propFilter.Name].ValueOrigin == PropertyValueOrigin.Inherited) + { listener.Filter = Filter.RefreshRuntimeObject(listener.Filter); + } else + { listener.Filter = null; + } } _runtimeObject = listener; @@ -400,7 +365,8 @@ internal TraceListener RefreshRuntimeObject(TraceListener listener) throw new ConfigurationErrorsException(SR.Format(SR.Could_not_create_listener, Name), e); } } - - private bool InitDataChanged(TraceListener listener) => !s_initData.TryGetValue(listener, out string previousInitData) || InitData != previousInitData; + + private bool InitDataChanged(TraceListener listener) => !s_initData.TryGetValue(listener, out string previousInitData) + || InitData != previousInitData; } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs index c510ae83e47ae2..757787acbe3cd9 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs @@ -1,5 +1,6 @@ // 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.Collections; using System.Collections.Specialized; @@ -7,34 +8,16 @@ namespace System.Diagnostics { - [ConfigurationCollection(typeof(SourceElement), AddItemName = "source", - CollectionType = ConfigurationElementCollectionType.BasicMap)] + [ConfigurationCollection(typeof(SourceElement), + AddItemName = "source", + CollectionType = ConfigurationElementCollectionType.BasicMap)] internal sealed class SourceElementsCollection : ConfigurationElementCollection { + public new SourceElement this[string name] => (SourceElement)BaseGet(name); - public new SourceElement this[string name] - { - get - { - return (SourceElement)BaseGet(name); - } - } + protected override string ElementName => "source"; - protected override string ElementName - { - get - { - return "source"; - } - } - - public override ConfigurationElementCollectionType CollectionType - { - get - { - return ConfigurationElementCollectionType.BasicMap; - } - } + public override ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.BasicMap; protected override ConfigurationElement CreateNewElement() { @@ -43,10 +26,7 @@ protected override ConfigurationElement CreateNewElement() return se; } - protected override object GetElementKey(ConfigurationElement element) - { - return ((SourceElement)element).Name; - } + protected override object GetElementKey(ConfigurationElement element) => ((SourceElement)element).Name; } @@ -70,68 +50,24 @@ static SourceElement() _properties.Add(_propListeners); } - public StringDictionary Attributes - { - get - { - if (_attributes == null) - _attributes = new StringDictionary(); - return _attributes; - } - } + public StringDictionary Attributes => _attributes ??= new StringDictionary(); [ConfigurationProperty("listeners")] - public ListenerElementsCollection Listeners - { - get - { - return (ListenerElementsCollection)this[_propListeners]; - } - } + public ListenerElementsCollection Listeners => (ListenerElementsCollection)this[_propListeners]; [ConfigurationProperty("name", IsRequired = true, DefaultValue = "")] - public string Name - { - get - { - return (string)this[_propName]; - } - } + public string Name => (string)this[_propName]; - protected internal override ConfigurationPropertyCollection Properties - { - get - { - return _properties; - } - } + protected internal override ConfigurationPropertyCollection Properties => _properties; [ConfigurationProperty("switchName")] - public string SwitchName - { - get - { - return (string)this[_propSwitchName]; - } - } + public string SwitchName => (string)this[_propSwitchName]; [ConfigurationProperty("switchValue")] - public string SwitchValue - { - get - { - return (string)this[_propSwitchValue]; - } - } + public string SwitchValue => (string)this[_propSwitchValue]; [ConfigurationProperty("switchType")] - public string SwitchType - { - get - { - return (string)this[_propSwitchType]; - } - } + public string SwitchType => (string)this[_propSwitchType]; protected internal override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) { @@ -199,7 +135,7 @@ protected internal override void Unmerge(ConfigurationElement sourceElement, internal void ResetProperties() { - // blow away any UnrecognizedAttributes that we have deserialized earlier + // Blow away any UnrecognizedAttributes that we have deserialized earlier. if (_attributes != null) { _attributes.Clear(); @@ -212,5 +148,4 @@ internal void ResetProperties() } } } - } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs index 4829943ae2e660..6294b664c7f0bf 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs @@ -1,5 +1,6 @@ // 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.Collections; using System.Collections.Specialized; @@ -10,32 +11,10 @@ namespace System.Diagnostics [ConfigurationCollection(typeof(SwitchElement))] internal sealed class SwitchElementsCollection : ConfigurationElementCollection { - - public new SwitchElement this[string name] - { - get - { - return (SwitchElement)BaseGet(name); - } - } - - public override ConfigurationElementCollectionType CollectionType - { - get - { - return ConfigurationElementCollectionType.AddRemoveClearMap; - } - } - - protected override ConfigurationElement CreateNewElement() - { - return new SwitchElement(); - } - - protected override object GetElementKey(ConfigurationElement element) - { - return ((SwitchElement)element).Name; - } + public new SwitchElement this[string name] => (SwitchElement)BaseGet(name); + public override ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.AddRemoveClearMap; + protected override ConfigurationElement CreateNewElement() => new SwitchElement(); + protected override object GetElementKey(ConfigurationElement element) => ((SwitchElement)element).Name; } internal sealed class SwitchElement : ConfigurationElement @@ -52,41 +31,15 @@ static SwitchElement() _properties.Add(_propValue); } - public StringDictionary Attributes - { - get - { - if (_attributes == null) - _attributes = new StringDictionary(); - return _attributes; - } - } + public StringDictionary Attributes => _attributes ??= new StringDictionary(); [ConfigurationProperty("name", DefaultValue = "", IsRequired = true, IsKey = true)] - public string Name - { - get - { - return (string)this[_propName]; - } - } + public string Name => (string)this[_propName]; - protected internal override ConfigurationPropertyCollection Properties - { - get - { - return _properties; - } - } + protected internal override ConfigurationPropertyCollection Properties => _properties; [ConfigurationProperty("value", IsRequired = true)] - public string Value - { - get - { - return (string)this[_propValue]; - } - } + public string Value => (string)this[_propValue]; // Our optional attributes implementation is little convoluted as there is // no such firsclass mechanism from the config system. We basically cache @@ -146,7 +99,7 @@ protected internal override void Unmerge(ConfigurationElement sourceElement, internal void ResetProperties() { - // blow away any UnrecognizedAttributes that we have deserialized earlier + // Blow away any UnrecognizedAttributes that we have deserialized earlier. if (_attributes != null) { _attributes.Clear(); diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs index f7e837591f006d..3a14ffabdf07bc 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs @@ -1,68 +1,39 @@ // 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; namespace System.Diagnostics { internal sealed class SystemDiagnosticsSection : ConfigurationSection { - private static readonly ConfigurationPropertyCollection _properties = new(); - private static readonly ConfigurationProperty _propSources = new ConfigurationProperty("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propSharedListeners = new ConfigurationProperty("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propSwitches = new ConfigurationProperty("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propTrace = new ConfigurationProperty("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationPropertyCollection s_properties = new(); + private static readonly ConfigurationProperty s_propSources = new ConfigurationProperty("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSharedListeners = new ConfigurationProperty("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSwitches = new ConfigurationProperty("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propTrace = new ConfigurationProperty("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); static SystemDiagnosticsSection() { - _properties.Add(_propSources); - _properties.Add(_propSharedListeners); - _properties.Add(_propSwitches); - _properties.Add(_propTrace); + s_properties.Add(s_propSources); + s_properties.Add(s_propSharedListeners); + s_properties.Add(s_propSwitches); + s_properties.Add(s_propTrace); } - protected internal override ConfigurationPropertyCollection Properties - { - get - { - return _properties; - } - } + protected internal override ConfigurationPropertyCollection Properties => s_properties; [ConfigurationProperty("sources")] - public SourceElementsCollection Sources - { - get - { - return (SourceElementsCollection)base[_propSources]; - } - } + public SourceElementsCollection Sources => (SourceElementsCollection)base[s_propSources]; [ConfigurationProperty("sharedListeners")] - public ListenerElementsCollection SharedListeners - { - get - { - return (ListenerElementsCollection)base[_propSharedListeners]; - } - } + public ListenerElementsCollection SharedListeners => (ListenerElementsCollection)base[s_propSharedListeners]; [ConfigurationProperty("switches")] - public SwitchElementsCollection Switches - { - get - { - return (SwitchElementsCollection)base[_propSwitches]; - } - } + public SwitchElementsCollection Switches => (SwitchElementsCollection)base[s_propSwitches]; [ConfigurationProperty("trace")] - public TraceSection Trace - { - get - { - return (TraceSection)base[_propTrace]; - } - } + public TraceSection Trace => (TraceSection)base[s_propTrace]; protected internal override void InitializeDefault() { diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs index b9c549a6b7b595..516cbaccfad902 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs @@ -1,22 +1,39 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections; + +using System.Xml.Linq; namespace System.Diagnostics { public static class TraceConfiguration { + private static volatile bool s_registered; + + /// + /// Register the configuration system to apply settings from configuration files + /// to and related classes. + /// public static void Register() { - // register callbacks - Trace.ConfigureSwitch += ConfigureSwitch; - Trace.ConfigureTrace += ConfigureTraceSettings; - Trace.ConfigureTraceSource += ConfigureTraceSource; + if (!s_registered) + { + // Registering callbacks more than once is fine, but avoid the overhead common cases without taking a lock. + Trace.RefreshConfiguration += RefreshConfiguration; + Trace.ConfigureSwitch += ConfigureSwitch; + Trace.ConfigureTrace += ConfigureTraceSettings; + Trace.ConfigureTraceSource += ConfigureTraceSource; + + s_registered = true; + } } - private static void ConfigureTraceSource(TraceSource traceSource) + private static void RefreshConfiguration(object sender, EventArgs e) => DiagnosticsConfiguration.Refresh(); + + private static void ConfigureTraceSource(object sender, ConfigureTraceSourceEventArgs e) { - // ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceSource.cs,176 + TraceSource traceSource = e.TraceSource; + + // Ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceSource.cs,176 SourceElementsCollection sources = DiagnosticsConfiguration.Sources; if (sources != null) @@ -24,11 +41,11 @@ private static void ConfigureTraceSource(TraceSource traceSource) SourceElement sourceElement = sources[traceSource.Name]; if (sourceElement != null) { - // first check if the type changed - if ((string.IsNullOrEmpty(sourceElement.SwitchType) && traceSource.Switch.GetType() != typeof(SourceSwitch)) || - (sourceElement.SwitchType != traceSource.Switch.GetType().AssemblyQualifiedName)) - { + e.WasConfigured = true; + // First check if the type changed. + if (SourceSwitchTypeChanged()) + { if (!string.IsNullOrEmpty(sourceElement.SwitchName)) { CreateSwitch(sourceElement.SwitchType, sourceElement.SwitchName); @@ -38,12 +55,14 @@ private static void ConfigureTraceSource(TraceSource traceSource) CreateSwitch(sourceElement.SwitchType, traceSource.Name); if (!string.IsNullOrEmpty(sourceElement.SwitchValue)) + { traceSource.Switch.Level = (SourceLevels)Enum.Parse(typeof(SourceLevels), sourceElement.SwitchValue); + } } } else if (!string.IsNullOrEmpty(sourceElement.SwitchName)) { - // create a new switch if the name changed, otherwise just refresh. + // Create a new switch if the name changed, otherwise just refresh. if (sourceElement.SwitchName != traceSource.Switch.DisplayName) CreateSwitch(sourceElement.SwitchType, sourceElement.SwitchName); else @@ -53,11 +72,15 @@ private static void ConfigureTraceSource(TraceSource traceSource) } else { - // the switchValue changed. Just update our internalSwitch. + // The SwitchValue changed; just update our internalSwitch. if (!string.IsNullOrEmpty(sourceElement.SwitchValue)) + { traceSource.Switch.Level = (SourceLevels)Enum.Parse(typeof(SourceLevels), sourceElement.SwitchValue); + } else + { traceSource.Switch.Level = SourceLevels.Off; + } } TraceListener[] newListenerCollection = new TraceListener[sourceElement.Listeners.Count]; @@ -82,25 +105,42 @@ private static void ConfigureTraceSource(TraceSource traceSource) } else { - // there was no config, so clear whatever we have. + // There was no config, so clear whatever we have. traceSource.Switch.Level = traceSource.DefaultLevel; traceSource.Listeners.Clear(); traceSource.Attributes.Clear(); } + + bool SourceSwitchTypeChanged() + { + string sourceTypeName = sourceElement.SwitchType; + Type currentType = traceSource.Switch.GetType(); + + return (string.IsNullOrEmpty(sourceTypeName) && currentType != typeof(SourceSwitch)) || + (!string.IsNullOrEmpty(sourceTypeName) && + // Compare with FullName only + sourceTypeName != currentType.FullName && + // Compare with FullName plus start of AssemblyQualifiedName + !sourceTypeName.StartsWith(currentType.FullName + ",")); + } } void CreateSwitch(string typeName, string name) { if (!string.IsNullOrEmpty(typeName)) + { traceSource.Switch = (SourceSwitch)TraceUtils.GetRuntimeObject(typeName, typeof(SourceSwitch), name); + } else + { traceSource.Switch = new SourceSwitch(name, traceSource.DefaultLevel.ToString()); + } } } - private static void ConfigureTraceSettings() + private static void ConfigureTraceSettings(object sender, EventArgs e) { - // ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,06360b4de5e221c2, https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,37 + // Ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,06360b4de5e221c2, https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,37 TraceSection traceSection = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace; @@ -123,29 +163,30 @@ private static void ConfigureTraceSettings() } } - private static void ConfigureSwitch(Switch @switch) + private static void ConfigureSwitch(object sender, ConfigureSwitchEventArgs e) { - // ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/Switch.cs,173 + Switch sw = e.Switch; + + // Ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/Switch.cs,173 SwitchElementsCollection switchSettings = DiagnosticsConfiguration.SwitchSettings; if (switchSettings != null) { - SwitchElement mySettings = switchSettings[@switch.DisplayName]; + SwitchElement mySettings = switchSettings[sw.DisplayName]; if (mySettings != null) { if (mySettings.Value != null) { - @switch.Value = mySettings.Value; + sw.Value = mySettings.Value; } else { - @switch.Value = @switch.DefaultValue; + sw.Value = sw.DefaultValue; } - @switch.Attributes = mySettings.Attributes; + sw.Attributes = mySettings.Attributes; } } - } } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs index 11a260175c23a3..95c7a17b1bb202 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs @@ -7,62 +7,32 @@ namespace System.Diagnostics { internal sealed class TraceSection : ConfigurationElement { - private static readonly ConfigurationPropertyCollection _properties = new(); - private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), null, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propAutoFlush = new ConfigurationProperty("autoflush", typeof(bool), false, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propIndentSize = new ConfigurationProperty("indentsize", typeof(int), 4, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propUseGlobalLock = new ConfigurationProperty("useGlobalLock", typeof(bool), true, ConfigurationPropertyOptions.None); + private static readonly ConfigurationPropertyCollection s_properties = new(); + private static readonly ConfigurationProperty s_propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propAutoFlush = new ConfigurationProperty("autoflush", typeof(bool), false, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propIndentSize = new ConfigurationProperty("indentsize", typeof(int), 4, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propUseGlobalLock = new ConfigurationProperty("useGlobalLock", typeof(bool), true, ConfigurationPropertyOptions.None); static TraceSection() { - _properties.Add(_propListeners); - _properties.Add(_propAutoFlush); - _properties.Add(_propIndentSize); - _properties.Add(_propUseGlobalLock); + s_properties.Add(s_propListeners); + s_properties.Add(s_propAutoFlush); + s_properties.Add(s_propIndentSize); + s_properties.Add(s_propUseGlobalLock); } [ConfigurationProperty("autoflush", DefaultValue = false)] - public bool AutoFlush - { - get - { - return (bool)this[_propAutoFlush]; - } - } + public bool AutoFlush => (bool)this[s_propAutoFlush]; [ConfigurationProperty("indentsize", DefaultValue = 4)] - public int IndentSize - { - get - { - return (int)this[_propIndentSize]; - } - } + public int IndentSize => (int)this[s_propIndentSize]; [ConfigurationProperty("listeners")] - public ListenerElementsCollection Listeners - { - get - { - return (ListenerElementsCollection)this[_propListeners]; - } - } + public ListenerElementsCollection Listeners => (ListenerElementsCollection)this[s_propListeners]; [ConfigurationProperty("useGlobalLock", DefaultValue = true)] - public bool UseGlobalLock - { - get - { - return (bool)this[_propUseGlobalLock]; - } - } + public bool UseGlobalLock => (bool)this[s_propUseGlobalLock]; - protected internal override ConfigurationPropertyCollection Properties - { - get - { - return _properties; - } - } + protected internal override ConfigurationPropertyCollection Properties => s_properties; } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceUtils.cs similarity index 65% rename from src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs rename to src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceUtils.cs index 51bc4c3f6d67fb..0d44b55b8e1dd2 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/traceutils.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceUtils.cs @@ -1,5 +1,6 @@ // 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.IO; using System.Reflection; @@ -11,21 +12,33 @@ namespace System.Diagnostics { internal static class TraceUtils { + private const string SystemDiagnostics = "System.Diagnostics."; + internal static object GetRuntimeObject(string className, Type baseType, string initializeData) { object newObject = null; - Type objectType; + Type objectType = null; if (className.Length == 0) { throw new ConfigurationErrorsException(SR.EmptyTypeName_NotAllowed); } - objectType = Type.GetType(className); + if (className.StartsWith(SystemDiagnostics)) + { + // Since the config file likely has just the FullName without the assembly name, + // map the FullName to the built in types. + objectType = MapToBuiltInTypes(className); + } if (objectType == null) { - throw new ConfigurationErrorsException(SR.Format(SR.Could_not_find_type, className)); + objectType = Type.GetType(className); + + if (objectType == null) + { + throw new ConfigurationErrorsException(SR.Format(SR.Could_not_find_type, className)); + } } if (!baseType.IsAssignableFrom(objectType)) @@ -39,7 +52,7 @@ internal static object GetRuntimeObject(string className, Type baseType, string if (IsOwnedTL(objectType)) throw new ConfigurationErrorsException(SR.TL_InitializeData_NotSpecified); - // create an object with parameterless constructor + // Create an object with parameterless constructor. ConstructorInfo ctorInfo = objectType.GetConstructor(Array.Empty()); if (ctorInfo == null) throw new ConfigurationErrorsException(SR.Format(SR.Could_not_get_constructor, className)); @@ -47,14 +60,14 @@ internal static object GetRuntimeObject(string className, Type baseType, string } else { - // create an object with a one-string constructor - // first look for a string constructor + // Create an object with a one-string constructor. + // First look for a string constructor. ConstructorInfo ctorInfo = objectType.GetConstructor(new Type[] { typeof(string) }); if (ctorInfo != null) { // Special case to enable specifying relative path to trace file from config for // our own TextWriterTraceListener derivatives. We will prepend it with fullpath - // prefix from config file location + // prefix from config file location. if (IsOwnedTextWriterTL(objectType)) { if ((initializeData[0] != Path.DirectorySeparatorChar) && (initializeData[0] != Path.AltDirectorySeparatorChar) && !Path.IsPathRooted(initializeData)) @@ -74,10 +87,13 @@ internal static object GetRuntimeObject(string className, Type baseType, string } else { - // now look for another 1 param constructor. + // Now look for another 1 param constructor. ConstructorInfo[] ctorInfos = objectType.GetConstructors(); if (ctorInfos == null) + { throw new ConfigurationErrorsException(SR.Format(SR.Could_not_get_constructor, className)); + } + for (int i = 0; i < ctorInfos.Length; i++) { ParameterInfo[] ctorparams = ctorInfos[i].GetParameters(); @@ -98,7 +114,7 @@ internal static object GetRuntimeObject(string className, Type baseType, string catch (Exception e) { innerException = e; - // ignore exceptions for now. If we don't have a newObject at the end, then we'll throw. + // Ignore exceptions for now. If we don't have a newObject at the end, then we'll throw. } } } @@ -114,20 +130,61 @@ internal static object GetRuntimeObject(string className, Type baseType, string if (newObject == null) { if (innerException != null) + { throw new ConfigurationErrorsException(SR.Format(SR.Could_not_create_type_instance, className), innerException); - else - throw new ConfigurationErrorsException(SR.Format(SR.Could_not_create_type_instance, className)); + } + + throw new ConfigurationErrorsException(SR.Format(SR.Could_not_create_type_instance, className)); } return newObject; } - // Our own tracelisteners that needs extra config validation + private static Type MapToBuiltInTypes(string className) + { + string name = className.Substring(SystemDiagnostics.Length); + switch (name) + { + // Types in System.Diagnostics.TraceSource.dll: + case nameof(DefaultTraceListener): + return typeof(DefaultTraceListener); + case nameof(SourceFilter): + return typeof(SourceFilter); + case nameof(EventTypeFilter): + return typeof(EventTypeFilter); + case nameof(BooleanSwitch): + return typeof(BooleanSwitch); + case nameof(TraceSwitch): + return typeof(TraceSwitch); + case nameof(SourceSwitch): + return typeof(SourceSwitch); + + // Types in System.Diagnostics.TextWriterTraceListener: + case nameof(ConsoleTraceListener): + return typeof(ConsoleTraceListener); + case nameof(DelimitedListTraceListener): + return typeof(DelimitedListTraceListener); + case nameof(XmlWriterTraceListener): + return typeof(XmlWriterTraceListener); + case nameof(TextWriterTraceListener): + return typeof(TextWriterTraceListener); + + // Types in System.Diagnostics.EventLog.dll: + case nameof(EventLogTraceListener): + return typeof(EventLogTraceListener); + + default: + return null; + } + } + + // Our own tracelisteners that needs extra config validation. internal static bool IsOwnedTL(Type type) { - return (typeof(EventLogTraceListener) == type - || IsOwnedTextWriterTL(type)); + return typeof(EventLogTraceListener) == type + || IsOwnedTextWriterTL(type); } + internal static bool IsOwnedTextWriterTL(Type type) { return (typeof(XmlWriterTraceListener) == type) @@ -137,10 +194,9 @@ internal static bool IsOwnedTextWriterTL(Type type) private static object ConvertToBaseTypeOrEnum(string value, Type type) { - if (type.IsEnum) - return Enum.Parse(type, value, false); - else - return Convert.ChangeType(value, type, CultureInfo.InvariantCulture); + return type.IsEnum ? + Enum.Parse(type, value, false) : + Convert.ChangeType(value, type, CultureInfo.InvariantCulture); } } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs index 6a281101271f84..7f0c063f1f6ee1 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs @@ -6,8 +6,8 @@ namespace System.Diagnostics { internal class TypedElement : ConfigurationElement { - protected static readonly ConfigurationProperty _propTypeName = new ConfigurationProperty("type", typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsTypeStringTransformationRequired); - protected static readonly ConfigurationProperty _propInitData = new ConfigurationProperty("initializeData", typeof(string), string.Empty, ConfigurationPropertyOptions.None); + protected static readonly ConfigurationProperty s_propTypeName = new ConfigurationProperty("type", typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsTypeStringTransformationRequired); + protected static readonly ConfigurationProperty s_propInitData = new ConfigurationProperty("initializeData", typeof(string), string.Empty, ConfigurationPropertyOptions.None); protected ConfigurationPropertyCollection _properties; protected object _runtimeObject; @@ -16,8 +16,8 @@ internal class TypedElement : ConfigurationElement public TypedElement(Type baseType) : base() { _properties = new ConfigurationPropertyCollection(); - _properties.Add(_propTypeName); - _properties.Add(_propInitData); + _properties.Add(s_propTypeName); + _properties.Add(s_propInitData); _baseType = baseType; } @@ -27,34 +27,27 @@ public string InitData { get { - return (string)this[_propInitData]; + return (string)this[s_propInitData]; } - // This is useful when the OM becomes public. In the meantime, this can be utilized via reflection + // This is useful when the OM becomes public. In the meantime, this can be utilized via reflection. set { - this[_propInitData] = value; + this[s_propInitData] = value; } - } - protected internal override ConfigurationPropertyCollection Properties - { - get - { - return _properties; - } - } + protected internal override ConfigurationPropertyCollection Properties => _properties; [ConfigurationProperty("type", IsRequired = true, DefaultValue = "")] public virtual string TypeName { get { - return (string)this[_propTypeName]; + return (string)this[s_propTypeName]; } set { - this[_propTypeName] = value; + this[s_propTypeName] = value; } } @@ -65,6 +58,5 @@ protected object BaseGetRuntimeObject() return _runtimeObject; } - } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj index 733fcd5adf9813..8f28909e9dc4e2 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj @@ -5,22 +5,14 @@ true - - - - - - - - + + + + + + + + @@ -98,13 +90,19 @@ + + + + + + diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Diagnostics/DiagnosticsTestData.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Diagnostics/DiagnosticsTestData.cs new file mode 100644 index 00000000000000..05bbdbe991140f --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Diagnostics/DiagnosticsTestData.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.DiagnosticsTests +{ + public static class DiagnosticsTestData + { + public static string Sample = +@" + + + + + + + + + + + + + + + + + + + + + +"; + } +} diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Diagnostics/TraceSourceConfigurationTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Diagnostics/TraceSourceConfigurationTests.cs new file mode 100644 index 00000000000000..2ea13aeb31983e --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Diagnostics/TraceSourceConfigurationTests.cs @@ -0,0 +1,78 @@ +// 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.Diagnostics; +using System.DiagnosticsTests; +using System.Reflection; +using Xunit; + +namespace System.Diagnostics.Tests +{ + public class DiagnosticConfigurationTests + { + [Fact] + public void ReadConfigSectionsFromFile() + { + using (var temp = new TempConfig(DiagnosticsTestData.Sample)) + { + var config = ConfigurationManager.OpenExeConfiguration(temp.ExePath); + + ConfigurationSection section = config.GetSection("system.diagnostics"); + Assert.NotNull(section); + Assert.Equal("SystemDiagnosticsSection", section.GetType().Name); + + ConfigurationElementCollection collection; + ConfigurationElement[] items; + + // Verify Switches + collection = (ConfigurationElementCollection)GetPropertyValue("Switches"); + Assert.Equal("SwitchElementsCollection", collection.GetType().Name); + Assert.Equal(1, collection.Count); + items = new ConfigurationElement[1]; + collection.CopyTo(items, 0); + Assert.Equal("sourceSwitch", items[0].ElementInformation.Properties["name"].Value.ToString()); + Assert.Equal("Error", items[0].ElementInformation.Properties["value"].Value.ToString()); + + // Verify SharedListeners + collection = (ConfigurationElementCollection)GetPropertyValue("SharedListeners"); + Assert.Equal("SharedListenerElementsCollection", collection.GetType().Name); + Assert.Equal(1, collection.Count); + items = new ConfigurationElement[1]; + collection.CopyTo(items, 0); + Assert.Equal("myListener", items[0].ElementInformation.Properties["name"].Value.ToString()); + Assert.Equal("System.Diagnostics.TextWriterTraceListener", items[0].ElementInformation.Properties["type"].Value.ToString()); + Assert.Equal("myListener.log", items[0].ElementInformation.Properties["initializeData"].Value.ToString()); + + // Verify Sources + collection = (ConfigurationElementCollection)GetPropertyValue("Sources"); + Assert.Equal("SourceElementsCollection", GetPropertyValue("Sources").GetType().Name); + Assert.Equal(1, collection.Count); + items = new ConfigurationElement[1]; + collection.CopyTo(items, 0); + Assert.Equal("TraceSourceApp", items[0].ElementInformation.Properties["name"].Value.ToString()); + Assert.Equal("sourceSwitch", items[0].ElementInformation.Properties["switchName"].Value.ToString()); + Assert.Equal("System.Diagnostics.SourceSwitch", items[0].ElementInformation.Properties["switchType"].Value); + + ConfigurationElementCollection listeners = (ConfigurationElementCollection)items[0].ElementInformation.Properties["listeners"].Value; + Assert.Equal("ListenerElementsCollection", listeners.GetType().Name); + Assert.Equal(2, listeners.Count); + ConfigurationElement[] listenerItems = new ConfigurationElement[2]; + listeners.CopyTo(listenerItems, 0); + Assert.Equal("console", listenerItems[0].ElementInformation.Properties["name"].Value.ToString()); + Assert.Equal("System.Diagnostics.ConsoleTraceListener", listenerItems[0].ElementInformation.Properties["type"].Value.ToString()); + Assert.Equal("myListener", listenerItems[1].ElementInformation.Properties["name"].Value.ToString()); + + ConfigurationElement filter = (ConfigurationElement)listenerItems[0].ElementInformation.Properties["filter"].Value; + Assert.Equal("FilterElement", filter.GetType().Name); + Assert.Equal("System.Diagnostics.EventTypeFilter", filter.ElementInformation.Properties["type"].Value.ToString()); + Assert.Equal("Error", filter.ElementInformation.Properties["initializeData"].Value.ToString()); + + object GetPropertyValue(string propertyName) => section.GetType(). + GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance). + GetValue(section); + } + } + } +} + diff --git a/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.sln b/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.sln index 897ad3f4f502c6..0de933741901b4 100644 --- a/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.sln +++ b/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.sln @@ -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.3.32714.290 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "..\..\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj", "{89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{F6BCA6EF-777E-408B-B49B-B055B5A0BA19}" @@ -25,7 +29,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.TraceSou EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.TraceSource", "src\System.Diagnostics.TraceSource.csproj", "{48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.TraceSource.Tests", "tests\System.Diagnostics.TraceSource.Tests.csproj", "{0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.TraceSource.Tests", "tests\System.Diagnostics.TraceSource.Tests\System.Diagnostics.TraceSource.Tests.csproj", "{0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ObjectModel", "..\System.ObjectModel\ref\System.ObjectModel.csproj", "{535A9671-08A0-46DD-8191-DC9B995DF425}" EndProject @@ -53,19 +57,27 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{1826CD8D-A5E EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{BDABB39C-A9FF-4A9B-8BA2-EF873C5EEB16}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.TraceSource.Config.Tests", "tests\System.Diagnostics.TraceSource.Config.Tests\System.Diagnostics.TraceSource.Config.Tests.csproj", "{422C9340-E720-4554-B6AC-560A19FE16B1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Checked|Any CPU = Checked|Any CPU + Checked|x64 = Checked|x64 + Checked|x86 = Checked|x86 Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 - Checked|Any CPU = Checked|Any CPU - Checked|x64 = Checked|x64 - Checked|x86 = Checked|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|Any CPU.ActiveCfg = Checked|x64 + {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|Any CPU.Build.0 = Checked|x64 + {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|x64.ActiveCfg = Checked|x64 + {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|x64.Build.0 = Checked|x64 + {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|x86.ActiveCfg = Checked|x86 + {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|x86.Build.0 = Checked|x86 {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Debug|Any CPU.ActiveCfg = Debug|x64 {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Debug|Any CPU.Build.0 = Debug|x64 {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Debug|x64.ActiveCfg = Debug|x64 @@ -78,12 +90,12 @@ Global {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Release|x64.Build.0 = Release|x64 {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Release|x86.ActiveCfg = Release|x86 {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Release|x86.Build.0 = Release|x86 - {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|Any CPU.ActiveCfg = Checked|x64 - {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|Any CPU.Build.0 = Checked|x64 - {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|x64.ActiveCfg = Checked|x64 - {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|x64.Build.0 = Checked|x64 - {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|x86.ActiveCfg = Checked|x86 - {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73}.Checked|x86.Build.0 = Checked|x86 + {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|Any CPU.Build.0 = Debug|Any CPU + {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|x64.ActiveCfg = Debug|Any CPU + {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|x64.Build.0 = Debug|Any CPU + {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|x86.ActiveCfg = Debug|Any CPU + {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|x86.Build.0 = Debug|Any CPU {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Debug|Any CPU.Build.0 = Debug|Any CPU {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -96,12 +108,12 @@ Global {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Release|x64.Build.0 = Release|Any CPU {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Release|x86.ActiveCfg = Release|Any CPU {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Release|x86.Build.0 = Release|Any CPU - {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|Any CPU.Build.0 = Debug|Any CPU - {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|x64.ActiveCfg = Debug|Any CPU - {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|x64.Build.0 = Debug|Any CPU - {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|x86.ActiveCfg = Debug|Any CPU - {F6BCA6EF-777E-408B-B49B-B055B5A0BA19}.Checked|x86.Build.0 = Debug|Any CPU + {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|Any CPU.Build.0 = Debug|Any CPU + {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|x64.ActiveCfg = Debug|Any CPU + {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|x64.Build.0 = Debug|Any CPU + {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|x86.ActiveCfg = Debug|Any CPU + {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|x86.Build.0 = Debug|Any CPU {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Debug|Any CPU.Build.0 = Debug|Any CPU {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -114,12 +126,12 @@ Global {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Release|x64.Build.0 = Release|Any CPU {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Release|x86.ActiveCfg = Release|Any CPU {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Release|x86.Build.0 = Release|Any CPU - {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|Any CPU.Build.0 = Debug|Any CPU - {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|x64.ActiveCfg = Debug|Any CPU - {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|x64.Build.0 = Debug|Any CPU - {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|x86.ActiveCfg = Debug|Any CPU - {A26E9B9C-AFE7-4740-AC73-626D9823E515}.Checked|x86.Build.0 = Debug|Any CPU + {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|Any CPU.Build.0 = Debug|Any CPU + {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|x64.ActiveCfg = Debug|Any CPU + {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|x64.Build.0 = Debug|Any CPU + {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|x86.ActiveCfg = Debug|Any CPU + {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|x86.Build.0 = Debug|Any CPU {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Debug|Any CPU.Build.0 = Debug|Any CPU {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -132,12 +144,12 @@ Global {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Release|x64.Build.0 = Release|Any CPU {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Release|x86.ActiveCfg = Release|Any CPU {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Release|x86.Build.0 = Release|Any CPU - {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|Any CPU.Build.0 = Debug|Any CPU - {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|x64.ActiveCfg = Debug|Any CPU - {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|x64.Build.0 = Debug|Any CPU - {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|x86.ActiveCfg = Debug|Any CPU - {89C01491-2BE8-438C-8F1D-24DE9AFD7A86}.Checked|x86.Build.0 = Debug|Any CPU + {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|Any CPU.Build.0 = Debug|Any CPU + {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|x64.ActiveCfg = Debug|Any CPU + {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|x64.Build.0 = Debug|Any CPU + {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|x86.ActiveCfg = Debug|Any CPU + {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|x86.Build.0 = Debug|Any CPU {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Debug|Any CPU.Build.0 = Debug|Any CPU {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -150,12 +162,12 @@ Global {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Release|x64.Build.0 = Release|Any CPU {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Release|x86.ActiveCfg = Release|Any CPU {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Release|x86.Build.0 = Release|Any CPU - {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|Any CPU.Build.0 = Debug|Any CPU - {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|x64.ActiveCfg = Debug|Any CPU - {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|x64.Build.0 = Debug|Any CPU - {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|x86.ActiveCfg = Debug|Any CPU - {51AEBD0E-0A93-4532-A010-CAAF8E320D6C}.Checked|x86.Build.0 = Debug|Any CPU + {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|Any CPU.Build.0 = Debug|Any CPU + {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|x64.ActiveCfg = Debug|Any CPU + {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|x64.Build.0 = Debug|Any CPU + {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|x86.ActiveCfg = Debug|Any CPU + {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|x86.Build.0 = Debug|Any CPU {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Debug|Any CPU.Build.0 = Debug|Any CPU {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -168,12 +180,12 @@ Global {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Release|x64.Build.0 = Release|Any CPU {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Release|x86.ActiveCfg = Release|Any CPU {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Release|x86.Build.0 = Release|Any CPU - {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|Any CPU.Build.0 = Debug|Any CPU - {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|x64.ActiveCfg = Debug|Any CPU - {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|x64.Build.0 = Debug|Any CPU - {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|x86.ActiveCfg = Debug|Any CPU - {64F83961-AECA-4D5C-B467-A1A94AE6FFB4}.Checked|x86.Build.0 = Debug|Any CPU + {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|Any CPU.Build.0 = Debug|Any CPU + {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|x64.ActiveCfg = Debug|Any CPU + {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|x64.Build.0 = Debug|Any CPU + {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|x86.ActiveCfg = Debug|Any CPU + {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|x86.Build.0 = Debug|Any CPU {279066F9-4DB9-4897-8CE4-66BC31118323}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {279066F9-4DB9-4897-8CE4-66BC31118323}.Debug|Any CPU.Build.0 = Debug|Any CPU {279066F9-4DB9-4897-8CE4-66BC31118323}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -186,12 +198,12 @@ Global {279066F9-4DB9-4897-8CE4-66BC31118323}.Release|x64.Build.0 = Release|Any CPU {279066F9-4DB9-4897-8CE4-66BC31118323}.Release|x86.ActiveCfg = Release|Any CPU {279066F9-4DB9-4897-8CE4-66BC31118323}.Release|x86.Build.0 = Release|Any CPU - {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|Any CPU.Build.0 = Debug|Any CPU - {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|x64.ActiveCfg = Debug|Any CPU - {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|x64.Build.0 = Debug|Any CPU - {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|x86.ActiveCfg = Debug|Any CPU - {279066F9-4DB9-4897-8CE4-66BC31118323}.Checked|x86.Build.0 = Debug|Any CPU + {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|Any CPU.Build.0 = Debug|Any CPU + {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|x64.ActiveCfg = Debug|Any CPU + {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|x64.Build.0 = Debug|Any CPU + {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|x86.ActiveCfg = Debug|Any CPU + {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|x86.Build.0 = Debug|Any CPU {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Debug|Any CPU.Build.0 = Debug|Any CPU {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -204,12 +216,12 @@ Global {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Release|x64.Build.0 = Release|Any CPU {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Release|x86.ActiveCfg = Release|Any CPU {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Release|x86.Build.0 = Release|Any CPU - {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|Any CPU.Build.0 = Debug|Any CPU - {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|x64.ActiveCfg = Debug|Any CPU - {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|x64.Build.0 = Debug|Any CPU - {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|x86.ActiveCfg = Debug|Any CPU - {95F843FE-38B4-4ED5-81FF-605DE38155F6}.Checked|x86.Build.0 = Debug|Any CPU + {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|Any CPU.Build.0 = Debug|Any CPU + {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|x64.ActiveCfg = Debug|Any CPU + {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|x64.Build.0 = Debug|Any CPU + {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|x86.ActiveCfg = Debug|Any CPU + {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|x86.Build.0 = Debug|Any CPU {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Debug|Any CPU.Build.0 = Debug|Any CPU {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -222,12 +234,12 @@ Global {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Release|x64.Build.0 = Release|Any CPU {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Release|x86.ActiveCfg = Release|Any CPU {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Release|x86.Build.0 = Release|Any CPU - {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|Any CPU.Build.0 = Debug|Any CPU - {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|x64.ActiveCfg = Debug|Any CPU - {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|x64.Build.0 = Debug|Any CPU - {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|x86.ActiveCfg = Debug|Any CPU - {ED544AD5-41C5-4445-BC0F-EFA1553C881A}.Checked|x86.Build.0 = Debug|Any CPU + {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|Any CPU.Build.0 = Debug|Any CPU + {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|x64.ActiveCfg = Debug|Any CPU + {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|x64.Build.0 = Debug|Any CPU + {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|x86.ActiveCfg = Debug|Any CPU + {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|x86.Build.0 = Debug|Any CPU {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Debug|Any CPU.Build.0 = Debug|Any CPU {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -240,12 +252,12 @@ Global {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Release|x64.Build.0 = Release|Any CPU {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Release|x86.ActiveCfg = Release|Any CPU {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Release|x86.Build.0 = Release|Any CPU - {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|Any CPU.Build.0 = Debug|Any CPU - {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|x64.ActiveCfg = Debug|Any CPU - {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|x64.Build.0 = Debug|Any CPU - {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|x86.ActiveCfg = Debug|Any CPU - {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4}.Checked|x86.Build.0 = Debug|Any CPU + {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|Any CPU.Build.0 = Debug|Any CPU + {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|x64.ActiveCfg = Debug|Any CPU + {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|x64.Build.0 = Debug|Any CPU + {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|x86.ActiveCfg = Debug|Any CPU + {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|x86.Build.0 = Debug|Any CPU {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -258,12 +270,12 @@ Global {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Release|x64.Build.0 = Release|Any CPU {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Release|x86.ActiveCfg = Release|Any CPU {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Release|x86.Build.0 = Release|Any CPU - {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|Any CPU.Build.0 = Debug|Any CPU - {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|x64.ActiveCfg = Debug|Any CPU - {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|x64.Build.0 = Debug|Any CPU - {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|x86.ActiveCfg = Debug|Any CPU - {83696A63-CF89-4DE4-8F79-96F5B830A4B6}.Checked|x86.Build.0 = Debug|Any CPU + {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|Any CPU.Build.0 = Debug|Any CPU + {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|x64.ActiveCfg = Debug|Any CPU + {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|x64.Build.0 = Debug|Any CPU + {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|x86.ActiveCfg = Debug|Any CPU + {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|x86.Build.0 = Debug|Any CPU {2F00396E-003A-4385-92DC-69FDBEF330D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2F00396E-003A-4385-92DC-69FDBEF330D8}.Debug|Any CPU.Build.0 = Debug|Any CPU {2F00396E-003A-4385-92DC-69FDBEF330D8}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -276,12 +288,12 @@ Global {2F00396E-003A-4385-92DC-69FDBEF330D8}.Release|x64.Build.0 = Release|Any CPU {2F00396E-003A-4385-92DC-69FDBEF330D8}.Release|x86.ActiveCfg = Release|Any CPU {2F00396E-003A-4385-92DC-69FDBEF330D8}.Release|x86.Build.0 = Release|Any CPU - {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|Any CPU.Build.0 = Debug|Any CPU - {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|x64.ActiveCfg = Debug|Any CPU - {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|x64.Build.0 = Debug|Any CPU - {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|x86.ActiveCfg = Debug|Any CPU - {2F00396E-003A-4385-92DC-69FDBEF330D8}.Checked|x86.Build.0 = Debug|Any CPU + {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|Any CPU.Build.0 = Debug|Any CPU + {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|x64.ActiveCfg = Debug|Any CPU + {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|x64.Build.0 = Debug|Any CPU + {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|x86.ActiveCfg = Debug|Any CPU + {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|x86.Build.0 = Debug|Any CPU {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Debug|Any CPU.Build.0 = Debug|Any CPU {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -294,12 +306,12 @@ Global {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Release|x64.Build.0 = Release|Any CPU {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Release|x86.ActiveCfg = Release|Any CPU {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Release|x86.Build.0 = Release|Any CPU - {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|Any CPU.Build.0 = Debug|Any CPU - {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|x64.ActiveCfg = Debug|Any CPU - {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|x64.Build.0 = Debug|Any CPU - {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|x86.ActiveCfg = Debug|Any CPU - {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF}.Checked|x86.Build.0 = Debug|Any CPU + {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|Any CPU.Build.0 = Debug|Any CPU + {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|x64.ActiveCfg = Debug|Any CPU + {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|x64.Build.0 = Debug|Any CPU + {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|x86.ActiveCfg = Debug|Any CPU + {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|x86.Build.0 = Debug|Any CPU {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Debug|Any CPU.Build.0 = Debug|Any CPU {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -312,12 +324,12 @@ Global {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Release|x64.Build.0 = Release|Any CPU {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Release|x86.ActiveCfg = Release|Any CPU {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Release|x86.Build.0 = Release|Any CPU - {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|Any CPU.Build.0 = Debug|Any CPU - {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|x64.ActiveCfg = Debug|Any CPU - {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|x64.Build.0 = Debug|Any CPU - {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|x86.ActiveCfg = Debug|Any CPU - {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}.Checked|x86.Build.0 = Debug|Any CPU + {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|Any CPU.Build.0 = Debug|Any CPU + {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|x64.ActiveCfg = Debug|Any CPU + {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|x64.Build.0 = Debug|Any CPU + {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|x86.ActiveCfg = Debug|Any CPU + {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|x86.Build.0 = Debug|Any CPU {535A9671-08A0-46DD-8191-DC9B995DF425}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {535A9671-08A0-46DD-8191-DC9B995DF425}.Debug|Any CPU.Build.0 = Debug|Any CPU {535A9671-08A0-46DD-8191-DC9B995DF425}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -330,12 +342,12 @@ Global {535A9671-08A0-46DD-8191-DC9B995DF425}.Release|x64.Build.0 = Release|Any CPU {535A9671-08A0-46DD-8191-DC9B995DF425}.Release|x86.ActiveCfg = Release|Any CPU {535A9671-08A0-46DD-8191-DC9B995DF425}.Release|x86.Build.0 = Release|Any CPU - {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|Any CPU.Build.0 = Debug|Any CPU - {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|x64.ActiveCfg = Debug|Any CPU - {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|x64.Build.0 = Debug|Any CPU - {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|x86.ActiveCfg = Debug|Any CPU - {535A9671-08A0-46DD-8191-DC9B995DF425}.Checked|x86.Build.0 = Debug|Any CPU + {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|Any CPU.Build.0 = Debug|Any CPU + {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|x64.ActiveCfg = Debug|Any CPU + {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|x64.Build.0 = Debug|Any CPU + {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|x86.ActiveCfg = Debug|Any CPU + {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|x86.Build.0 = Debug|Any CPU {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Debug|Any CPU.Build.0 = Debug|Any CPU {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -348,12 +360,12 @@ Global {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Release|x64.Build.0 = Release|Any CPU {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Release|x86.ActiveCfg = Release|Any CPU {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Release|x86.Build.0 = Release|Any CPU - {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|Any CPU.Build.0 = Debug|Any CPU - {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|x64.ActiveCfg = Debug|Any CPU - {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|x64.Build.0 = Debug|Any CPU - {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|x86.ActiveCfg = Debug|Any CPU - {8EAD8906-AF4E-42CA-983E-28CFE2224AEE}.Checked|x86.Build.0 = Debug|Any CPU + {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|Any CPU.Build.0 = Debug|Any CPU + {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|x64.ActiveCfg = Debug|Any CPU + {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|x64.Build.0 = Debug|Any CPU + {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|x86.ActiveCfg = Debug|Any CPU + {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|x86.Build.0 = Debug|Any CPU {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Debug|Any CPU.Build.0 = Debug|Any CPU {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -366,12 +378,12 @@ Global {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Release|x64.Build.0 = Release|Any CPU {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Release|x86.ActiveCfg = Release|Any CPU {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Release|x86.Build.0 = Release|Any CPU - {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|Any CPU.Build.0 = Debug|Any CPU - {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|x64.ActiveCfg = Debug|Any CPU - {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|x64.Build.0 = Debug|Any CPU - {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|x86.ActiveCfg = Debug|Any CPU - {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}.Checked|x86.Build.0 = Debug|Any CPU + {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|Any CPU.Build.0 = Debug|Any CPU + {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|x64.ActiveCfg = Debug|Any CPU + {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|x64.Build.0 = Debug|Any CPU + {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|x86.ActiveCfg = Debug|Any CPU + {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|x86.Build.0 = Debug|Any CPU {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Debug|Any CPU.Build.0 = Debug|Any CPU {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -384,12 +396,12 @@ Global {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Release|x64.Build.0 = Release|Any CPU {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Release|x86.ActiveCfg = Release|Any CPU {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Release|x86.Build.0 = Release|Any CPU - {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|Any CPU.Build.0 = Debug|Any CPU - {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|x64.ActiveCfg = Debug|Any CPU - {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|x64.Build.0 = Debug|Any CPU - {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|x86.ActiveCfg = Debug|Any CPU - {2F5DA438-6CBA-42AA-818A-64C633A56D55}.Checked|x86.Build.0 = Debug|Any CPU + {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|Any CPU.Build.0 = Debug|Any CPU + {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|x64.ActiveCfg = Debug|Any CPU + {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|x64.Build.0 = Debug|Any CPU + {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|x86.ActiveCfg = Debug|Any CPU + {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|x86.Build.0 = Debug|Any CPU {A17B970B-41B2-4C78-BA05-2B954357E46A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A17B970B-41B2-4C78-BA05-2B954357E46A}.Debug|Any CPU.Build.0 = Debug|Any CPU {A17B970B-41B2-4C78-BA05-2B954357E46A}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -402,12 +414,12 @@ Global {A17B970B-41B2-4C78-BA05-2B954357E46A}.Release|x64.Build.0 = Release|Any CPU {A17B970B-41B2-4C78-BA05-2B954357E46A}.Release|x86.ActiveCfg = Release|Any CPU {A17B970B-41B2-4C78-BA05-2B954357E46A}.Release|x86.Build.0 = Release|Any CPU - {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|Any CPU.Build.0 = Debug|Any CPU - {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|x64.ActiveCfg = Debug|Any CPU - {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|x64.Build.0 = Debug|Any CPU - {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|x86.ActiveCfg = Debug|Any CPU - {A17B970B-41B2-4C78-BA05-2B954357E46A}.Checked|x86.Build.0 = Debug|Any CPU + {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|Any CPU.Build.0 = Debug|Any CPU + {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|x64.ActiveCfg = Debug|Any CPU + {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|x64.Build.0 = Debug|Any CPU + {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|x86.ActiveCfg = Debug|Any CPU + {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|x86.Build.0 = Debug|Any CPU {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Debug|Any CPU.Build.0 = Debug|Any CPU {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -420,12 +432,12 @@ Global {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Release|x64.Build.0 = Release|Any CPU {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Release|x86.ActiveCfg = Release|Any CPU {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Release|x86.Build.0 = Release|Any CPU - {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|Any CPU.Build.0 = Debug|Any CPU - {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|x64.ActiveCfg = Debug|Any CPU - {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|x64.Build.0 = Debug|Any CPU - {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|x86.ActiveCfg = Debug|Any CPU - {3D4EEB00-D4E0-4581-A144-51EFF8319FFB}.Checked|x86.Build.0 = Debug|Any CPU + {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|Any CPU.Build.0 = Debug|Any CPU + {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|x64.ActiveCfg = Debug|Any CPU + {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|x64.Build.0 = Debug|Any CPU + {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|x86.ActiveCfg = Debug|Any CPU + {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|x86.Build.0 = Debug|Any CPU {637E7769-42D2-4541-9A63-32301113FA5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {637E7769-42D2-4541-9A63-32301113FA5A}.Debug|Any CPU.Build.0 = Debug|Any CPU {637E7769-42D2-4541-9A63-32301113FA5A}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -438,12 +450,12 @@ Global {637E7769-42D2-4541-9A63-32301113FA5A}.Release|x64.Build.0 = Release|Any CPU {637E7769-42D2-4541-9A63-32301113FA5A}.Release|x86.ActiveCfg = Release|Any CPU {637E7769-42D2-4541-9A63-32301113FA5A}.Release|x86.Build.0 = Release|Any CPU - {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|Any CPU.Build.0 = Debug|Any CPU - {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|x64.ActiveCfg = Debug|Any CPU - {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|x64.Build.0 = Debug|Any CPU - {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|x86.ActiveCfg = Debug|Any CPU - {637E7769-42D2-4541-9A63-32301113FA5A}.Checked|x86.Build.0 = Debug|Any CPU + {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|Any CPU.Build.0 = Debug|Any CPU + {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|x64.ActiveCfg = Debug|Any CPU + {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|x64.Build.0 = Debug|Any CPU + {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|x86.ActiveCfg = Debug|Any CPU + {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|x86.Build.0 = Debug|Any CPU {7D404296-72F5-4F99-931F-73791FAB3E14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7D404296-72F5-4F99-931F-73791FAB3E14}.Debug|Any CPU.Build.0 = Debug|Any CPU {7D404296-72F5-4F99-931F-73791FAB3E14}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -456,12 +468,12 @@ Global {7D404296-72F5-4F99-931F-73791FAB3E14}.Release|x64.Build.0 = Release|Any CPU {7D404296-72F5-4F99-931F-73791FAB3E14}.Release|x86.ActiveCfg = Release|Any CPU {7D404296-72F5-4F99-931F-73791FAB3E14}.Release|x86.Build.0 = Release|Any CPU - {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|Any CPU.Build.0 = Debug|Any CPU - {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|x64.ActiveCfg = Debug|Any CPU - {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|x64.Build.0 = Debug|Any CPU - {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|x86.ActiveCfg = Debug|Any CPU - {7D404296-72F5-4F99-931F-73791FAB3E14}.Checked|x86.Build.0 = Debug|Any CPU + {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|Any CPU.Build.0 = Debug|Any CPU + {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|x64.ActiveCfg = Debug|Any CPU + {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|x64.Build.0 = Debug|Any CPU + {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|x86.ActiveCfg = Debug|Any CPU + {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|x86.Build.0 = Debug|Any CPU {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Debug|Any CPU.Build.0 = Debug|Any CPU {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -474,42 +486,58 @@ Global {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Release|x64.Build.0 = Release|Any CPU {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Release|x86.ActiveCfg = Release|Any CPU {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Release|x86.Build.0 = Release|Any CPU - {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|Any CPU.Build.0 = Debug|Any CPU - {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|x64.ActiveCfg = Debug|Any CPU - {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|x64.Build.0 = Debug|Any CPU - {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|x86.ActiveCfg = Debug|Any CPU - {7C0A6923-A9BC-4F10-81E0-C535EEF537BB}.Checked|x86.Build.0 = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Checked|Any CPU.Build.0 = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Checked|x64.ActiveCfg = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Checked|x64.Build.0 = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Checked|x86.ActiveCfg = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Checked|x86.Build.0 = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Debug|x64.ActiveCfg = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Debug|x64.Build.0 = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Debug|x86.ActiveCfg = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Debug|x86.Build.0 = Debug|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Release|Any CPU.Build.0 = Release|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Release|x64.ActiveCfg = Release|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Release|x64.Build.0 = Release|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Release|x86.ActiveCfg = Release|Any CPU + {422C9340-E720-4554-B6AC-560A19FE16B1}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {89B01AF7-F0CE-4168-8C4A-33FCDCF33B73} = {315BC231-270B-456C-919A-3E9BB50CDD7A} - {89C01491-2BE8-438C-8F1D-24DE9AFD7A86} = {315BC231-270B-456C-919A-3E9BB50CDD7A} - {64F83961-AECA-4D5C-B467-A1A94AE6FFB4} = {315BC231-270B-456C-919A-3E9BB50CDD7A} - {95F843FE-38B4-4ED5-81FF-605DE38155F6} = {315BC231-270B-456C-919A-3E9BB50CDD7A} - {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4} = {315BC231-270B-456C-919A-3E9BB50CDD7A} - {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF} = {315BC231-270B-456C-919A-3E9BB50CDD7A} - {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C} = {315BC231-270B-456C-919A-3E9BB50CDD7A} - {637E7769-42D2-4541-9A63-32301113FA5A} = {315BC231-270B-456C-919A-3E9BB50CDD7A} - {7C0A6923-A9BC-4F10-81E0-C535EEF537BB} = {315BC231-270B-456C-919A-3E9BB50CDD7A} {F6BCA6EF-777E-408B-B49B-B055B5A0BA19} = {6BA02609-AE23-4E80-8B4B-9C6548AA147A} - {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0} = {6BA02609-AE23-4E80-8B4B-9C6548AA147A} {A26E9B9C-AFE7-4740-AC73-626D9823E515} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} + {89C01491-2BE8-438C-8F1D-24DE9AFD7A86} = {315BC231-270B-456C-919A-3E9BB50CDD7A} {51AEBD0E-0A93-4532-A010-CAAF8E320D6C} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} + {64F83961-AECA-4D5C-B467-A1A94AE6FFB4} = {315BC231-270B-456C-919A-3E9BB50CDD7A} {279066F9-4DB9-4897-8CE4-66BC31118323} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} + {95F843FE-38B4-4ED5-81FF-605DE38155F6} = {315BC231-270B-456C-919A-3E9BB50CDD7A} {ED544AD5-41C5-4445-BC0F-EFA1553C881A} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} + {97D756D3-8ECA-45F5-A9F5-DBF659D87BC4} = {315BC231-270B-456C-919A-3E9BB50CDD7A} {83696A63-CF89-4DE4-8F79-96F5B830A4B6} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} {2F00396E-003A-4385-92DC-69FDBEF330D8} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} + {48CC1460-B1E7-4DE9-A4E7-2206F7FD54CF} = {315BC231-270B-456C-919A-3E9BB50CDD7A} + {0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0} = {6BA02609-AE23-4E80-8B4B-9C6548AA147A} {535A9671-08A0-46DD-8191-DC9B995DF425} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} - {3D4EEB00-D4E0-4581-A144-51EFF8319FFB} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} - {7D404296-72F5-4F99-931F-73791FAB3E14} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} {8EAD8906-AF4E-42CA-983E-28CFE2224AEE} = {BDABB39C-A9FF-4A9B-8BA2-EF873C5EEB16} + {4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C} = {315BC231-270B-456C-919A-3E9BB50CDD7A} {2F5DA438-6CBA-42AA-818A-64C633A56D55} = {BDABB39C-A9FF-4A9B-8BA2-EF873C5EEB16} {A17B970B-41B2-4C78-BA05-2B954357E46A} = {BDABB39C-A9FF-4A9B-8BA2-EF873C5EEB16} + {3D4EEB00-D4E0-4581-A144-51EFF8319FFB} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} + {637E7769-42D2-4541-9A63-32301113FA5A} = {315BC231-270B-456C-919A-3E9BB50CDD7A} + {7D404296-72F5-4F99-931F-73791FAB3E14} = {1826CD8D-A5E3-4C8E-A49A-E746D9682B87} + {7C0A6923-A9BC-4F10-81E0-C535EEF537BB} = {315BC231-270B-456C-919A-3E9BB50CDD7A} + {422C9340-E720-4554-B6AC-560A19FE16B1} = {6BA02609-AE23-4E80-8B4B-9C6548AA147A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {52B54BB6-271E-45BD-A7A4-D4CEDC973704} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\System.Private.CoreLib\src\System.Private.CoreLib.Shared.projitems*{89b01af7-f0ce-4168-8c4a-33fcdcf33b73}*SharedItemsImports = 5 + EndGlobalSection EndGlobal diff --git a/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs b/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs index a8f71b5dbe2223..ac1f42b6b5f3c1 100644 --- a/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs +++ b/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs @@ -14,6 +14,17 @@ public partial class BooleanSwitch : System.Diagnostics.Switch public bool Enabled { get { throw null; } set { } } protected override void OnValueChanged() { } } + public sealed partial class ConfigureSwitchEventArgs : System.EventArgs + { + public ConfigureSwitchEventArgs(System.Diagnostics.Switch @switch) { } + public System.Diagnostics.Switch Switch { get { throw null; } } + } + public sealed partial class ConfigureTraceSourceEventArgs : System.EventArgs + { + public ConfigureTraceSourceEventArgs(System.Diagnostics.TraceSource traceSource) { } + public System.Diagnostics.TraceSource TraceSource { get { throw null; } } + public bool WasConfigured { get { throw null; } set { } } + } public partial class CorrelationManager { internal CorrelationManager() { } @@ -122,10 +133,11 @@ public static void Fail(string? message, string? detailMessage) { } public static void Flush() { } [System.Diagnostics.ConditionalAttribute("TRACE")] public static void Indent() { } - public static event Action? ConfigureTrace { add { } remove { } } - public static event Action? ConfigureTraceSource { add { } remove { } } - public static event Action? ConfigureSwitch { add { } remove { } } + public static event EventHandler? ConfigureTrace { add { } remove { } } + public static event EventHandler? ConfigureTraceSource { add { } remove { } } + public static event EventHandler? ConfigureSwitch { add { } remove { } } public static void Refresh() { } + public static event EventHandler? RefreshConfiguration { add { } remove { } } [System.Diagnostics.ConditionalAttribute("TRACE")] public static void TraceError(string? message) { } [System.Diagnostics.ConditionalAttribute("TRACE")] diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj b/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj index 6d81fba9c23025..23ae1a61c77f4c 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj @@ -1,10 +1,12 @@ - + $(DefineConstants);TRACE $(NetCoreAppCurrent) + + diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureSwitchEventArgs.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureSwitchEventArgs.cs new file mode 100644 index 00000000000000..168f2c16ad12ff --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureSwitchEventArgs.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics +{ + /// + /// Provides data for the event. + /// + public sealed class ConfigureSwitchEventArgs : EventArgs + { + public ConfigureSwitchEventArgs(Switch @switch) + { + Switch = @switch; + } + + public Switch Switch { get; } + } +} diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureTraceSourceEventArgs.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureTraceSourceEventArgs.cs new file mode 100644 index 00000000000000..e35e1b0cce97da --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureTraceSourceEventArgs.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics +{ + /// + /// Provides data for the event. + /// + public sealed class ConfigureTraceSourceEventArgs : EventArgs + { + public ConfigureTraceSourceEventArgs(TraceSource traceSource) + { + TraceSource = traceSource; + } + + public TraceSource TraceSource { get; } + public bool WasConfigured { get; set; } + } +} diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs index 081f99606865ea..dd35b104f73034 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs @@ -262,6 +262,9 @@ internal static void RefreshAll() } } + /// + /// Refreshes the trace configuration data. + /// public void Refresh() { lock (InitializedLock) diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs index 705cde0d6e52d5..6e7476562c1073 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs @@ -159,29 +159,33 @@ public static void Fail(string? message, string? detailMessage) TraceInternal.Fail(message, detailMessage); } - public static event Action? ConfigureTrace; - + public static event EventHandler? ConfigureTrace; internal static void OnConfigureTrace() { - Trace.ConfigureTrace?.Invoke(); + ConfigureTrace?.Invoke(null, EventArgs.Empty); } - public static event Action? ConfigureTraceSource; - - internal static void OnConfigureTraceSource(TraceSource traceSource) + public static event EventHandler? RefreshConfiguration; + internal static void OnRefreshConfiguration() { - Trace.ConfigureTraceSource?.Invoke(traceSource); + RefreshConfiguration?.Invoke(null, EventArgs.Empty); } - public static event Action? ConfigureSwitch; + public static event EventHandler? ConfigureTraceSource; + internal static void OnConfigureTraceSource(ConfigureTraceSourceEventArgs e) + { + ConfigureTraceSource?.Invoke(null, e); + } + public static event EventHandler? ConfigureSwitch; internal static void OnConfigureSwitch(Switch @switch) { - Trace.ConfigureSwitch?.Invoke(@switch); + ConfigureSwitch?.Invoke(null, new ConfigureSwitchEventArgs(@switch)); } public static void Refresh() { + OnRefreshConfiguration(); Switch.RefreshAll(); TraceSource.RefreshAll(); TraceInternal.Refresh(); diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListeners.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListeners.cs index 514d7df1317bb9..c8733ab9a4830e 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListeners.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListeners.cs @@ -89,7 +89,7 @@ public void AddRange(TraceListener[] value) for (int i = 0; ((i) < (value.Length)); i = ((i) + (1))) { - this.Add(value[i]); + Add(value[i]); } } @@ -103,7 +103,7 @@ public void AddRange(TraceListenerCollection value) int currentCount = value.Count; for (int i = 0; i < currentCount; i = ((i) + (1))) { - this.Add(value[i]); + Add(value[i]); } } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs index fc4dca99fdb096..744225a3ef0e63 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs @@ -20,12 +20,10 @@ public class TraceSource private readonly SourceLevels _switchLevel; private readonly string _sourceName; internal volatile bool _initCalled; // Whether we've called Initialize already. + internal volatile bool _configInitializing; private StringDictionary? _attributes; - public TraceSource(string name) - : this(name, SourceLevels.Off) - { - } + public TraceSource(string name) : this(name, SourceLevels.Off) { } public TraceSource(string name, SourceLevels defaultLevel) { @@ -76,20 +74,37 @@ private void Initialize() if (_initCalled) return; - NoConfigInit(); + if (_configInitializing) + return; + + _configInitializing = true; + + NoConfigInit_BeforeEvent(); + + ConfigureTraceSourceEventArgs e = new ConfigureTraceSourceEventArgs(this); + Trace.OnConfigureTraceSource(e); - Trace.OnConfigureTraceSource(this); + if (!e.WasConfigured) + { + NoConfigInit_AfterEvent(); + } + _configInitializing = false; _initCalled = true; } } - } - private void NoConfigInit() - { - _internalSwitch = new SourceSwitch(_sourceName, _switchLevel.ToString()); - _listeners = new TraceListenerCollection(); - _listeners.Add(new DefaultTraceListener()); + void NoConfigInit_BeforeEvent() + { + _listeners = new TraceListenerCollection(); + _internalSwitch = new SourceSwitch(_sourceName, _switchLevel.ToString()); + } + + void NoConfigInit_AfterEvent() + { + Debug.Assert(_listeners != null); + _listeners.Add(new DefaultTraceListener()); + } } public void Close() @@ -167,6 +182,8 @@ internal void Refresh() Initialize(); return; } + + Trace.OnConfigureTraceSource(new ConfigureTraceSourceEventArgs(this)); } [Conditional("TRACE")] @@ -469,9 +486,7 @@ public StringDictionary Attributes { get { - // Ensure that config is loaded Initialize(); - return _attributes ??= new StringDictionary(); } @@ -484,20 +499,13 @@ public StringDictionary Attributes public SourceLevels DefaultLevel => _switchLevel; - public string Name - { - get - { - return _sourceName; - } - } + public string Name => _sourceName; public TraceListenerCollection Listeners { get { Initialize(); - return _listeners!; } } @@ -508,7 +516,6 @@ public SourceSwitch Switch get { Initialize(); - return _internalSwitch!; } set diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSwitch.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSwitch.cs index a9f6bc742c151f..45400a06f821d4 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSwitch.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSwitch.cs @@ -17,8 +17,7 @@ public class TraceSwitch : Switch /// public TraceSwitch(string displayName, string? description) : base(displayName, description) - { - } + { } public TraceSwitch(string displayName, string? description, string defaultSwitchValue) : base(displayName, description, defaultSwitchValue) @@ -49,52 +48,28 @@ public TraceLevel Level /// , , , or /// . /// - public bool TraceError - { - get - { - return (Level >= TraceLevel.Error); - } - } + public bool TraceError => Level >= TraceLevel.Error; /// /// Gets a value /// indicating whether the is set to /// , , or . /// - public bool TraceWarning - { - get - { - return (Level >= TraceLevel.Warning); - } - } + public bool TraceWarning => Level >= TraceLevel.Warning; /// /// Gets a value /// indicating whether the is set to /// or . /// - public bool TraceInfo - { - get - { - return (Level >= TraceLevel.Info); - } - } + public bool TraceInfo => Level >= TraceLevel.Info; /// /// Gets a value /// indicating whether the is set to /// . /// - public bool TraceVerbose - { - get - { - return (Level == TraceLevel.Verbose); - } - } + public bool TraceVerbose => Level == TraceLevel.Verbose; /// /// diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/AssemblyInfo.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/AssemblyInfo.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/AssemblyInfo.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/AssemblyInfo.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs new file mode 100644 index 00000000000000..94d3e06e45a5ad --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace System.Diagnostics.TraceSourceConfigTests +{ + public class StringTraceListener : DefaultTraceListener + { + private StringWriter _writer; + public bool ShouldOverrideWriteLine { get; set; } = true; + + public StringTraceListener() + { + _writer = new StringWriter(); + AssertUiEnabled = false; + } + + public void Clear() + { + _writer = new StringWriter(); + } + + public string Output + { + get { return _writer.ToString(); } + } + + public override void Write(string message) + { + _writer.Write(message); + } + + public override void WriteLine(string message) + { + if (ShouldOverrideWriteLine) + { + _writer.WriteLine(message); + } + else + { + base.WriteLine(message); + } + } + } +} diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj new file mode 100644 index 00000000000000..6f35d2ffe79951 --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj @@ -0,0 +1,28 @@ + + + true + $(NetCoreAppCurrent) + + + + + + + + + Always + + + Always + + + Always + + + Always + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs new file mode 100644 index 00000000000000..46149cf3eb8fce --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs @@ -0,0 +1,233 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Configuration; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace System.Diagnostics.TraceSourceConfigTests +{ + public class ConfigurationTests + { + private const string ConfigFile = "testhost.dll.config"; + + private static void CreateAndLoadConfigFile(string filename) + { + Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + Assert.Equal(ConfigFile, Path.GetFileName(config.FilePath)); + string dir = Path.GetDirectoryName(config.FilePath); + string from = Path.Combine(dir, filename); + File.Copy(from, ConfigFile, overwrite: true); + TraceConfiguration.Register(); + Trace.Refresh(); + } + + [Fact] + public void ConfigWithRuntimeFilterChange() + { + CreateAndLoadConfigFile("testhost_ConfigWithRuntime.dll.config"); + + TraceSource mySource = new TraceSource("TraceSourceApp"); + StringTraceListener origListener = (StringTraceListener)mySource.Listeners["origListener"]; + StringTraceListener secondListener = (StringTraceListener)mySource.Listeners["secondListener"]; + + // Issue an error and a warning message. Only the error message should be logged. + mySource.TraceEvent(TraceEventType.Error, 1, "Error message."); + mySource.TraceEvent(TraceEventType.Warning, 2, "Warning message."); + + Assert.Equal("TraceSourceApp Error: 1 : Error message.\r\n", origListener.Output); + Assert.Equal("TraceSourceApp Error: 1 : Error message.\r\n", secondListener.Output); + + // Save the original settings from the configuration file. + EventTypeFilter configFilter = (EventTypeFilter)mySource.Listeners["origListener"].Filter; + Assert.NotNull(configFilter); + + // Create a new filter that logs warnings. + origListener.Filter = new EventTypeFilter(SourceLevels.Warning); + + // Allow the trace source to send messages to listeners for all event types. + // This overrides settings in the configuration file. + // If the switch level is not changed, the event filter changes have no effect. + mySource.Switch.Level = SourceLevels.All; + + // Issue a critical and warning message. + origListener.Clear(); + secondListener.Clear(); + mySource.TraceEvent(TraceEventType.Critical, 3, "Critical message."); + mySource.TraceEvent(TraceEventType.Warning, 4, "Warning message."); + + // Both should be logged for origListener. + Assert.Equal( + "TraceSourceApp Critical: 3 : Critical message.\r\n" + + "TraceSourceApp Warning: 4 : Warning message.\r\n", origListener.Output); + + // secondListener is unchanged and doesn't log warnings. + Assert.Equal("TraceSourceApp Critical: 3 : Critical message.\r\n", secondListener.Output); + + // Restore the original filter settings. + origListener.Clear(); + secondListener.Clear(); + origListener.Filter = configFilter; + + // Issue an error and information message. Only the error message should be logged. + mySource.TraceEvent(TraceEventType.Error, 5, "Error message."); + mySource.TraceInformation("Informational message."); + + Assert.Equal("TraceSourceApp Error: 5 : Error message.\r\n", origListener.Output); + Assert.Equal("TraceSourceApp Error: 5 : Error message.\r\n", secondListener.Output); + + origListener.Clear(); + secondListener.Clear(); + mySource.Close(); + } + + [Fact] + public void RefreshSwitchFromConfigFile() + { + // Use a SourceSwitch that logs Error. + CreateAndLoadConfigFile("testhost_RefreshSwitch_before.dll.config"); + + TraceSource mySource = new TraceSource("TraceSourceApp"); + StringTraceListener listener = (StringTraceListener)mySource.Listeners["origListener"]; + Log(); + Assert.Equal( + "TraceSourceApp Error: 1 : Error message.\r\n" + + "TraceSourceApp Critical: 3 : Critical message.\r\n", listener.Output); + + // Change the switch to log All. + listener.Clear(); + CreateAndLoadConfigFile("testhost_RefreshSwitch_after.dll.config"); + Trace.Refresh(); + Log(); + Assert.Equal( + "TraceSourceApp Error: 1 : Error message.\r\n" + + "TraceSourceApp Warning: 2 : Warning message.\r\n" + + "TraceSourceApp Critical: 3 : Critical message.\r\n" + + "TraceSourceApp Information: 0 : Informational message.\r\n", listener.Output); + + listener.Clear(); + mySource.Close(); + + void Log() + { + mySource.TraceEvent(TraceEventType.Error, 1, "Error message."); + mySource.TraceEvent(TraceEventType.Warning, 2, "Warning message."); + mySource.TraceEvent(TraceEventType.Critical, 3, "Critical message."); + mySource.TraceInformation("Informational message."); + } + } + + [Fact] + public void ConfigWithEvents_RuntimeListener() + { + CreateAndLoadConfigFile("testhost_ConfigWithRuntime.dll.config"); + + Trace.ConfigureTraceSource += SubscribeToConfigTracesource_ConfigureTraceSource; + Trace.ConfigureSwitch += SubscribeToConfigTracesource_ConfigureSwitch; + + TraceSource mySource = new("TraceSource_NoListeners"); + Assert.Equal(1, mySource.Listeners.Count); // The default listener was removed via the config + StringTraceListener dynamicallyAddedListener = (StringTraceListener)mySource.Listeners[0]; + + // Only the Critical should be logged. + // The config setting was to only log Error, but changed to Critical in the event handler. + Log(); + Assert.Equal("TraceSource_NoListeners Critical: 3 : Critical message.\r\n", dynamicallyAddedListener.Output); + + // Log all. + dynamicallyAddedListener.Clear(); + mySource.Switch.Level = SourceLevels.All; + Log(); + Assert.Equal( + "TraceSource_NoListeners Error: 1 : Error message.\r\n" + + "TraceSource_NoListeners Warning: 2 : Warning message.\r\n" + + "TraceSource_NoListeners Critical: 3 : Critical message.\r\n" + + "TraceSource_NoListeners Information: 0 : Informational message.\r\n", dynamicallyAddedListener.Output); + + dynamicallyAddedListener.Clear(); + mySource.Close(); + Trace.ConfigureTraceSource -= SubscribeToConfigTracesource_ConfigureTraceSource; + Trace.ConfigureSwitch -= SubscribeToConfigTracesource_ConfigureSwitch; + + void Log() + { + mySource.TraceEvent(TraceEventType.Error, 1, "Error message."); + mySource.TraceEvent(TraceEventType.Warning, 2, "Warning message."); + mySource.TraceEvent(TraceEventType.Critical, 3, "Critical message."); + mySource.TraceInformation("Informational message."); + } + } + + private void SubscribeToConfigTracesource_ConfigureTraceSource(object? sender, ConfigureTraceSourceEventArgs e) + { + TraceSource traceSource = e.TraceSource; + if (traceSource.Name == "TraceSource_NoListeners") + { + Assert.Equal("generalSourceSwitch_Error", traceSource.Switch.DisplayName); + traceSource.Listeners.Add(new StringTraceListener()); + } + } + + private void SubscribeToConfigTracesource_ConfigureSwitch(object? sender, ConfigureSwitchEventArgs e) + { + Switch sw = e.Switch; + if (sw.DisplayName == "generalSourceSwitch_Error") + { + Assert.IsType(sw); + SourceSwitch sourceSwitch = (SourceSwitch)sw; + Assert.Equal(TraceLevel.Error.ToString(), sourceSwitch.Level.ToString()); + + // Change to critical + sourceSwitch.Level = SourceLevels.Critical; + } + } + + [Fact] + public void AllTypes() + { + CreateAndLoadConfigFile("testhost_AllTypes.dll.config"); + + TraceSource mySource; + + mySource = new("ConsoleTraceListener"); + Assert.Equal("L1", mySource.Listeners[1].Name); + + mySource = new("DefaultTraceListener"); + Assert.Equal("L1", mySource.Listeners[1].Name); + + mySource = new("DelimitedListTraceListener"); + Assert.Equal("L1", mySource.Listeners[1].Name); + + // Only supported on .NET Framework. + mySource = new("EventLogTraceListener"); + Exception e = Assert.Throws(() => mySource.Listeners[1].Name); + Assert.IsType(e.InnerException); + + mySource = new("TextWriterTraceListener"); + Assert.Equal("L1", mySource.Listeners[1].Name); + + mySource = new("XmlWriterTraceListener"); + Assert.Equal("L1", mySource.Listeners[1].Name); + + Switch switch_booleanSwitch = new BooleanSwitch("booleanSwitch", null); + Assert.Equal("True", switch_booleanSwitch.Value); + + Switch switch_sourceSwitch = new SourceSwitch("sourceSwitch"); + Assert.Equal("Critical", switch_sourceSwitch.Value); + + Switch switch_traceSwitch = new TraceSwitch("traceSwitch", null); + Assert.Equal("Info", switch_traceSwitch.Value); + + TraceSource filter_sourceFilter = new("filter_sourceFilter"); + Assert.IsType(filter_sourceFilter.Listeners[1].Filter); + + TraceSource filter_eventTypeFilter = new("filter_eventTypeFilter"); + Assert.IsType(filter_eventTypeFilter.Listeners[1].Filter); + } + } +} diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_AllTypes.dll.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_AllTypes.dll.config new file mode 100644 index 00000000000000..fd91b2af8eafed --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_AllTypes.dll.config @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ConfigWithRuntime.dll.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ConfigWithRuntime.dll.config new file mode 100644 index 00000000000000..32b7fe3fd2920a --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ConfigWithRuntime.dll.config @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_after.dll.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_after.dll.config new file mode 100644 index 00000000000000..6bcc590cc75783 --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_after.dll.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_before.dll.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_before.dll.config new file mode 100644 index 00000000000000..2a077281398615 --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_before.dll.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_refresh.dll.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_refresh.dll.config new file mode 100644 index 00000000000000..366da09c5fea6f --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_refresh.dll.config @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/AssemblyInfo.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/AssemblyInfo.cs new file mode 100644 index 00000000000000..a1de79002e07d5 --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly, DisableTestParallelization = true, MaxParallelThreads = 1)] diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/BooleanSwitchClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/BooleanSwitchClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/BooleanSwitchClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/BooleanSwitchClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/CorrelationManagerTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/CorrelationManagerTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/CorrelationManagerTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/CorrelationManagerTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/DefaultTraceListenerClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/DefaultTraceListenerClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/EventTypeFilterClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/EventTypeFilterClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/EventTypeFilterClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/EventTypeFilterClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/SourceFilterClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/SourceFilterClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/SourceFilterClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/SourceFilterClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/SwitchClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/SwitchClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/SwitchClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/SwitchClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests.csproj b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj similarity index 76% rename from src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests.csproj rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj index 7c0de93514b041..c0e6c51b02bbb9 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj @@ -3,6 +3,10 @@ true $(NetCoreAppCurrent) + + + @@ -24,4 +28,7 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TestTextTraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TestTextTraceListener.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TestTextTraceListener.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TestTextTraceListener.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TestTraceFilter.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TestTraceFilter.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TestTraceFilter.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TestTraceFilter.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TestTraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TestTraceListener.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TestTraceListener.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TestTraceListener.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TraceClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceEventCacheClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceEventCacheClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TraceEventCacheClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceEventCacheClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceFilterClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceFilterClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TraceFilterClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceFilterClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceInternalClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceInternalClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TraceInternalClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceInternalClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceListenerClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceListenerClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TraceListenerClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceListenerClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceListenerCollectionClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceListenerCollectionClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TraceListenerCollectionClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceListenerCollectionClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceSourceClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceSourceClassTests.cs similarity index 99% rename from src/libraries/System.Diagnostics.TraceSource/tests/TraceSourceClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceSourceClassTests.cs index ac9f2f958bb22b..c4f5fb390c49c6 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/TraceSourceClassTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceSourceClassTests.cs @@ -11,7 +11,7 @@ namespace System.Diagnostics.TraceSourceTests public sealed class TraceSourceClassTests { [Fact] - public void ConstrutorExceptionTest() + public void ConstructorExceptionTest() { Assert.Throws(() => new TraceSource(null)); AssertExtensions.Throws("name", null, () => new TraceSource("")); @@ -23,6 +23,7 @@ public void DefaultListenerTest() var trace = new TraceSource("TestTraceSource"); Assert.Equal(1, trace.Listeners.Count); Assert.IsType(trace.Listeners[0]); + Assert.Equal(SourceLevels.Off, trace.Switch.Level); } [Fact] diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceSwitchClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceSwitchClassTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TraceSwitchClassTests.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceSwitchClassTests.cs diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/TraceTestHelper.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceTestHelper.cs similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/TraceTestHelper.cs rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/TraceTestHelper.cs From ba57e1f92b1eddb5c876d1eaaeb58ad196489d7e Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Fri, 29 Jul 2022 17:37:29 -0500 Subject: [PATCH 4/9] Tests and naming --- .../src/Resources/Strings.resx | 79 +++++++-- .../Diagnostics/ListenerElementsCollection.cs | 10 +- .../Diagnostics/SourceElementsCollection.cs | 10 +- .../Diagnostics/SwitchElementsCollection.cs | 4 +- .../Diagnostics/SystemDiagnosticsSection.cs | 8 +- .../System/Diagnostics/TraceConfiguration.cs | 52 +++--- .../src/System/Diagnostics/TraceSection.cs | 8 +- .../src/System/Diagnostics/TraceUtils.cs | 12 ++ .../src/System/Diagnostics/TypedElement.cs | 4 +- ...guration.ConfigurationManager.Tests.csproj | 7 +- .../ref/System.Diagnostics.TraceSource.cs | 37 ++-- .../src/System.Diagnostics.TraceSource.csproj | 4 +- .../Diagnostics/DefaultTraceListener.cs | 2 - ...Args.cs => InitializingSwitchEventArgs.cs} | 6 +- ...cs => InitializingTraceSourceEventArgs.cs} | 8 +- .../src/System/Diagnostics/Switch.cs | 22 ++- .../src/System/Diagnostics/Trace.cs | 29 +-- .../src/System/Diagnostics/TraceInternal.cs | 7 +- .../src/System/Diagnostics/TraceListener.cs | 6 - .../src/System/Diagnostics/TraceSource.cs | 31 +++- .../src/System/Diagnostics/TraceUtils.cs | 3 + ...iagnostics.TraceSource.Config.Tests.csproj | 26 ++- .../TraceSourceWithConfigurationTests.cs | 165 +++++++++++++----- ...es.dll.config => testhost_AllTypes.config} | 0 ...fig => testhost_ChangeSwitch_after.config} | 4 +- ...ig => testhost_ChangeSwitch_before.config} | 6 +- ...nfig => testhost_ConfigWithRuntime.config} | 0 .../testhost_RemoveSource_after.config | 9 + .../testhost_RemoveSource_before.config | 16 ++ .../testhost_RemoveSwitch_after.config | 11 ++ .../testhost_RemoveSwitch_before.config | 16 ++ ...testhost_Switch_MissingValue_Throws.config | 7 + ...ystem.Diagnostics.TraceSource.Tests.csproj | 4 - 33 files changed, 420 insertions(+), 193 deletions(-) rename src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/{ConfigureSwitchEventArgs.cs => InitializingSwitchEventArgs.cs} (61%) rename src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/{ConfigureTraceSourceEventArgs.cs => InitializingTraceSourceEventArgs.cs} (54%) rename src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/{testhost_AllTypes.dll.config => testhost_AllTypes.config} (100%) rename src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/{testhost_RefreshSwitch_after.dll.config => testhost_ChangeSwitch_after.config} (63%) rename src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/{testhost_RefreshSwitch_before.dll.config => testhost_ChangeSwitch_before.config} (54%) rename src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/{testhost_ConfigWithRuntime.dll.config => testhost_ConfigWithRuntime.config} (100%) create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSource_after.config create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSource_before.config create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSwitch_after.config create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSwitch_before.config create mode 100644 src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_Switch_MissingValue_Throws.config diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx b/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx index ebb19d0a9a4794..c7a69f6327f5f5 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx +++ b/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx @@ -1,4 +1,64 @@ - + + + @@ -75,10 +135,6 @@ {0}: {1} - An error occurred loading a configuration file @@ -91,9 +147,6 @@ Invalid format for a section or section group name - Cannot add a ConfigurationSection that already belongs to the Configuration. @@ -664,18 +717,17 @@ The file name '{0}' was already in the collection. - - Couldn't create listener '{0}'. + Could not create listener '{0}'. Could not create {0}. - Couldn't find type for class {0}. + Could not find type for class {0}. - Couldn't find constructor for class {0}. + Could not find constructor for class {0}. switchType needs to be a valid class name. It can't be empty. @@ -695,7 +747,4 @@ initializeData needs to be valid for this TraceListener. - - Couldn't find method {0} on class {1}. - \ No newline at end of file diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs index fc792347400daa..d82fe1be599270 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs @@ -78,9 +78,9 @@ internal sealed class SharedListenerElementsCollection : ListenerElementsCollect internal sealed class ListenerElement : TypedElement { - private static readonly ConfigurationProperty s_propFilter = new ConfigurationProperty("filter", typeof(FilterElement), null, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propName = new ConfigurationProperty("name", typeof(string), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); - private static readonly ConfigurationProperty s_propOutputOpts = new ConfigurationProperty("traceOutputOptions", typeof(TraceOptions), TraceOptions.None, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propFilter = new("filter", typeof(FilterElement), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propName = new("name", typeof(string), null, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); + private static readonly ConfigurationProperty s_propOutputOpts = new("traceOutputOptions", typeof(TraceOptions), TraceOptions.None, ConfigurationPropertyOptions.None); private ConfigurationProperty _propListenerTypeName; private bool _allowReferences; @@ -208,7 +208,7 @@ public TraceListener GetRuntimeObject() TraceListener newListener = (TraceListener)BaseGetRuntimeObject(); s_initData.AddOrUpdate(newListener, InitData); newListener.Name = Name; - newListener.Attributes = Attributes; + TraceUtils.CopyStringDictionary(Attributes, newListener.Attributes); newListener.TraceOutputOptions = TraceOutputOptions; if (Filter != null && !string.IsNullOrEmpty(Filter.TypeName)) @@ -339,7 +339,7 @@ internal TraceListener RefreshRuntimeObject(TraceListener listener) } else { - listener.Attributes = Attributes; + TraceUtils.CopyStringDictionary(Attributes, listener.Attributes); listener.TraceOutputOptions = TraceOutputOptions; if (listener.Filter != null) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs index 757787acbe3cd9..9ee667b72234d2 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs @@ -33,11 +33,11 @@ protected override ConfigurationElement CreateNewElement() internal sealed class SourceElement : ConfigurationElement { private static readonly ConfigurationPropertyCollection _properties = new(); - private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired); - private static readonly ConfigurationProperty _propSwitchName = new ConfigurationProperty("switchName", typeof(string), null, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propSwitchValue = new ConfigurationProperty("switchValue", typeof(string), null, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propSwitchType = new ConfigurationProperty("switchType", typeof(string), null, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), new ListenerElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propName = new("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired); + private static readonly ConfigurationProperty _propSwitchName = new("switchName", typeof(string), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propSwitchValue = new("switchValue", typeof(string), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propSwitchType = new("switchType", typeof(string), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty _propListeners = new("listeners", typeof(ListenerElementsCollection), new ListenerElementsCollection(), ConfigurationPropertyOptions.None); private StringDictionary _attributes; diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs index 6294b664c7f0bf..507ab073278955 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs @@ -20,8 +20,8 @@ internal sealed class SwitchElementsCollection : ConfigurationElementCollection internal sealed class SwitchElement : ConfigurationElement { private static readonly ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection(); - private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); - private static readonly ConfigurationProperty _propValue = new ConfigurationProperty("value", typeof(string), null, ConfigurationPropertyOptions.IsRequired); + private static readonly ConfigurationProperty _propName = new("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey); + private static readonly ConfigurationProperty _propValue = new("value", typeof(string), null, ConfigurationPropertyOptions.IsRequired); private StringDictionary _attributes; diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs index 3a14ffabdf07bc..e4b5af069fe35b 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs @@ -8,10 +8,10 @@ namespace System.Diagnostics internal sealed class SystemDiagnosticsSection : ConfigurationSection { private static readonly ConfigurationPropertyCollection s_properties = new(); - private static readonly ConfigurationProperty s_propSources = new ConfigurationProperty("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propSharedListeners = new ConfigurationProperty("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propSwitches = new ConfigurationProperty("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propTrace = new ConfigurationProperty("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSources = new("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSharedListeners = new("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSwitches = new("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propTrace = new("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); static SystemDiagnosticsSection() { diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs index 516cbaccfad902..d02b5a006b3da4 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Xml.Linq; - namespace System.Diagnostics { public static class TraceConfiguration @@ -18,18 +16,19 @@ public static void Register() if (!s_registered) { // Registering callbacks more than once is fine, but avoid the overhead common cases without taking a lock. - Trace.RefreshConfiguration += RefreshConfiguration; - Trace.ConfigureSwitch += ConfigureSwitch; - Trace.ConfigureTrace += ConfigureTraceSettings; - Trace.ConfigureTraceSource += ConfigureTraceSource; + Trace.Refreshing += RefreshingConfiguration; + Switch.Initializing += InitializingSwitch; + TraceSource.Initializing += InitializingTraceSource; + + ConfigureTraceSettings(); s_registered = true; } } - private static void RefreshConfiguration(object sender, EventArgs e) => DiagnosticsConfiguration.Refresh(); + private static void RefreshingConfiguration(object sender, EventArgs e) => DiagnosticsConfiguration.Refresh(); - private static void ConfigureTraceSource(object sender, ConfigureTraceSourceEventArgs e) + private static void InitializingTraceSource(object sender, InitializingTraceSourceEventArgs e) { TraceSource traceSource = e.TraceSource; @@ -41,10 +40,10 @@ private static void ConfigureTraceSource(object sender, ConfigureTraceSourceEven SourceElement sourceElement = sources[traceSource.Name]; if (sourceElement != null) { - e.WasConfigured = true; + e.WasInitialized = true; // First check if the type changed. - if (SourceSwitchTypeChanged()) + if (HasSourceSwitchTypeChanged()) { if (!string.IsNullOrEmpty(sourceElement.SwitchName)) { @@ -98,7 +97,7 @@ private static void ConfigureTraceSource(object sender, ConfigureTraceSourceEven } } - traceSource.Attributes = sourceElement.Attributes; + TraceUtils.CopyStringDictionary(sourceElement.Attributes, traceSource.Attributes); traceSource.Listeners.Clear(); traceSource.Listeners.AddRange(newListenerCollection); @@ -111,17 +110,26 @@ private static void ConfigureTraceSource(object sender, ConfigureTraceSourceEven traceSource.Attributes.Clear(); } - bool SourceSwitchTypeChanged() + bool HasSourceSwitchTypeChanged() { string sourceTypeName = sourceElement.SwitchType; Type currentType = traceSource.Switch.GetType(); - return (string.IsNullOrEmpty(sourceTypeName) && currentType != typeof(SourceSwitch)) || - (!string.IsNullOrEmpty(sourceTypeName) && - // Compare with FullName only - sourceTypeName != currentType.FullName && - // Compare with FullName plus start of AssemblyQualifiedName - !sourceTypeName.StartsWith(currentType.FullName + ",")); + if (string.IsNullOrEmpty(sourceTypeName)) + { + // SourceSwitch is the default switch type. + return currentType != typeof(SourceSwitch); + } + + if (sourceTypeName == currentType.FullName) + { + return false; + } + + // Since there can be more than one valid AssemblyQualifiedName for a given Type this + // check can return true for some cases which can cause a minor side effect of a new + // Switch being created instead of just being refreshed. + return sourceElement.SwitchType != currentType.AssemblyQualifiedName; } } @@ -138,7 +146,7 @@ void CreateSwitch(string typeName, string name) } } - private static void ConfigureTraceSettings(object sender, EventArgs e) + private static void ConfigureTraceSettings() { // Ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,06360b4de5e221c2, https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,37 @@ -153,7 +161,7 @@ private static void ConfigureTraceSettings(object sender, EventArgs e) ListenerElementsCollection listeners = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace.Listeners; if (listeners != null) { - // If listeners were configured, replace the defaults with these + // If listeners were configured, replace the defaults with these. Trace.Listeners.Clear(); foreach (var listener in listeners.GetRuntimeObject()) { @@ -163,7 +171,7 @@ private static void ConfigureTraceSettings(object sender, EventArgs e) } } - private static void ConfigureSwitch(object sender, ConfigureSwitchEventArgs e) + private static void InitializingSwitch(object sender, InitializingSwitchEventArgs e) { Switch sw = e.Switch; @@ -184,7 +192,7 @@ private static void ConfigureSwitch(object sender, ConfigureSwitchEventArgs e) sw.Value = sw.DefaultValue; } - sw.Attributes = mySettings.Attributes; + TraceUtils.CopyStringDictionary(sw.Attributes, mySettings.Attributes); } } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs index 95c7a17b1bb202..e5795150549d94 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceSection.cs @@ -8,10 +8,10 @@ namespace System.Diagnostics internal sealed class TraceSection : ConfigurationElement { private static readonly ConfigurationPropertyCollection s_properties = new(); - private static readonly ConfigurationProperty s_propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), null, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propAutoFlush = new ConfigurationProperty("autoflush", typeof(bool), false, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propIndentSize = new ConfigurationProperty("indentsize", typeof(int), 4, ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propUseGlobalLock = new ConfigurationProperty("useGlobalLock", typeof(bool), true, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propListeners = new("listeners", typeof(ListenerElementsCollection), null, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propAutoFlush = new("autoflush", typeof(bool), false, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propIndentSize = new("indentsize", typeof(int), 4, ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propUseGlobalLock = new("useGlobalLock", typeof(bool), true, ConfigurationPropertyOptions.None); static TraceSection() { diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceUtils.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceUtils.cs index 0d44b55b8e1dd2..99029ca290ef73 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceUtils.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceUtils.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.Collections; using System.Runtime.Versioning; +using System.Collections.Specialized; namespace System.Diagnostics { @@ -198,5 +199,16 @@ private static object ConvertToBaseTypeOrEnum(string value, Type type) Enum.Parse(type, value, false) : Convert.ChangeType(value, type, CultureInfo.InvariantCulture); } + + // Copy the StringDictionary to another StringDictionary. + // This is not as efficient as directly setting the property, but it avoids having to expose a public setter on the property. + internal static void CopyStringDictionary(StringDictionary source, StringDictionary dest) + { + dest.Clear(); + foreach (string key in source) + { + dest[key] = source[key]; + } + } } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs index 7f0c063f1f6ee1..618911077816c2 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TypedElement.cs @@ -6,8 +6,8 @@ namespace System.Diagnostics { internal class TypedElement : ConfigurationElement { - protected static readonly ConfigurationProperty s_propTypeName = new ConfigurationProperty("type", typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsTypeStringTransformationRequired); - protected static readonly ConfigurationProperty s_propInitData = new ConfigurationProperty("initializeData", typeof(string), string.Empty, ConfigurationPropertyOptions.None); + protected static readonly ConfigurationProperty s_propTypeName = new("type", typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsTypeStringTransformationRequired); + protected static readonly ConfigurationProperty s_propInitData = new("initializeData", typeof(string), string.Empty, ConfigurationPropertyOptions.None); protected ConfigurationPropertyCollection _properties; protected object _runtimeObject; diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj index 8f28909e9dc4e2..40dd04ac683659 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj @@ -1,4 +1,4 @@ - + true $(NetCoreAppCurrent);$(NetFrameworkMinimum) @@ -90,8 +90,8 @@ - - + + @@ -102,7 +102,6 @@ - diff --git a/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs b/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs index ac1f42b6b5f3c1..3831073431a074 100644 --- a/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs +++ b/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs @@ -14,17 +14,6 @@ public partial class BooleanSwitch : System.Diagnostics.Switch public bool Enabled { get { throw null; } set { } } protected override void OnValueChanged() { } } - public sealed partial class ConfigureSwitchEventArgs : System.EventArgs - { - public ConfigureSwitchEventArgs(System.Diagnostics.Switch @switch) { } - public System.Diagnostics.Switch Switch { get { throw null; } } - } - public sealed partial class ConfigureTraceSourceEventArgs : System.EventArgs - { - public ConfigureTraceSourceEventArgs(System.Diagnostics.TraceSource traceSource) { } - public System.Diagnostics.TraceSource TraceSource { get { throw null; } } - public bool WasConfigured { get { throw null; } set { } } - } public partial class CorrelationManager { internal CorrelationManager() { } @@ -50,6 +39,17 @@ public EventTypeFilter(System.Diagnostics.SourceLevels level) { } public System.Diagnostics.SourceLevels EventType { get { throw null; } set { } } public override bool ShouldTrace(System.Diagnostics.TraceEventCache? cache, string source, System.Diagnostics.TraceEventType eventType, int id, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string? formatOrMessage, object?[]? args, object? data1, object?[]? data) { throw null; } } + public sealed partial class InitializingSwitchEventArgs : System.EventArgs + { + public InitializingSwitchEventArgs(System.Diagnostics.Switch @switch) { } + public System.Diagnostics.Switch Switch { get { throw null; } } + } + public sealed partial class InitializingTraceSourceEventArgs : System.EventArgs + { + public InitializingTraceSourceEventArgs(System.Diagnostics.TraceSource traceSource) { } + public System.Diagnostics.TraceSource TraceSource { get { throw null; } } + public bool WasInitialized { get { throw null; } set { } } + } public partial class SourceFilter : System.Diagnostics.TraceFilter { public SourceFilter(string source) { } @@ -81,10 +81,11 @@ public abstract partial class Switch { protected Switch(string displayName, string? description) { } protected Switch(string displayName, string? description, string defaultSwitchValue) { } - public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } set { } } + public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } } public string DefaultValue { get { throw null; } } public string Description { get { throw null; } } public string DisplayName { get { throw null; } } + public static event System.EventHandler? Initializing { add { } remove { } } protected int SwitchSetting { get { throw null; } set { } } public string Value { get { throw null; } set { } } protected virtual string[]? GetSupportedAttributes() { throw null; } @@ -133,11 +134,8 @@ public static void Fail(string? message, string? detailMessage) { } public static void Flush() { } [System.Diagnostics.ConditionalAttribute("TRACE")] public static void Indent() { } - public static event EventHandler? ConfigureTrace { add { } remove { } } - public static event EventHandler? ConfigureTraceSource { add { } remove { } } - public static event EventHandler? ConfigureSwitch { add { } remove { } } public static void Refresh() { } - public static event EventHandler? RefreshConfiguration { add { } remove { } } + public static event System.EventHandler? Refreshing { add { } remove { } } [System.Diagnostics.ConditionalAttribute("TRACE")] public static void TraceError(string? message) { } [System.Diagnostics.ConditionalAttribute("TRACE")] @@ -225,7 +223,7 @@ public abstract partial class TraceListener : System.MarshalByRefObject, System. { protected TraceListener() { } protected TraceListener(string? name) { } - public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } set { } } + public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } } public System.Diagnostics.TraceFilter? Filter { get { throw null; } set { } } public int IndentLevel { get { throw null; } set { } } public int IndentSize { get { throw null; } set { } } @@ -302,8 +300,9 @@ public partial class TraceSource { public TraceSource(string name) { } public TraceSource(string name, System.Diagnostics.SourceLevels defaultLevel) { } - public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } set { } } - public SourceLevels DefaultLevel { get { throw null; } } + public System.Collections.Specialized.StringDictionary Attributes { get { throw null; } } + public System.Diagnostics.SourceLevels DefaultLevel { get { throw null; } } + public static event System.EventHandler? Initializing { add { } remove { } } public System.Diagnostics.TraceListenerCollection Listeners { get { throw null; } } public string Name { get { throw null; } } public System.Diagnostics.SourceSwitch Switch { get { throw null; } set { } } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj b/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj index 23ae1a61c77f4c..a97fe112aee959 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/src/System.Diagnostics.TraceSource.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/DefaultTraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/DefaultTraceListener.cs index 665b85850cbe9d..e808e3f8c56f2c 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/DefaultTraceListener.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/DefaultTraceListener.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#define DEBUG -#define TRACE using System; using System.IO; using System.Text; diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureSwitchEventArgs.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs similarity index 61% rename from src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureSwitchEventArgs.cs rename to src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs index 168f2c16ad12ff..49832eca314e1b 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureSwitchEventArgs.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs @@ -4,11 +4,11 @@ namespace System.Diagnostics { /// - /// Provides data for the event. + /// Provides data for the event. /// - public sealed class ConfigureSwitchEventArgs : EventArgs + public sealed class InitializingSwitchEventArgs : EventArgs { - public ConfigureSwitchEventArgs(Switch @switch) + public InitializingSwitchEventArgs(Switch @switch) { Switch = @switch; } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureTraceSourceEventArgs.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs similarity index 54% rename from src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureTraceSourceEventArgs.cs rename to src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs index e35e1b0cce97da..c66a2c308905b7 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/ConfigureTraceSourceEventArgs.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs @@ -4,16 +4,16 @@ namespace System.Diagnostics { /// - /// Provides data for the event. + /// Provides data for the event. /// - public sealed class ConfigureTraceSourceEventArgs : EventArgs + public sealed class InitializingTraceSourceEventArgs : EventArgs { - public ConfigureTraceSourceEventArgs(TraceSource traceSource) + public InitializingTraceSourceEventArgs(TraceSource traceSource) { TraceSource = traceSource; } public TraceSource TraceSource { get; } - public bool WasConfigured { get; set; } + public bool WasInitialized { get; set; } } } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs index dd35b104f73034..46ffc6d00774f5 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs @@ -123,11 +123,6 @@ public StringDictionary Attributes Initialize(); return _attributes ??= new StringDictionary(); } - set - { - TraceUtils.VerifyAttributes(value, GetSupportedAttributes(), this); - _attributes = value; - } } /// @@ -142,7 +137,9 @@ protected int SwitchSetting if (!_initialized) { if (InitializeWithStatus()) + { OnSwitchSettingChanged(); + } } return _switchSetting; } @@ -168,6 +165,9 @@ protected int SwitchSetting protected internal virtual string[]? GetSupportedAttributes() => null; + /// + /// The default value assigned in the constructor. + /// public string DefaultValue => _defaultValue; public string Value @@ -185,6 +185,16 @@ public string Value } } + /// + /// Occurs when a needs to be initialized. + /// + public static event EventHandler? Initializing; + internal void OnInitializing() + { + Initializing?.Invoke(null, new InitializingSwitchEventArgs(this)); + TraceUtils.VerifyAttributes(Attributes, GetSupportedAttributes(), this); + } + private void Initialize() { InitializeWithStatus(); @@ -209,7 +219,7 @@ private bool InitializeWithStatus() try { - Trace.OnConfigureSwitch(this); + OnInitializing(); } catch (Exception) { diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs index 6e7476562c1073..ceeb2d11c13c50 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs @@ -159,33 +159,18 @@ public static void Fail(string? message, string? detailMessage) TraceInternal.Fail(message, detailMessage); } - public static event EventHandler? ConfigureTrace; - internal static void OnConfigureTrace() + /// + /// Occurs when a needs to be refreshed from configuration. + /// + public static event EventHandler? Refreshing; + internal static void OnRefreshing() { - ConfigureTrace?.Invoke(null, EventArgs.Empty); - } - - public static event EventHandler? RefreshConfiguration; - internal static void OnRefreshConfiguration() - { - RefreshConfiguration?.Invoke(null, EventArgs.Empty); - } - - public static event EventHandler? ConfigureTraceSource; - internal static void OnConfigureTraceSource(ConfigureTraceSourceEventArgs e) - { - ConfigureTraceSource?.Invoke(null, e); - } - - public static event EventHandler? ConfigureSwitch; - internal static void OnConfigureSwitch(Switch @switch) - { - ConfigureSwitch?.Invoke(null, new ConfigureSwitchEventArgs(@switch)); + Refreshing?.Invoke(null, EventArgs.Empty); } public static void Refresh() { - OnRefreshConfiguration(); + OnRefreshing(); Switch.RefreshAll(); TraceSource.RefreshAll(); TraceInternal.Refresh(); diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs index 5c3983e16e74d6..e17c1d57579ba3 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs @@ -285,8 +285,8 @@ private static void InitializeSettings() { if (!s_settingsInitialized) { - // we should avoid 2 threads altering the state concurrently for predictable behavior - // though it may not be strictly necessary at present + // We should avoid 2 threads altering the state concurrently for predictable behavior + // though it may not be strictly necessary at present. lock (critSec) { // prevent re-entrance @@ -301,9 +301,6 @@ private static void InitializeSettings() { s_autoFlush = DiagnosticsConfiguration.AutoFlush; s_useGlobalLock = DiagnosticsConfiguration.UseGlobalLock; - - Trace.OnConfigureTrace(); - s_settingsInitialized = true; s_settingsInitializing = false; } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs index 9b40d62eea53f7..0cd7be16db6b0a 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs @@ -45,11 +45,6 @@ protected TraceListener(string? name) public StringDictionary Attributes { get => _attributes ??= new StringDictionary(); - set - { - TraceUtils.VerifyAttributes(value, GetSupportedAttributes(), this); - _attributes = value; - } } /// @@ -59,7 +54,6 @@ public StringDictionary Attributes public virtual string Name { get { return _listenerName ?? ""; } - set { _listenerName = value; } } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs index 744225a3ef0e63..ec6538c7834248 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs @@ -81,10 +81,10 @@ private void Initialize() NoConfigInit_BeforeEvent(); - ConfigureTraceSourceEventArgs e = new ConfigureTraceSourceEventArgs(this); - Trace.OnConfigureTraceSource(e); + InitializingTraceSourceEventArgs e = new InitializingTraceSourceEventArgs(this); + OnInitializing(e); - if (!e.WasConfigured) + if (!e.WasInitialized) { NoConfigInit_AfterEvent(); } @@ -183,7 +183,7 @@ internal void Refresh() return; } - Trace.OnConfigureTraceSource(new ConfigureTraceSourceEventArgs(this)); + OnInitializing(new InitializingTraceSourceEventArgs(this)); } [Conditional("TRACE")] @@ -489,16 +489,29 @@ public StringDictionary Attributes Initialize(); return _attributes ??= new StringDictionary(); } + } - set + /// + /// The default level assigned in the constructor. + /// + public SourceLevels DefaultLevel => _switchLevel; + + /// + /// Occurs when a needs to be initialized. + /// + public static event EventHandler? Initializing; + internal void OnInitializing(InitializingTraceSourceEventArgs e) + { + Initializing?.Invoke(this, e); + + TraceUtils.VerifyAttributes(Attributes, GetSupportedAttributes(), this); + + foreach (TraceListener listener in Listeners) { - TraceUtils.VerifyAttributes(value, GetSupportedAttributes(), this); - _attributes = value; + TraceUtils.VerifyAttributes(listener.Attributes, listener.GetSupportedAttributes(), this); } } - public SourceLevels DefaultLevel => _switchLevel; - public string Name => _sourceName; public TraceListenerCollection Listeners diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs index 3f207e1d206754..f02be73226fdc7 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs @@ -30,8 +30,11 @@ internal static void VerifyAttributes(StringDictionary? attributes, string[]? su found = true; } } + if (!found) + { throw new ArgumentException(SR.Format(SR.AttributeNotSupported, key, parent.GetType().FullName)); + } } } } diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj index 6f35d2ffe79951..9c0a839c203afc 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj @@ -3,22 +3,40 @@ true $(NetCoreAppCurrent) + + + - + + Always + + + Always + + + Always + + + Always + + + Always + + Always - + Always - + Always - + Always diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs index 46149cf3eb8fce..f59f8440c3f15c 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs @@ -14,12 +14,25 @@ namespace System.Diagnostics.TraceSourceConfigTests { public class ConfigurationTests { - private const string ConfigFile = "testhost.dll.config"; + private static volatile string? _configFile = null; + + private static string ConfigFile + { + get + { + if (_configFile == null) + { + Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + _configFile = Path.GetFileName(config.FilePath); + } + + return _configFile; + } + } private static void CreateAndLoadConfigFile(string filename) { Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); - Assert.Equal(ConfigFile, Path.GetFileName(config.FilePath)); string dir = Path.GetDirectoryName(config.FilePath); string from = Path.Combine(dir, filename); File.Copy(from, ConfigFile, overwrite: true); @@ -28,9 +41,10 @@ private static void CreateAndLoadConfigFile(string filename) } [Fact] - public void ConfigWithRuntimeFilterChange() + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] + public void RuntimeFilterChange() { - CreateAndLoadConfigFile("testhost_ConfigWithRuntime.dll.config"); + CreateAndLoadConfigFile("testhost_ConfigWithRuntime.config"); TraceSource mySource = new TraceSource("TraceSourceApp"); StringTraceListener origListener = (StringTraceListener)mySource.Listeners["origListener"]; @@ -40,8 +54,8 @@ public void ConfigWithRuntimeFilterChange() mySource.TraceEvent(TraceEventType.Error, 1, "Error message."); mySource.TraceEvent(TraceEventType.Warning, 2, "Warning message."); - Assert.Equal("TraceSourceApp Error: 1 : Error message.\r\n", origListener.Output); - Assert.Equal("TraceSourceApp Error: 1 : Error message.\r\n", secondListener.Output); + Assert.Equal($"TraceSourceApp Error: 1 : Error message.{Environment.NewLine}", origListener.Output); + Assert.Equal($"TraceSourceApp Error: 1 : Error message.{Environment.NewLine}", secondListener.Output); // Save the original settings from the configuration file. EventTypeFilter configFilter = (EventTypeFilter)mySource.Listeners["origListener"].Filter; @@ -63,11 +77,11 @@ public void ConfigWithRuntimeFilterChange() // Both should be logged for origListener. Assert.Equal( - "TraceSourceApp Critical: 3 : Critical message.\r\n" + - "TraceSourceApp Warning: 4 : Warning message.\r\n", origListener.Output); + $"TraceSourceApp Critical: 3 : Critical message.{Environment.NewLine}" + + $"TraceSourceApp Warning: 4 : Warning message.{Environment.NewLine}", origListener.Output); // secondListener is unchanged and doesn't log warnings. - Assert.Equal("TraceSourceApp Critical: 3 : Critical message.\r\n", secondListener.Output); + Assert.Equal($"TraceSourceApp Critical: 3 : Critical message.{Environment.NewLine}", secondListener.Output); // Restore the original filter settings. origListener.Clear(); @@ -78,8 +92,8 @@ public void ConfigWithRuntimeFilterChange() mySource.TraceEvent(TraceEventType.Error, 5, "Error message."); mySource.TraceInformation("Informational message."); - Assert.Equal("TraceSourceApp Error: 5 : Error message.\r\n", origListener.Output); - Assert.Equal("TraceSourceApp Error: 5 : Error message.\r\n", secondListener.Output); + Assert.Equal($"TraceSourceApp Error: 5 : Error message.{Environment.NewLine}", origListener.Output); + Assert.Equal($"TraceSourceApp Error: 5 : Error message.{Environment.NewLine}", secondListener.Output); origListener.Clear(); secondListener.Clear(); @@ -87,32 +101,36 @@ public void ConfigWithRuntimeFilterChange() } [Fact] - public void RefreshSwitchFromConfigFile() + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] + public void Refresh_RemoveSwitch() { // Use a SourceSwitch that logs Error. - CreateAndLoadConfigFile("testhost_RefreshSwitch_before.dll.config"); + CreateAndLoadConfigFile("testhost_RemoveSwitch_before.config"); + + SourceSwitch sswitch = new SourceSwitch("Refresh_RemoveSwitch_sourceSwitchToBeRemoved", "Warning"); + Assert.Equal("Warning", sswitch.DefaultValue); + Assert.Equal("Error", sswitch.Value); + + TraceSource mySource = new TraceSource("Refresh_RemoveSwitch"); + StringTraceListener listener = (StringTraceListener)mySource.Listeners["listener"]; - TraceSource mySource = new TraceSource("TraceSourceApp"); - StringTraceListener listener = (StringTraceListener)mySource.Listeners["origListener"]; Log(); Assert.Equal( - "TraceSourceApp Error: 1 : Error message.\r\n" + - "TraceSourceApp Critical: 3 : Critical message.\r\n", listener.Output); + $"Refresh_RemoveSwitch Error: 1 : Error message.{Environment.NewLine}" + + $"Refresh_RemoveSwitch Critical: 3 : Critical message.{Environment.NewLine}", listener.Output); // Change the switch to log All. listener.Clear(); - CreateAndLoadConfigFile("testhost_RefreshSwitch_after.dll.config"); + CreateAndLoadConfigFile("testhost_RemoveSwitch_after.config"); Trace.Refresh(); + + Assert.Equal("Warning", sswitch.DefaultValue); + Assert.Equal("Warning", sswitch.Value); // Changed to Warning since the switch was removed from the config. + Log(); - Assert.Equal( - "TraceSourceApp Error: 1 : Error message.\r\n" + - "TraceSourceApp Warning: 2 : Warning message.\r\n" + - "TraceSourceApp Critical: 3 : Critical message.\r\n" + - "TraceSourceApp Information: 0 : Informational message.\r\n", listener.Output); + Assert.Equal(string.Empty, listener.Output); // The default replacement switch is off. listener.Clear(); - mySource.Close(); - void Log() { mySource.TraceEvent(TraceEventType.Error, 1, "Error message."); @@ -123,12 +141,71 @@ void Log() } [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] + public void Refresh_ChangeSwitch() + { + // Use a SourceSwitch that logs Error. + CreateAndLoadConfigFile("testhost_ChangeSwitch_before.config"); + + TraceSource mySource = new TraceSource("Refresh_ChangeSwitch"); + StringTraceListener listener = (StringTraceListener)mySource.Listeners["listener"]; + + mySource.TraceInformation("Informational message."); + Assert.Equal(string.Empty, listener.Output); // Switch is off. + + // Change the switch to log. + listener.Clear(); + CreateAndLoadConfigFile("testhost_ChangeSwitch_after.config"); + Trace.Refresh(); + + mySource.TraceInformation("Informational message."); + Assert.Equal($"Refresh_ChangeSwitch Information: 0 : Informational message.{Environment.NewLine}", listener.Output); + + listener.Close(); + mySource.Close(); + } + + [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] + public void Refresh_RemoveSource() + { + // Use a SourceSwitch that logs Error. + CreateAndLoadConfigFile("testhost_RemoveSource_before.config"); + + TraceSource mySourceToBeRemoved = new TraceSource("Refresh_RemoveSource", SourceLevels.Warning); + Assert.Equal(SourceLevels.Warning, mySourceToBeRemoved.DefaultLevel); + Assert.Equal(SourceLevels.Error, mySourceToBeRemoved.Switch.Level); // Config has Error. + Assert.Equal("Error", mySourceToBeRemoved.Switch.Value); + + StringTraceListener listenerToBeRemoved = (StringTraceListener)mySourceToBeRemoved.Listeners["listener"]; + listenerToBeRemoved.Clear(); + mySourceToBeRemoved.TraceEvent(TraceEventType.Error, 1, "Error message."); + Assert.Equal($"Refresh_RemoveSource Error: 1 : Error message.{Environment.NewLine}", listenerToBeRemoved.Output); + + // Change the switch to log All. + listenerToBeRemoved.Clear(); + CreateAndLoadConfigFile("testhost_RemoveSource_after.config"); + Trace.Refresh(); + + Assert.Equal(SourceLevels.Warning, mySourceToBeRemoved.DefaultLevel); + Assert.Equal(SourceLevels.Warning, mySourceToBeRemoved.Switch.Level); // Changed to Warning since the switch was removed from the config. + Assert.Equal("Error", mySourceToBeRemoved.Switch.Value); + + mySourceToBeRemoved.TraceEvent(TraceEventType.Error, 1, "Error message."); + Assert.Equal(string.Empty, listenerToBeRemoved.Output); + + listenerToBeRemoved.Clear(); + //mySourceToBeRemoved.Close(); + } + + [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public void ConfigWithEvents_RuntimeListener() { - CreateAndLoadConfigFile("testhost_ConfigWithRuntime.dll.config"); + CreateAndLoadConfigFile("testhost_ConfigWithRuntime.config"); - Trace.ConfigureTraceSource += SubscribeToConfigTracesource_ConfigureTraceSource; - Trace.ConfigureSwitch += SubscribeToConfigTracesource_ConfigureSwitch; + TraceSource.Initializing += SubscribeToTraceSource_Initializing; + Switch.Initializing += SubscribeToSwitch_Initializing; TraceSource mySource = new("TraceSource_NoListeners"); Assert.Equal(1, mySource.Listeners.Count); // The default listener was removed via the config @@ -137,22 +214,22 @@ public void ConfigWithEvents_RuntimeListener() // Only the Critical should be logged. // The config setting was to only log Error, but changed to Critical in the event handler. Log(); - Assert.Equal("TraceSource_NoListeners Critical: 3 : Critical message.\r\n", dynamicallyAddedListener.Output); + Assert.Equal($"TraceSource_NoListeners Critical: 3 : Critical message.{Environment.NewLine}", dynamicallyAddedListener.Output); // Log all. dynamicallyAddedListener.Clear(); mySource.Switch.Level = SourceLevels.All; Log(); Assert.Equal( - "TraceSource_NoListeners Error: 1 : Error message.\r\n" + - "TraceSource_NoListeners Warning: 2 : Warning message.\r\n" + - "TraceSource_NoListeners Critical: 3 : Critical message.\r\n" + - "TraceSource_NoListeners Information: 0 : Informational message.\r\n", dynamicallyAddedListener.Output); + $"TraceSource_NoListeners Error: 1 : Error message.{Environment.NewLine}" + + $"TraceSource_NoListeners Warning: 2 : Warning message.{Environment.NewLine}" + + $"TraceSource_NoListeners Critical: 3 : Critical message.{Environment.NewLine}" + + $"TraceSource_NoListeners Information: 0 : Informational message.{Environment.NewLine}", dynamicallyAddedListener.Output); dynamicallyAddedListener.Clear(); mySource.Close(); - Trace.ConfigureTraceSource -= SubscribeToConfigTracesource_ConfigureTraceSource; - Trace.ConfigureSwitch -= SubscribeToConfigTracesource_ConfigureSwitch; + TraceSource.Initializing -= SubscribeToTraceSource_Initializing; + Switch.Initializing -= SubscribeToSwitch_Initializing; void Log() { @@ -163,7 +240,7 @@ void Log() } } - private void SubscribeToConfigTracesource_ConfigureTraceSource(object? sender, ConfigureTraceSourceEventArgs e) + private void SubscribeToTraceSource_Initializing(object? sender, InitializingTraceSourceEventArgs e) { TraceSource traceSource = e.TraceSource; if (traceSource.Name == "TraceSource_NoListeners") @@ -173,7 +250,7 @@ private void SubscribeToConfigTracesource_ConfigureTraceSource(object? sender, C } } - private void SubscribeToConfigTracesource_ConfigureSwitch(object? sender, ConfigureSwitchEventArgs e) + private void SubscribeToSwitch_Initializing(object? sender, InitializingSwitchEventArgs e) { Switch sw = e.Switch; if (sw.DisplayName == "generalSourceSwitch_Error") @@ -188,9 +265,10 @@ private void SubscribeToConfigTracesource_ConfigureSwitch(object? sender, Config } [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public void AllTypes() { - CreateAndLoadConfigFile("testhost_AllTypes.dll.config"); + CreateAndLoadConfigFile("testhost_AllTypes.config"); TraceSource mySource; @@ -203,7 +281,7 @@ public void AllTypes() mySource = new("DelimitedListTraceListener"); Assert.Equal("L1", mySource.Listeners[1].Name); - // Only supported on .NET Framework. + // The referenced S.R.ConfigurationManager.dll is NetStandard, which does not support EventLogTraceListener. mySource = new("EventLogTraceListener"); Exception e = Assert.Throws(() => mySource.Listeners[1].Name); Assert.IsType(e.InnerException); @@ -229,5 +307,14 @@ public void AllTypes() TraceSource filter_eventTypeFilter = new("filter_eventTypeFilter"); Assert.IsType(filter_eventTypeFilter.Listeners[1].Filter); } + + [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] + public void Switch_MissingValue_Throws() + { + Exception e = Assert.Throws(() => + CreateAndLoadConfigFile("testhost_Switch_MissingValue_Throws.config")); + Assert.Contains("'value'", e.ToString()); + } } } diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_AllTypes.dll.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_AllTypes.config similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_AllTypes.dll.config rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_AllTypes.config diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_after.dll.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ChangeSwitch_after.config similarity index 63% rename from src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_after.dll.config rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ChangeSwitch_after.config index 6bcc590cc75783..e7bd8d69770ecc 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_after.dll.config +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ChangeSwitch_after.config @@ -1,11 +1,11 @@  - - + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_before.dll.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ChangeSwitch_before.config similarity index 54% rename from src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_before.dll.config rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ChangeSwitch_before.config index 2a077281398615..86f2f66d8dacce 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RefreshSwitch_before.dll.config +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ChangeSwitch_before.config @@ -1,16 +1,16 @@  - - + - + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ConfigWithRuntime.dll.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ConfigWithRuntime.config similarity index 100% rename from src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ConfigWithRuntime.dll.config rename to src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_ConfigWithRuntime.config diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSource_after.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSource_after.config new file mode 100644 index 00000000000000..c07deb67560703 --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSource_after.config @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSource_before.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSource_before.config new file mode 100644 index 00000000000000..4b549fe9a28ba0 --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSource_before.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSwitch_after.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSwitch_after.config new file mode 100644 index 00000000000000..8c388eca0864b1 --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSwitch_after.config @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSwitch_before.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSwitch_before.config new file mode 100644 index 00000000000000..d6bb34450708aa --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_RemoveSwitch_before.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_Switch_MissingValue_Throws.config b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_Switch_MissingValue_Throws.config new file mode 100644 index 00000000000000..046ab064dfa0f4 --- /dev/null +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/testhost_Switch_MissingValue_Throws.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj index c0e6c51b02bbb9..c2276c55544508 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj @@ -3,10 +3,6 @@ true $(NetCoreAppCurrent) - - - From 3159c85b20abbe305329e5da3334f2c1949809f4 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Mon, 8 Aug 2022 11:51:26 -0500 Subject: [PATCH 5/9] Non functional changes - format, comments --- .../src/Resources/Strings.resx | 71 +++---------------- .../Diagnostics/DiagnosticsConfiguration.cs | 40 +++-------- .../Diagnostics/ListenerElementsCollection.cs | 2 +- .../Diagnostics/SourceElementsCollection.cs | 2 +- .../Diagnostics/SwitchElementsCollection.cs | 2 +- .../src/System/Diagnostics/Switch.cs | 1 + .../src/System/Diagnostics/Trace.cs | 1 + .../src/System/Diagnostics/TraceInternal.cs | 2 +- .../src/System/Diagnostics/TraceSource.cs | 1 + 9 files changed, 24 insertions(+), 98 deletions(-) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx b/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx index c7a69f6327f5f5..de9cd14cb77b88 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx +++ b/src/libraries/System.Configuration.ConfigurationManager/src/Resources/Strings.resx @@ -1,64 +1,4 @@ - - - + @@ -135,6 +75,10 @@ {0}: {1} + An error occurred loading a configuration file @@ -147,6 +91,9 @@ Invalid format for a section or section group name + Cannot add a ConfigurationSection that already belongs to the Configuration. @@ -747,4 +694,4 @@ initializeData needs to be valid for this TraceListener. - \ No newline at end of file + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs index 8cbdae295e4ae4..868298fa7f7476 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/DiagnosticsConfiguration.cs @@ -18,14 +18,7 @@ internal static SwitchElementsCollection SwitchSettings { Initialize(); SystemDiagnosticsSection configSectionSav = s_configSection; - if (configSectionSav != null) - { - return configSectionSav.Switches; - } - else - { - return null; - } + return configSectionSav?.Switches; } } @@ -100,12 +93,7 @@ internal static ListenerElementsCollection SharedListeners { Initialize(); SystemDiagnosticsSection configSectionSav = s_configSection; - if (configSectionSav != null) - { - return configSectionSav.SharedListeners; - } - - return null; + return configSectionSav?.SharedListeners; } } @@ -115,12 +103,7 @@ internal static SourceElementsCollection Sources { Initialize(); SystemDiagnosticsSection configSectionSav = s_configSection; - if (configSectionSav != null && configSectionSav.Sources != null) - { - return configSectionSav.Sources; - } - - return null; + return configSectionSav?.Sources; } } @@ -135,8 +118,7 @@ internal static SystemDiagnosticsSection SystemDiagnosticsSection private static SystemDiagnosticsSection GetConfigSection() { - SystemDiagnosticsSection s_configSection = (SystemDiagnosticsSection)PrivilegedConfigurationManager.GetSection("system.diagnostics"); - return s_configSection; + return s_configSection ??= (SystemDiagnosticsSection)PrivilegedConfigurationManager.GetSection("system.diagnostics"); } internal static bool IsInitializing() => s_initState == InitState.Initializing; @@ -147,17 +129,11 @@ internal static bool CanInitialize() => (s_initState != InitState.Initializing) internal static void Initialize() { - // Initialize() is also called by other components outside of Trace (such as PerformanceCounter) - // as a result using one lock for this critical section and another for Trace API critical sections - // (such as Trace.WriteLine) could potentially lead to deadlock between 2 threads that are - // executing these critical sections (and consequently obtaining the 2 locks) in the reverse order. - // Using the same lock for DiagnosticsConfiguration as well as TraceInternal avoids this issue. - // Sequential locks on TraceInternal.critSec by the same thread is a non issue for this critical section. - - // TODO -- determine if locking here is still important - // lock (TraceInternal.critSec) { + // 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 + // 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 || diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs index d82fe1be599270..04a54960bcc91d 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/ListenerElementsCollection.cs @@ -227,7 +227,7 @@ public TraceListener GetRuntimeObject() } // Our optional attributes implementation is little convoluted as there is - // no such firsclass mechanism from the config system. We basically cache + // no such first class mechanism from the config system. We basically cache // any "unrecognized" attribute here and serialize it out later. protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) { diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs index 9ee667b72234d2..b4d0434445f9ab 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SourceElementsCollection.cs @@ -78,7 +78,7 @@ protected internal override void DeserializeElement(XmlReader reader, bool seria } // Our optional attributes implementation is little convoluted as there is - // no such firsclass mechanism from the config system. We basically cache + // no such first class mechanism from the config system. We basically cache // any "unrecognized" attribute here and serialize it out later. protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) { diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs index 507ab073278955..7cd92443d111cb 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SwitchElementsCollection.cs @@ -42,7 +42,7 @@ static SwitchElement() public string Value => (string)this[_propValue]; // Our optional attributes implementation is little convoluted as there is - // no such firsclass mechanism from the config system. We basically cache + // no such first class mechanism from the config system. We basically cache // any "unrecognized" attribute here and serialize it out later. protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) { diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs index 46ffc6d00774f5..3ea419aaf50407 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs @@ -189,6 +189,7 @@ public string Value /// Occurs when a needs to be initialized. /// public static event EventHandler? Initializing; + internal void OnInitializing() { Initializing?.Invoke(null, new InitializingSwitchEventArgs(this)); diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs index ceeb2d11c13c50..22e4c6b1e2c9dc 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Trace.cs @@ -163,6 +163,7 @@ public static void Fail(string? message, string? detailMessage) /// Occurs when a needs to be refreshed from configuration. /// public static event EventHandler? Refreshing; + internal static void OnRefreshing() { Refreshing?.Invoke(null, EventArgs.Empty); diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs index e17c1d57579ba3..0454ae306aa3bd 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceInternal.cs @@ -289,7 +289,7 @@ private static void InitializeSettings() // though it may not be strictly necessary at present. lock (critSec) { - // prevent re-entrance + // Prevent re-entrance. if (s_settingsInitializing) { return; diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs index ec6538c7834248..f9a8d23f3ec363 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceSource.cs @@ -500,6 +500,7 @@ public StringDictionary Attributes /// Occurs when a needs to be initialized. /// public static event EventHandler? Initializing; + internal void OnInitializing(InitializingTraceSourceEventArgs e) { Initializing?.Invoke(this, e); From a5ac25d24200ca0e6febfcaaba0d95f4bba30791 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Mon, 8 Aug 2022 16:49:19 -0500 Subject: [PATCH 6/9] Fix System.Diagnostics.PerformanceCounter diag overlap --- ...stem.Configuration.ConfigurationManager.cs | 15 ++++-- ....Configuration.ConfigurationManager.csproj | 3 +- ...uration.ConfigurationManager.netcoreapp.cs | 13 +++++ ....Configuration.ConfigurationManager.csproj | 6 ++- .../Diagnostics/PerfCounterSettings.cs} | 6 +-- .../Diagnostics/SystemDiagnosticsSection.cs | 36 ++++--------- .../SystemDiagnosticsSection.netcoreapp.cs | 40 +++++++++++++++ .../System/Diagnostics/TraceConfiguration.cs | 10 ++-- ...stem.Diagnostics.PerformanceCounter.csproj | 4 +- .../Diagnostics/DiagnosticsConfiguration.cs | 4 +- .../Diagnostics/SystemDiagnosticsSection.cs | 18 ------- .../StringTraceListener.cs | 5 -- ...iagnostics.TraceSource.Config.Tests.csproj | 2 +- .../TraceSourceWithConfigurationTests.cs | 50 ++++++++++--------- 14 files changed, 119 insertions(+), 93 deletions(-) create mode 100644 src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs rename src/libraries/{System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs => System.Configuration.ConfigurationManager/src/System/Diagnostics/PerfCounterSettings.cs} (72%) create mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.netcoreapp.cs delete mode 100644 src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs index 7c754beb6ae33f..c55756b576a0ee 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs @@ -1578,15 +1578,22 @@ public ProviderException(string message) { } public ProviderException(string message, System.Exception innerException) { } } } -#if NET7_0_OR_GREATER namespace System.Diagnostics { - public static partial class TraceConfiguration + public sealed partial class PerfCounterSettings : System.Configuration.ConfigurationElement { - public static void Register() { } + public PerfCounterSettings() { } + public int FileMappingSize { get { throw null; } } + protected override System.Configuration.ConfigurationPropertyCollection Properties { get { throw null; } } + } + public sealed partial class SystemDiagnosticsSection : System.Configuration.ConfigurationSection + { + public SystemDiagnosticsSection() { } + public System.Diagnostics.PerfCounterSettings PerfCounterSettings { get { throw null; } } + protected override System.Configuration.ConfigurationPropertyCollection Properties { get { throw null; } } + protected override void InitializeDefault() { } } } -#endif namespace System.Drawing.Configuration { public sealed partial class SystemDrawingSection : System.Configuration.ConfigurationSection diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj index 58e634cc9634ee..6e0f157ee6f2e3 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) disable @@ -8,6 +8,7 @@ + diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs new file mode 100644 index 00000000000000..3fffb8cd3951d8 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs @@ -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() { } + } +} diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj index 2badd2c37adec6..387d0b664286b6 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj @@ -257,6 +257,8 @@ System.Configuration.ConfigurationManager + + @@ -269,13 +271,13 @@ System.Configuration.ConfigurationManager - + - + diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/PerfCounterSettings.cs similarity index 72% rename from src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs rename to src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/PerfCounterSettings.cs index 7169e201f65e33..cea7b4673d03d2 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/PerfCounterSettings.cs @@ -1,11 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// 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; namespace System.Diagnostics { - internal sealed class PerfCounterSection : ConfigurationElement + public sealed class PerfCounterSettings : ConfigurationElement { private static readonly ConfigurationProperty s_propFileMappingSize = new ConfigurationProperty("filemappingsize", typeof(int), 524288, ConfigurationPropertyOptions.None); private static readonly ConfigurationPropertyCollection s_properties = new ConfigurationPropertyCollection { s_propFileMappingSize }; @@ -13,6 +13,6 @@ internal sealed class PerfCounterSection : ConfigurationElement [ConfigurationProperty("filemappingsize", DefaultValue = 524288)] public int FileMappingSize => (int)this[s_propFileMappingSize]; - protected override ConfigurationPropertyCollection Properties => s_properties; + protected internal override ConfigurationPropertyCollection Properties => s_properties; } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs index e4b5af069fe35b..9a8a3d64e09bb7 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs @@ -1,43 +1,27 @@ -// Licensed to the .NET Foundation under one or more agreements. +// 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; namespace System.Diagnostics { - internal sealed class SystemDiagnosticsSection : ConfigurationSection + public sealed partial class SystemDiagnosticsSection : ConfigurationSection { private static readonly ConfigurationPropertyCollection s_properties = new(); - private static readonly ConfigurationProperty s_propSources = new("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propSharedListeners = new("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propSwitches = new("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propTrace = new("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propPerfCounters = new ConfigurationProperty("performanceCounters", typeof(PerfCounterSettings), new PerfCounterSettings(), ConfigurationPropertyOptions.None); static SystemDiagnosticsSection() { - s_properties.Add(s_propSources); - s_properties.Add(s_propSharedListeners); - s_properties.Add(s_propSwitches); - s_properties.Add(s_propTrace); + s_properties.Add(s_propPerfCounters); + +#if NET7_0_OR_GREATER + SystemDiagnosticsSectionNetCoreApp(); +#endif } protected internal override ConfigurationPropertyCollection Properties => s_properties; - [ConfigurationProperty("sources")] - public SourceElementsCollection Sources => (SourceElementsCollection)base[s_propSources]; - - [ConfigurationProperty("sharedListeners")] - public ListenerElementsCollection SharedListeners => (ListenerElementsCollection)base[s_propSharedListeners]; - - [ConfigurationProperty("switches")] - public SwitchElementsCollection Switches => (SwitchElementsCollection)base[s_propSwitches]; - - [ConfigurationProperty("trace")] - public TraceSection Trace => (TraceSection)base[s_propTrace]; - - protected internal override void InitializeDefault() - { - Trace.Listeners?.InitializeDefaultInternal(); - } + [ConfigurationProperty("performanceCounters")] + public PerfCounterSettings PerfCounterSettings => (PerfCounterSettings)base[s_propPerfCounters]; } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.netcoreapp.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.netcoreapp.cs new file mode 100644 index 00000000000000..0757a137df8321 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.netcoreapp.cs @@ -0,0 +1,40 @@ +// 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; + +namespace System.Diagnostics +{ + public partial class SystemDiagnosticsSection + { + private static readonly ConfigurationProperty s_propSources = new("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSharedListeners = new("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSwitches = new("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propTrace = new("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); + + private static void SystemDiagnosticsSectionNetCoreApp() + { + s_properties.Add(s_propSources); + s_properties.Add(s_propSharedListeners); + s_properties.Add(s_propSwitches); + s_properties.Add(s_propTrace); + } + + [ConfigurationProperty("sources")] + internal SourceElementsCollection Sources => (SourceElementsCollection)base[s_propSources]; + + [ConfigurationProperty("sharedListeners")] + internal ListenerElementsCollection SharedListeners => (ListenerElementsCollection)base[s_propSharedListeners]; + + [ConfigurationProperty("switches")] + internal SwitchElementsCollection Switches => (SwitchElementsCollection)base[s_propSwitches]; + + [ConfigurationProperty("trace")] + internal TraceSection Trace => (TraceSection)base[s_propTrace]; + + protected internal override void InitializeDefault() + { + Trace.Listeners?.InitializeDefaultInternal(); + } + } +} diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs index d02b5a006b3da4..8c21cb6473a264 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs @@ -150,13 +150,13 @@ private static void ConfigureTraceSettings() { // Ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,06360b4de5e221c2, https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,37 - TraceSection traceSection = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace; + TraceSection traceSettings = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace; - if (traceSection != null) + if (traceSettings != null) { - Trace.UseGlobalLock = traceSection.UseGlobalLock; - Trace.AutoFlush = traceSection.AutoFlush; - Trace.IndentSize = traceSection.IndentSize; + Trace.UseGlobalLock = traceSettings.UseGlobalLock; + Trace.AutoFlush = traceSettings.AutoFlush; + Trace.IndentSize = traceSettings.IndentSize; ListenerElementsCollection listeners = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace.Listeners; if (listeners != null) diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj index 8a800527bb10bb..b1fe08e2d0a23c 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true @@ -29,7 +29,6 @@ System.Diagnostics.PerformanceCounter - Component @@ -41,7 +40,6 @@ System.Diagnostics.PerformanceCounter - diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs index ad942e734183d1..9eddbb2885b56e 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs @@ -32,9 +32,9 @@ internal static int PerformanceCountersFileMappingSize Initialize(); SystemDiagnosticsSection configSectionSav = s_configSection; - if (configSectionSav != null && configSectionSav.PerfCounters != null) + if (configSectionSav != null && configSectionSav.PerfCounterSettings != null) { - int size = configSectionSav.PerfCounters.FileMappingSize; + int size = configSectionSav.PerfCounterSettings.FileMappingSize; if (size < SharedPerformanceCounter.MinCountersFileMappingSize) size = SharedPerformanceCounter.MinCountersFileMappingSize; diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs deleted file mode 100644 index aa40d83aed03ae..00000000000000 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs +++ /dev/null @@ -1,18 +0,0 @@ -// 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; - -namespace System.Diagnostics -{ - internal sealed class SystemDiagnosticsSection : ConfigurationSection - { - private static readonly ConfigurationProperty s_propPerfCounters = new ConfigurationProperty("performanceCounters", typeof(PerfCounterSection), new PerfCounterSection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationPropertyCollection s_properties = new ConfigurationPropertyCollection { s_propPerfCounters }; - - [ConfigurationProperty("performanceCounters")] - public PerfCounterSection PerfCounters => (PerfCounterSection)base[s_propPerfCounters]; - - protected override ConfigurationPropertyCollection Properties => s_properties; - } -} diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs index 94d3e06e45a5ad..efd8d8283bb0cb 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs @@ -1,12 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace System.Diagnostics.TraceSourceConfigTests { diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj index 9c0a839c203afc..1ca83850ed6a54 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj @@ -41,6 +41,6 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs index f59f8440c3f15c..fda40c2f21e0b9 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs @@ -1,43 +1,36 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.Configuration; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Reflection; using Xunit; namespace System.Diagnostics.TraceSourceConfigTests { + // Note that parallelization is disabled due to file access as each test replaces the single config file on disk. public class ConfigurationTests { private static volatile string? _configFile = null; - private static string ConfigFile - { - get - { - if (_configFile == null) - { - Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); - _configFile = Path.GetFileName(config.FilePath); - } - - return _configFile; - } - } - private static void CreateAndLoadConfigFile(string filename) { Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); string dir = Path.GetDirectoryName(config.FilePath); string from = Path.Combine(dir, filename); - File.Copy(from, ConfigFile, overwrite: true); - TraceConfiguration.Register(); - Trace.Refresh(); + + if (_configFile == null) + { + _configFile = Path.GetFileName(config.FilePath); + File.Copy(from, _configFile, overwrite: true); + TraceConfiguration.Register(); + // Do not call Trace.Refresh() here since the first access should be tested without it. + } + else + { + File.Copy(from, _configFile, overwrite: true); + Trace.Refresh(); + } } [Fact] @@ -195,7 +188,7 @@ public void Refresh_RemoveSource() Assert.Equal(string.Empty, listenerToBeRemoved.Output); listenerToBeRemoved.Clear(); - //mySourceToBeRemoved.Close(); + mySourceToBeRemoved.Close(); } [Fact] @@ -314,7 +307,18 @@ public void Switch_MissingValue_Throws() { Exception e = Assert.Throws(() => CreateAndLoadConfigFile("testhost_Switch_MissingValue_Throws.config")); + Assert.Contains("'value'", e.ToString()); } + + private sealed class PerfCounterSection : ConfigurationElement + { + private static readonly ConfigurationProperty s_propFileMappingSize = new ConfigurationProperty("filemappingsize", typeof(int), 524288, ConfigurationPropertyOptions.None); + private static readonly ConfigurationPropertyCollection s_properties = new ConfigurationPropertyCollection { s_propFileMappingSize }; + + [ConfigurationProperty("filemappingsize", DefaultValue = 524288)] + public int FileMappingSize => (int)this[s_propFileMappingSize]; + protected override ConfigurationPropertyCollection Properties => s_properties; + } } } From bb6f2325796a2c6e3ba9ee008fc50f4ad16cb5f8 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Wed, 10 Aug 2022 11:51:00 -0500 Subject: [PATCH 7/9] Revert "Fix System.Diagnostics.PerformanceCounter diag overlap" This reverts commit a5ac25d24200ca0e6febfcaaba0d95f4bba30791. --- ...stem.Configuration.ConfigurationManager.cs | 15 ++---- ....Configuration.ConfigurationManager.csproj | 3 +- ...uration.ConfigurationManager.netcoreapp.cs | 13 ----- ....Configuration.ConfigurationManager.csproj | 6 +-- .../Diagnostics/SystemDiagnosticsSection.cs | 36 +++++++++---- .../SystemDiagnosticsSection.netcoreapp.cs | 40 --------------- .../System/Diagnostics/TraceConfiguration.cs | 10 ++-- ...stem.Diagnostics.PerformanceCounter.csproj | 4 +- .../Diagnostics/DiagnosticsConfiguration.cs | 4 +- .../System/Diagnostics/PerfCounterSection.cs} | 6 +-- .../Diagnostics/SystemDiagnosticsSection.cs | 18 +++++++ .../StringTraceListener.cs | 5 ++ ...iagnostics.TraceSource.Config.Tests.csproj | 2 +- .../TraceSourceWithConfigurationTests.cs | 50 +++++++++---------- 14 files changed, 93 insertions(+), 119 deletions(-) delete mode 100644 src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs delete mode 100644 src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.netcoreapp.cs rename src/libraries/{System.Configuration.ConfigurationManager/src/System/Diagnostics/PerfCounterSettings.cs => System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs} (72%) create mode 100644 src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs index c55756b576a0ee..7c754beb6ae33f 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs @@ -1578,22 +1578,15 @@ public ProviderException(string message) { } public ProviderException(string message, System.Exception innerException) { } } } +#if NET7_0_OR_GREATER namespace System.Diagnostics { - public sealed partial class PerfCounterSettings : System.Configuration.ConfigurationElement + public static partial class TraceConfiguration { - public PerfCounterSettings() { } - public int FileMappingSize { get { throw null; } } - protected override System.Configuration.ConfigurationPropertyCollection Properties { get { throw null; } } - } - public sealed partial class SystemDiagnosticsSection : System.Configuration.ConfigurationSection - { - public SystemDiagnosticsSection() { } - public System.Diagnostics.PerfCounterSettings PerfCounterSettings { get { throw null; } } - protected override System.Configuration.ConfigurationPropertyCollection Properties { get { throw null; } } - protected override void InitializeDefault() { } + public static void Register() { } } } +#endif namespace System.Drawing.Configuration { public sealed partial class SystemDrawingSection : System.Configuration.ConfigurationSection diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj index 6e0f157ee6f2e3..58e634cc9634ee 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) disable @@ -8,7 +8,6 @@ - diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs deleted file mode 100644 index 3fffb8cd3951d8..00000000000000 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs +++ /dev/null @@ -1,13 +0,0 @@ -// 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() { } - } -} diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj index 387d0b664286b6..2badd2c37adec6 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj @@ -257,8 +257,6 @@ System.Configuration.ConfigurationManager - - @@ -271,13 +269,13 @@ System.Configuration.ConfigurationManager - + - + diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs index 9a8a3d64e09bb7..e4b5af069fe35b 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.cs @@ -1,27 +1,43 @@ -// Licensed to the .NET Foundation under one or more agreements. +// 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; namespace System.Diagnostics { - public sealed partial class SystemDiagnosticsSection : ConfigurationSection + internal sealed class SystemDiagnosticsSection : ConfigurationSection { private static readonly ConfigurationPropertyCollection s_properties = new(); - private static readonly ConfigurationProperty s_propPerfCounters = new ConfigurationProperty("performanceCounters", typeof(PerfCounterSettings), new PerfCounterSettings(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSources = new("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSharedListeners = new("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propSwitches = new("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationProperty s_propTrace = new("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); static SystemDiagnosticsSection() { - s_properties.Add(s_propPerfCounters); - -#if NET7_0_OR_GREATER - SystemDiagnosticsSectionNetCoreApp(); -#endif + s_properties.Add(s_propSources); + s_properties.Add(s_propSharedListeners); + s_properties.Add(s_propSwitches); + s_properties.Add(s_propTrace); } protected internal override ConfigurationPropertyCollection Properties => s_properties; - [ConfigurationProperty("performanceCounters")] - public PerfCounterSettings PerfCounterSettings => (PerfCounterSettings)base[s_propPerfCounters]; + [ConfigurationProperty("sources")] + public SourceElementsCollection Sources => (SourceElementsCollection)base[s_propSources]; + + [ConfigurationProperty("sharedListeners")] + public ListenerElementsCollection SharedListeners => (ListenerElementsCollection)base[s_propSharedListeners]; + + [ConfigurationProperty("switches")] + public SwitchElementsCollection Switches => (SwitchElementsCollection)base[s_propSwitches]; + + [ConfigurationProperty("trace")] + public TraceSection Trace => (TraceSection)base[s_propTrace]; + + protected internal override void InitializeDefault() + { + Trace.Listeners?.InitializeDefaultInternal(); + } } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.netcoreapp.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.netcoreapp.cs deleted file mode 100644 index 0757a137df8321..00000000000000 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/SystemDiagnosticsSection.netcoreapp.cs +++ /dev/null @@ -1,40 +0,0 @@ -// 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; - -namespace System.Diagnostics -{ - public partial class SystemDiagnosticsSection - { - private static readonly ConfigurationProperty s_propSources = new("sources", typeof(SourceElementsCollection), new SourceElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propSharedListeners = new("sharedListeners", typeof(SharedListenerElementsCollection), new SharedListenerElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propSwitches = new("switches", typeof(SwitchElementsCollection), new SwitchElementsCollection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationProperty s_propTrace = new("trace", typeof(TraceSection), new TraceSection(), ConfigurationPropertyOptions.None); - - private static void SystemDiagnosticsSectionNetCoreApp() - { - s_properties.Add(s_propSources); - s_properties.Add(s_propSharedListeners); - s_properties.Add(s_propSwitches); - s_properties.Add(s_propTrace); - } - - [ConfigurationProperty("sources")] - internal SourceElementsCollection Sources => (SourceElementsCollection)base[s_propSources]; - - [ConfigurationProperty("sharedListeners")] - internal ListenerElementsCollection SharedListeners => (ListenerElementsCollection)base[s_propSharedListeners]; - - [ConfigurationProperty("switches")] - internal SwitchElementsCollection Switches => (SwitchElementsCollection)base[s_propSwitches]; - - [ConfigurationProperty("trace")] - internal TraceSection Trace => (TraceSection)base[s_propTrace]; - - protected internal override void InitializeDefault() - { - Trace.Listeners?.InitializeDefaultInternal(); - } - } -} diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs index 8c21cb6473a264..d02b5a006b3da4 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/TraceConfiguration.cs @@ -150,13 +150,13 @@ private static void ConfigureTraceSettings() { // Ported from https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,06360b4de5e221c2, https://referencesource.microsoft.com/#System/compmod/system/diagnostics/TraceInternal.cs,37 - TraceSection traceSettings = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace; + TraceSection traceSection = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace; - if (traceSettings != null) + if (traceSection != null) { - Trace.UseGlobalLock = traceSettings.UseGlobalLock; - Trace.AutoFlush = traceSettings.AutoFlush; - Trace.IndentSize = traceSettings.IndentSize; + Trace.UseGlobalLock = traceSection.UseGlobalLock; + Trace.AutoFlush = traceSection.AutoFlush; + Trace.IndentSize = traceSection.IndentSize; ListenerElementsCollection listeners = DiagnosticsConfiguration.SystemDiagnosticsSection?.Trace.Listeners; if (listeners != null) diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj index b1fe08e2d0a23c..8a800527bb10bb 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true @@ -29,6 +29,7 @@ System.Diagnostics.PerformanceCounter + Component @@ -40,6 +41,7 @@ System.Diagnostics.PerformanceCounter + diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs index 9eddbb2885b56e..ad942e734183d1 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs @@ -32,9 +32,9 @@ internal static int PerformanceCountersFileMappingSize Initialize(); SystemDiagnosticsSection configSectionSav = s_configSection; - if (configSectionSav != null && configSectionSav.PerfCounterSettings != null) + if (configSectionSav != null && configSectionSav.PerfCounters != null) { - int size = configSectionSav.PerfCounterSettings.FileMappingSize; + int size = configSectionSav.PerfCounters.FileMappingSize; if (size < SharedPerformanceCounter.MinCountersFileMappingSize) size = SharedPerformanceCounter.MinCountersFileMappingSize; diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/PerfCounterSettings.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs similarity index 72% rename from src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/PerfCounterSettings.cs rename to src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs index cea7b4673d03d2..7169e201f65e33 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Diagnostics/PerfCounterSettings.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs @@ -1,11 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// 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; namespace System.Diagnostics { - public sealed class PerfCounterSettings : ConfigurationElement + internal sealed class PerfCounterSection : ConfigurationElement { private static readonly ConfigurationProperty s_propFileMappingSize = new ConfigurationProperty("filemappingsize", typeof(int), 524288, ConfigurationPropertyOptions.None); private static readonly ConfigurationPropertyCollection s_properties = new ConfigurationPropertyCollection { s_propFileMappingSize }; @@ -13,6 +13,6 @@ public sealed class PerfCounterSettings : ConfigurationElement [ConfigurationProperty("filemappingsize", DefaultValue = 524288)] public int FileMappingSize => (int)this[s_propFileMappingSize]; - protected internal override ConfigurationPropertyCollection Properties => s_properties; + protected override ConfigurationPropertyCollection Properties => s_properties; } } diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs new file mode 100644 index 00000000000000..aa40d83aed03ae --- /dev/null +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs @@ -0,0 +1,18 @@ +// 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; + +namespace System.Diagnostics +{ + internal sealed class SystemDiagnosticsSection : ConfigurationSection + { + private static readonly ConfigurationProperty s_propPerfCounters = new ConfigurationProperty("performanceCounters", typeof(PerfCounterSection), new PerfCounterSection(), ConfigurationPropertyOptions.None); + private static readonly ConfigurationPropertyCollection s_properties = new ConfigurationPropertyCollection { s_propPerfCounters }; + + [ConfigurationProperty("performanceCounters")] + public PerfCounterSection PerfCounters => (PerfCounterSection)base[s_propPerfCounters]; + + protected override ConfigurationPropertyCollection Properties => s_properties; + } +} diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs index efd8d8283bb0cb..94d3e06e45a5ad 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs @@ -1,7 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; namespace System.Diagnostics.TraceSourceConfigTests { diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj index 1ca83850ed6a54..9c0a839c203afc 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj @@ -41,6 +41,6 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs index fda40c2f21e0b9..f59f8440c3f15c 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs @@ -1,36 +1,43 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; using System.Configuration; using System.IO; -using System.Reflection; +using System.Linq; +using System.Text; +using System.Threading.Tasks; using Xunit; namespace System.Diagnostics.TraceSourceConfigTests { - // Note that parallelization is disabled due to file access as each test replaces the single config file on disk. public class ConfigurationTests { private static volatile string? _configFile = null; + private static string ConfigFile + { + get + { + if (_configFile == null) + { + Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + _configFile = Path.GetFileName(config.FilePath); + } + + return _configFile; + } + } + private static void CreateAndLoadConfigFile(string filename) { Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); string dir = Path.GetDirectoryName(config.FilePath); string from = Path.Combine(dir, filename); - - if (_configFile == null) - { - _configFile = Path.GetFileName(config.FilePath); - File.Copy(from, _configFile, overwrite: true); - TraceConfiguration.Register(); - // Do not call Trace.Refresh() here since the first access should be tested without it. - } - else - { - File.Copy(from, _configFile, overwrite: true); - Trace.Refresh(); - } + File.Copy(from, ConfigFile, overwrite: true); + TraceConfiguration.Register(); + Trace.Refresh(); } [Fact] @@ -188,7 +195,7 @@ public void Refresh_RemoveSource() Assert.Equal(string.Empty, listenerToBeRemoved.Output); listenerToBeRemoved.Clear(); - mySourceToBeRemoved.Close(); + //mySourceToBeRemoved.Close(); } [Fact] @@ -307,18 +314,7 @@ public void Switch_MissingValue_Throws() { Exception e = Assert.Throws(() => CreateAndLoadConfigFile("testhost_Switch_MissingValue_Throws.config")); - Assert.Contains("'value'", e.ToString()); } - - private sealed class PerfCounterSection : ConfigurationElement - { - private static readonly ConfigurationProperty s_propFileMappingSize = new ConfigurationProperty("filemappingsize", typeof(int), 524288, ConfigurationPropertyOptions.None); - private static readonly ConfigurationPropertyCollection s_properties = new ConfigurationPropertyCollection { s_propFileMappingSize }; - - [ConfigurationProperty("filemappingsize", DefaultValue = 524288)] - public int FileMappingSize => (int)this[s_propFileMappingSize]; - protected override ConfigurationPropertyCollection Properties => s_properties; - } } } From 41c8997c338684e2553f05bf09e1843a527f0d42 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Wed, 10 Aug 2022 13:12:32 -0500 Subject: [PATCH 8/9] Remove code for perf counter filemappingsize config entry since it was broken --- ...stem.Diagnostics.PerformanceCounter.csproj | 2 - .../Diagnostics/DiagnosticsConfiguration.cs | 97 ++----------------- .../System/Diagnostics/PerfCounterSection.cs | 18 ---- .../Diagnostics/SystemDiagnosticsSection.cs | 18 ---- 4 files changed, 8 insertions(+), 127 deletions(-) delete mode 100644 src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs delete mode 100644 src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj index 8a800527bb10bb..a0dbb8e208bd40 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj @@ -29,7 +29,6 @@ System.Diagnostics.PerformanceCounter - Component @@ -41,7 +40,6 @@ System.Diagnostics.PerformanceCounter - diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs index ad942e734183d1..8343a152a7cd1f 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/DiagnosticsConfiguration.cs @@ -1,103 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Reflection; -using System.Configuration; - namespace System.Diagnostics { - internal enum InitState - { - NotInitialized, - Initializing, - Initialized - } - internal static class DiagnosticsConfiguration { - private static volatile SystemDiagnosticsSection s_configSection; - private static volatile InitState s_initState = InitState.NotInitialized; - internal static int PerformanceCountersFileMappingSize { get { - for (int retryCount = 0; !CanInitialize() && retryCount <= 5; ++retryCount) - { - if (retryCount == 5) - return SharedPerformanceCounter.DefaultCountersFileMappingSize; - - System.Threading.Thread.Sleep(200); - } - - Initialize(); - SystemDiagnosticsSection configSectionSav = s_configSection; - if (configSectionSav != null && configSectionSav.PerfCounters != null) - { - int size = configSectionSav.PerfCounters.FileMappingSize; - if (size < SharedPerformanceCounter.MinCountersFileMappingSize) - size = SharedPerformanceCounter.MinCountersFileMappingSize; - - if (size > SharedPerformanceCounter.MaxCountersFileMappingSize) - size = SharedPerformanceCounter.MaxCountersFileMappingSize; - - return size; - } - else - return SharedPerformanceCounter.DefaultCountersFileMappingSize; - } - } - - internal static string ConfigFilePath - { - get - { - Initialize(); - SystemDiagnosticsSection configSectionSav = s_configSection; - return configSectionSav?.ElementInformation?.Source ?? string.Empty; - } - } - - private static SystemDiagnosticsSection GetConfigSection() - { - SystemDiagnosticsSection configSection = (SystemDiagnosticsSection)ConfigurationManager.GetSection("system.diagnostics"); - return configSection; - } - - internal static bool CanInitialize() - { - bool setConfigurationSystemInProgress = (bool)(typeof(ConfigurationManager).GetProperty("SetConfigurationSystemInProgress", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null)); - return (s_initState != InitState.Initializing) && !setConfigurationSystemInProgress; - } - - internal static void Initialize() - { - // Initialize() is also called by other components outside of Trace (such as PerformanceCounter) - // as a result using one lock for this critical section and another for Trace API critical sections - // (such as Trace.WriteLine) could potentially lead to deadlock between 2 threads that are - // executing these critical sections (and consequently obtaining the 2 locks) in the reverse order. - // Using the same lock for DiagnosticsConfiguration as well as TraceInternal avoids this issue. - // Sequential locks on TraceInternal.critSec by the same thread is a non issue for this critical section. - lock (TraceInternal.critSec) - { - // 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. - bool setConfigurationSystemInProgress = (bool)(typeof(ConfigurationManager).GetProperty("SetConfigurationSystemInProgress", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null)); - if (s_initState != InitState.NotInitialized || setConfigurationSystemInProgress) - { - return; - } - - s_initState = InitState.Initializing; // used for preventing recursion - try - { - s_configSection = GetConfigSection(); - } - finally - { - s_initState = InitState.Initialized; - } + // This is supposed to read the filemappingsize value from the System.Diagnostics section in the app config file, but it was + // discovered it was broken so the code was removed. + // Removing the code was necessary to support TraceSource-based config entries which also need to read the System.Diagnostics + // section. The code as also removed to support using performance counters in general (without even using the filemappingsize entry) + // since just the presence of a System.Diagnostics section itself caused the removed code to throw so many performance counter + // scenarios would throw when having any TraceSource-related entries in the System.Diagnostics section. + // See https://github.com/dotnet/runtime/issues/73706. + return SharedPerformanceCounter.DefaultCountersFileMappingSize; } } } diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs deleted file mode 100644 index 7169e201f65e33..00000000000000 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerfCounterSection.cs +++ /dev/null @@ -1,18 +0,0 @@ -// 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; - -namespace System.Diagnostics -{ - internal sealed class PerfCounterSection : ConfigurationElement - { - private static readonly ConfigurationProperty s_propFileMappingSize = new ConfigurationProperty("filemappingsize", typeof(int), 524288, ConfigurationPropertyOptions.None); - private static readonly ConfigurationPropertyCollection s_properties = new ConfigurationPropertyCollection { s_propFileMappingSize }; - - [ConfigurationProperty("filemappingsize", DefaultValue = 524288)] - public int FileMappingSize => (int)this[s_propFileMappingSize]; - - protected override ConfigurationPropertyCollection Properties => s_properties; - } -} diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs deleted file mode 100644 index aa40d83aed03ae..00000000000000 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SystemDiagnosticsSection.cs +++ /dev/null @@ -1,18 +0,0 @@ -// 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; - -namespace System.Diagnostics -{ - internal sealed class SystemDiagnosticsSection : ConfigurationSection - { - private static readonly ConfigurationProperty s_propPerfCounters = new ConfigurationProperty("performanceCounters", typeof(PerfCounterSection), new PerfCounterSection(), ConfigurationPropertyOptions.None); - private static readonly ConfigurationPropertyCollection s_properties = new ConfigurationPropertyCollection { s_propPerfCounters }; - - [ConfigurationProperty("performanceCounters")] - public PerfCounterSection PerfCounters => (PerfCounterSection)base[s_propPerfCounters]; - - protected override ConfigurationPropertyCollection Properties => s_properties; - } -} From 939a0335f6eff8625617b72f15c5cf846c04d83c Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Wed, 10 Aug 2022 13:37:09 -0500 Subject: [PATCH 9/9] Feedback (non-functional) --- ...stem.Configuration.ConfigurationManager.cs | 9 ---- ....Configuration.ConfigurationManager.csproj | 1 + ...uration.ConfigurationManager.netcoreapp.cs | 13 ++++++ ...guration.ConfigurationManager.Tests.csproj | 4 +- .../InitializingSwitchEventArgs.cs | 2 +- .../InitializingTraceSourceEventArgs.cs | 2 +- .../src/System/Diagnostics/TraceListener.cs | 5 +-- .../src/System/Diagnostics/TraceUtils.cs | 1 + .../StringTraceListener.cs | 5 --- ...iagnostics.TraceSource.Config.Tests.csproj | 39 +++++------------ .../TraceSourceWithConfigurationTests.cs | 42 ++++++++----------- ...ystem.Diagnostics.TraceSource.Tests.csproj | 2 +- 12 files changed, 50 insertions(+), 75 deletions(-) create mode 100644 src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs index 7c754beb6ae33f..6d21ab559b502d 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.cs @@ -1578,15 +1578,6 @@ public ProviderException(string message) { } public ProviderException(string message, System.Exception innerException) { } } } -#if NET7_0_OR_GREATER -namespace System.Diagnostics -{ - public static partial class TraceConfiguration - { - public static void Register() { } - } -} -#endif namespace System.Drawing.Configuration { public sealed partial class SystemDrawingSection : System.Configuration.ConfigurationSection diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj index 58e634cc9634ee..82439a81b78185 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.csproj @@ -8,6 +8,7 @@ + diff --git a/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs new file mode 100644 index 00000000000000..3fffb8cd3951d8 --- /dev/null +++ b/src/libraries/System.Configuration.ConfigurationManager/ref/System.Configuration.ConfigurationManager.netcoreapp.cs @@ -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() { } + } +} diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj index 40dd04ac683659..bccb8f7e2fb189 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj @@ -1,4 +1,4 @@ - + true $(NetCoreAppCurrent);$(NetFrameworkMinimum) @@ -98,7 +98,7 @@ - + diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs index 49832eca314e1b..651bfd29fb0c77 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingSwitchEventArgs.cs @@ -4,7 +4,7 @@ namespace System.Diagnostics { /// - /// Provides data for the event. + /// Provides data for the event. /// public sealed class InitializingSwitchEventArgs : EventArgs { diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs index c66a2c308905b7..b4b3aac66ac5cc 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/InitializingTraceSourceEventArgs.cs @@ -4,7 +4,7 @@ namespace System.Diagnostics { /// - /// Provides data for the event. + /// Provides data for the event. /// public sealed class InitializingTraceSourceEventArgs : EventArgs { diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs index 0cd7be16db6b0a..e7208255dcb478 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs @@ -42,10 +42,7 @@ protected TraceListener(string? name) _listenerName = name; } - public StringDictionary Attributes - { - get => _attributes ??= new StringDictionary(); - } + public StringDictionary Attributes => _attributes ??= new StringDictionary(); /// /// Gets or sets a name for this . diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs index f02be73226fdc7..62fde9e9cfbf7d 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceUtils.cs @@ -1,5 +1,6 @@ // 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.IO; using System.Reflection; diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs index 94d3e06e45a5ad..efd8d8283bb0cb 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/StringTraceListener.cs @@ -1,12 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace System.Diagnostics.TraceSourceConfigTests { diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj index 9c0a839c203afc..cd36a59ecae62a 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/System.Diagnostics.TraceSource.Config.Tests.csproj @@ -12,35 +12,18 @@ - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - + - + \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs index f59f8440c3f15c..0f0124469a9a13 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Config.Tests/TraceSourceWithConfigurationTests.cs @@ -1,43 +1,36 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.Configuration; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Reflection; using Xunit; namespace System.Diagnostics.TraceSourceConfigTests { + // Note that parallelization is disabled due to file access as each test replaces the single config file on disk. public class ConfigurationTests { private static volatile string? _configFile = null; - private static string ConfigFile - { - get - { - if (_configFile == null) - { - Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); - _configFile = Path.GetFileName(config.FilePath); - } - - return _configFile; - } - } - private static void CreateAndLoadConfigFile(string filename) { Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); string dir = Path.GetDirectoryName(config.FilePath); string from = Path.Combine(dir, filename); - File.Copy(from, ConfigFile, overwrite: true); - TraceConfiguration.Register(); - Trace.Refresh(); + + if (_configFile == null) + { + _configFile = Path.GetFileName(config.FilePath); + File.Copy(from, _configFile, overwrite: true); + TraceConfiguration.Register(); + // Do not call Trace.Refresh() here since the first access should be tested without it. + } + else + { + File.Copy(from, _configFile, overwrite: true); + Trace.Refresh(); + } } [Fact] @@ -195,7 +188,7 @@ public void Refresh_RemoveSource() Assert.Equal(string.Empty, listenerToBeRemoved.Output); listenerToBeRemoved.Clear(); - //mySourceToBeRemoved.Close(); + mySourceToBeRemoved.Close(); } [Fact] @@ -312,8 +305,9 @@ public void AllTypes() [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public void Switch_MissingValue_Throws() { - Exception e = Assert.Throws(() => + Exception e = Assert.Throws(() => CreateAndLoadConfigFile("testhost_Switch_MissingValue_Throws.config")); + Assert.Contains("'value'", e.ToString()); } } diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj index c2276c55544508..cf88f62d327e7e 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/System.Diagnostics.TraceSource.Tests.csproj @@ -25,6 +25,6 @@ - + \ No newline at end of file