From e41a05184c0e47320f4330cb1014db6483245090 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Tue, 2 Jul 2024 21:29:29 +0200 Subject: [PATCH 1/8] If one of the loggers is enabled the entire logger abstraction is enabled --- .../Amazon.Runtime/Internal/Util/Logger.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs index b50c525b6dd7..781d16954611 100644 --- a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs +++ b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs @@ -80,6 +80,23 @@ private void ConfigureLoggers() il.IsEnabled = (logging & LoggingOptions.Console) == LoggingOptions.Console; if (il is InternalSystemDiagnosticsLogger) il.IsEnabled = (logging & LoggingOptions.SystemDiagnostics) == LoggingOptions.SystemDiagnostics; + + if (!IsEnabled) + { + IsEnabled = il.IsEnabled; + } + if (!IsErrorEnabled) + { + IsErrorEnabled = il.IsErrorEnabled; + } + if (!IsInfoEnabled) + { + IsInfoEnabled = il.IsInfoEnabled; + } + if (!IsDebugEnabled) + { + IsDebugEnabled = il.IsDebugEnabled; + } } } @@ -113,6 +130,14 @@ public static void ClearLoggerCache() #endregion + internal bool IsEnabled { get; private set; } + + internal virtual bool IsErrorEnabled { get; private set; } + + internal virtual bool IsDebugEnabled { get; private set; } + + internal virtual bool IsInfoEnabled { get; private set; } + #region Logging methods public void Flush() From 096683276a433a17a5a797a059ba023dd6f347bd Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Tue, 2 Jul 2024 21:29:47 +0200 Subject: [PATCH 2/8] Do not allocate debug information when not necessary --- sdk/src/Core/Amazon.Util/AWSSDKUtils.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sdk/src/Core/Amazon.Util/AWSSDKUtils.cs b/sdk/src/Core/Amazon.Util/AWSSDKUtils.cs index 773ad7449c16..688452b85a43 100644 --- a/sdk/src/Core/Amazon.Util/AWSSDKUtils.cs +++ b/sdk/src/Core/Amazon.Util/AWSSDKUtils.cs @@ -385,11 +385,15 @@ public static string CanonicalizeResourcePathV2(Uri endpoint, string resourcePat string canonicalizedResourcePath = JoinResourcePathSegmentsV2(encodedSegments); // Get the logger each time (it's cached) because we shouldn't store it in a static variable. - Logger.GetLogger(typeof(AWSSDKUtils)).DebugFormat("{0} encoded {1}{2} for canonicalization: {3}", - pathWasPreEncoded ? "Double" : "Single", - resourcePath, - endpoint == null ? "" : " with endpoint " + endpoint.AbsoluteUri, - canonicalizedResourcePath); + var logger = Logger.GetLogger(typeof(AWSSDKUtils)); + if (logger.IsDebugEnabled) + { + logger.DebugFormat("{0} encoded {1}{2} for canonicalization: {3}", + pathWasPreEncoded ? "Double" : "Single", + resourcePath, + endpoint == null ? "" : $" with endpoint {endpoint.AbsoluteUri}", + canonicalizedResourcePath); + } return canonicalizedResourcePath; } From 8cb487f159dde616ed73fd828f4bb47579babf2c Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Tue, 2 Jul 2024 21:53:10 +0200 Subject: [PATCH 3/8] Remove global logger lock --- .../Amazon.Runtime/Internal/Util/Logger.cs | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs index 781d16954611..b88a29e2b8fa 100644 --- a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs +++ b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs @@ -13,6 +13,7 @@ * permissions and limitations under the License. */ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; @@ -20,6 +21,7 @@ using System.Reflection; using System.Text; using System.ComponentModel; +using System.Threading; using Amazon.Runtime; using Amazon.Util.Internal; @@ -31,7 +33,7 @@ namespace Amazon.Runtime.Internal.Util /// public class Logger : ILogger { - private static IDictionary cachedLoggers = new Dictionary(); + private static ConcurrentDictionary> cachedLoggers = new ConcurrentDictionary>(); private List loggers; private static Logger emptyLogger = new Logger(); @@ -46,7 +48,7 @@ private Logger() #endif private Logger(Type type) { - loggers = new List(); + loggers = new List(3); if(!InternalSDKUtils.IsRunningNativeAot()) { @@ -104,25 +106,32 @@ private void ConfigureLoggers() public static Logger GetLogger(Type type) { - if (type == null) throw new ArgumentNullException("type"); + if (type == null) throw new ArgumentNullException(nameof(type)); - Logger l; - lock (cachedLoggers) - { - if (!cachedLoggers.TryGetValue(type, out l)) - { - l = new Logger(type); - cachedLoggers[type] = l; - } - } - return l; + // Use a lazy initialization to ensure that we only create a logger for a given type once because + // the constructor does some heavy lifting including setting up event listeners. + var lazyLogger = cachedLoggers.GetOrAdd(type, static t => new Lazy(() => new Logger(t))); + return lazyLogger.Value; } public static void ClearLoggerCache() { - lock (cachedLoggers) + var newLoggerCache = new ConcurrentDictionary>(); + ConcurrentDictionary> oldLoggerCache; + + do { - cachedLoggers = new Dictionary(); + oldLoggerCache = cachedLoggers; + } while (Interlocked.CompareExchange(ref cachedLoggers, newLoggerCache, oldLoggerCache) != oldLoggerCache); + + // Unregister all the loggers in the old cache + foreach (var item in oldLoggerCache) + { + var lazyLogger = item.Value; + if (lazyLogger.IsValueCreated) + { + lazyLogger.Value.Unregister(); + } } } @@ -138,6 +147,11 @@ public static void ClearLoggerCache() internal virtual bool IsInfoEnabled { get; private set; } + internal void Unregister() + { + AWSConfigs.PropertyChanged -= ConfigsChanged; + } + #region Logging methods public void Flush() From 553409f82b819ca81ff04d98fa032fa78f139fa4 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Tue, 2 Jul 2024 21:54:17 +0200 Subject: [PATCH 4/8] Cleanup --- sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs index b88a29e2b8fa..d0bdd841bae6 100644 --- a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs +++ b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs @@ -15,14 +15,8 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Globalization; -using System.Reflection; -using System.Text; using System.ComponentModel; using System.Threading; -using Amazon.Runtime; using Amazon.Util.Internal; namespace Amazon.Runtime.Internal.Util From 282ec1967f65a4ba3d3219a4543c6658ce83e2d0 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Tue, 2 Jul 2024 21:56:27 +0200 Subject: [PATCH 5/8] Satisfy null constraint eventhough this path cannot be hit --- sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs index d0bdd841bae6..fd9564ef27f7 100644 --- a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs +++ b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs @@ -16,6 +16,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; +using System.Linq; using System.Threading; using Amazon.Util.Internal; @@ -119,7 +120,7 @@ public static void ClearLoggerCache() } while (Interlocked.CompareExchange(ref cachedLoggers, newLoggerCache, oldLoggerCache) != oldLoggerCache); // Unregister all the loggers in the old cache - foreach (var item in oldLoggerCache) + foreach (var item in oldLoggerCache ?? Enumerable.Empty>>()) { var lazyLogger = item.Value; if (lazyLogger.IsValueCreated) From b19893f6a894c38f4a3eb7706bd2227062ba2d46 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Tue, 2 Jul 2024 21:57:49 +0200 Subject: [PATCH 6/8] AutoProperty --- sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs index fd9564ef27f7..a3c3b049e3db 100644 --- a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs +++ b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs @@ -30,7 +30,6 @@ public class Logger : ILogger { private static ConcurrentDictionary> cachedLoggers = new ConcurrentDictionary>(); private List loggers; - private static Logger emptyLogger = new Logger(); private Logger() { @@ -130,7 +129,7 @@ public static void ClearLoggerCache() } } - public static Logger EmptyLogger { get { return emptyLogger; } } + public static Logger EmptyLogger { get; } = new Logger(); #endregion From d97d1e8d557bf54cf7ab7c16dee47475fe9e3714 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Tue, 2 Jul 2024 22:09:01 +0200 Subject: [PATCH 7/8] use exact size --- sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs index a3c3b049e3db..4b3fcfd87430 100644 --- a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs +++ b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs @@ -42,15 +42,18 @@ private Logger() #endif private Logger(Type type) { - loggers = new List(3); - if(!InternalSDKUtils.IsRunningNativeAot()) { + loggers = new List(3); #pragma warning disable InternalLog4netLogger log4netLogger = new InternalLog4netLogger(type); loggers.Add(log4netLogger); #pragma warning restore } + else + { + loggers = new List(2); + } loggers.Add(new InternalConsoleLogger(type)); InternalSystemDiagnosticsLogger sdLogger = new InternalSystemDiagnosticsLogger(type); From ffca58cfbcb8e4d3fdad6f3bab0be69ed3c5310a Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Tue, 2 Jul 2024 22:09:55 +0200 Subject: [PATCH 8/8] Remove unnecessary locals --- sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs index 4b3fcfd87430..0b5b678bbeaa 100644 --- a/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs +++ b/sdk/src/Core/Amazon.Runtime/Internal/Util/Logger.cs @@ -46,8 +46,7 @@ private Logger(Type type) { loggers = new List(3); #pragma warning disable - InternalLog4netLogger log4netLogger = new InternalLog4netLogger(type); - loggers.Add(log4netLogger); + loggers.Add(new InternalLog4netLogger(type)); #pragma warning restore } else @@ -56,8 +55,7 @@ private Logger(Type type) } loggers.Add(new InternalConsoleLogger(type)); - InternalSystemDiagnosticsLogger sdLogger = new InternalSystemDiagnosticsLogger(type); - loggers.Add(sdLogger); + loggers.Add(new InternalSystemDiagnosticsLogger(type)); ConfigureLoggers(); AWSConfigs.PropertyChanged += ConfigsChanged; }