Browse Source

Cleanup conditional logging API.

Dariusz Komosinski 6 years ago
parent
commit
068b73750b

+ 20 - 29
src/Avalonia.Base/AvaloniaObject.cs

@@ -333,12 +333,11 @@ namespace Avalonia
                     throw new ArgumentException($"The property {property.Name} is readonly.");
                 }
 
-                if (Logger.IsEnabled(LogEventLevel.Verbose))
+                if (Logger.TryGetLogger(LogEventLevel.Verbose, out var logger))
                 {
                     var description = GetDescription(source);
 
-                    Logger.Log(
-                        LogEventLevel.Verbose,
+                    logger.Log(
                         LogArea.Property,
                         this,
                         "Bound {Property} to {Binding} with priority LocalValue",
@@ -355,12 +354,11 @@ namespace Avalonia
             }
             else
             {
-                if (Logger.IsEnabled(LogEventLevel.Verbose))
+                if (Logger.TryGetLogger(LogEventLevel.Verbose, out var logger))
                 {
                     var description = GetDescription(source);
 
-                    Logger.Log(
-                        LogEventLevel.Verbose,
+                    logger.Log(
                         LogArea.Property,
                         this,
                         "Bound {Property} to {Binding} with priority {Priority}",
@@ -416,18 +414,14 @@ namespace Avalonia
             {
                 RaisePropertyChanged(property, oldValue, newValue, (BindingPriority)priority);
 
-                if (Logger.IsEnabled(LogEventLevel.Verbose))
-                {
-                    Logger.Log(
-                        LogEventLevel.Verbose,
-                        LogArea.Property,
-                        this,
-                        "{Property} changed from {$Old} to {$Value} with priority {Priority}",
-                        property,
-                        oldValue,
-                        newValue,
-                        (BindingPriority)priority);
-                }
+                Logger.TryGetLogger(LogEventLevel.Verbose)?.Log(
+                    LogArea.Property,
+                    this,
+                    "{Property} changed from {$Old} to {$Value} with priority {Priority}",
+                    property,
+                    oldValue,
+                    newValue,
+                    (BindingPriority)priority);
             }
         }
         
@@ -826,19 +820,16 @@ namespace Avalonia
         /// <param name="priority">The priority.</param>
         private void LogPropertySet(AvaloniaProperty property, object value, BindingPriority priority)
         {
-            if (!Logger.IsEnabled(LogEventLevel.Verbose))
+            if (Logger.TryGetLogger(LogEventLevel.Verbose, out var logger))
             {
-                return;
+                logger.Log(
+                    LogArea.Property,
+                    this,
+                    "Set {Property} to {$Value} with priority {Priority}",
+                    property,
+                    value,
+                    priority);
             }
-
-            Logger.Log(
-                LogEventLevel.Verbose,
-                LogArea.Property,
-                this,
-                "Set {Property} to {$Value} with priority {Priority}",
-                property,
-                value,
-                priority);
         }
 
         private class DirectBindingSubscription : IObserver<object>, IDisposable

+ 30 - 0
src/Avalonia.Base/Logging/Logger.cs

@@ -25,6 +25,36 @@ namespace Avalonia.Logging
             return Sink?.IsEnabled(level) == true;
         }
 
+        /// <summary>
+        /// Returns parametrized logging sink if given log level is enabled.
+        /// </summary>
+        /// <param name="level">The log event level.</param>
+        /// <returns>Log sink or <see langword="null"/> if log level is not enabled.</returns>
+        public static ParametrizedLogger? TryGetLogger(LogEventLevel level)
+        {
+            if (!IsEnabled(level))
+            {
+                return null;
+            }
+
+            return new ParametrizedLogger(Sink, level);
+        }
+
+        /// <summary>
+        /// Returns parametrized logging sink if given log level is enabled.
+        /// </summary>
+        /// <param name="level">The log event level.</param>
+        /// <param name="outLogger">Log sink that is valid only if method returns <see langword="true"/>.</param>
+        /// <returns><see langword="true"/> if logger was obtained successfully.</returns>
+        public static bool TryGetLogger(LogEventLevel level, out ParametrizedLogger outLogger)
+        {
+            ParametrizedLogger? logger = TryGetLogger(level);
+
+            outLogger = logger.GetValueOrDefault();
+
+            return logger.HasValue;
+        }
+
         /// <summary>
         /// Logs an event.
         /// </summary>

+ 116 - 0
src/Avalonia.Base/Logging/ParametrizedLogger.cs

@@ -0,0 +1,116 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System.Runtime.CompilerServices;
+
+namespace Avalonia.Logging
+{
+    /// <summary>
+    /// Logger sink parametrized for given logging level.
+    /// </summary>
+    public readonly struct ParametrizedLogger
+    {
+        private readonly ILogSink _sink;
+        private readonly LogEventLevel _level;
+
+        public ParametrizedLogger(ILogSink sink, LogEventLevel level)
+        {
+            _sink = sink;
+            _level = level;
+        }
+
+        /// <summary>
+        /// Checks if this logger can be used.
+        /// </summary>
+        public bool IsValid => _sink != null;
+
+        /// <summary>
+        /// Logs an event.
+        /// </summary>
+        /// <param name="area">The area that the event originates.</param>
+        /// <param name="source">The object from which the event originates.</param>
+        /// <param name="messageTemplate">The message template.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public void Log(
+            string area,
+            object source,
+            string messageTemplate)
+        {
+            _sink.Log(_level, area, source, messageTemplate);
+        }
+
+        /// <summary>
+        /// Logs an event.
+        /// </summary>
+        /// <param name="area">The area that the event originates.</param>
+        /// <param name="source">The object from which the event originates.</param>
+        /// <param name="messageTemplate">The message template.</param>
+        /// <param name="propertyValue0">Message property value.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public void Log<T0>(
+            string area,
+            object source,
+            string messageTemplate,
+            T0 propertyValue0)
+        {
+            _sink.Log(_level, area, source, messageTemplate, propertyValue0);
+        }
+
+        /// <summary>
+        /// Logs an event.
+        /// </summary>
+        /// <param name="area">The area that the event originates.</param>
+        /// <param name="source">The object from which the event originates.</param>
+        /// <param name="messageTemplate">The message template.</param>
+        /// <param name="propertyValue0">Message property value.</param>
+        /// <param name="propertyValue1">Message property value.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public void Log<T0, T1>(
+            string area,
+            object source,
+            string messageTemplate,
+            T0 propertyValue0,
+            T1 propertyValue1)
+        {
+            _sink.Log(_level, area, source, messageTemplate, propertyValue0, propertyValue1);
+        }
+
+        /// <summary>
+        /// Logs an event.
+        /// </summary>
+        /// <param name="area">The area that the event originates.</param>
+        /// <param name="source">The object from which the event originates.</param>
+        /// <param name="messageTemplate">The message template.</param>
+        /// <param name="propertyValue0">Message property value.</param>
+        /// <param name="propertyValue1">Message property value.</param>
+        /// <param name="propertyValue2">Message property value.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public void Log<T0, T1, T2>(
+            string area,
+            object source,
+            string messageTemplate,
+            T0 propertyValue0,
+            T1 propertyValue1,
+            T2 propertyValue2)
+        {
+            _sink.Log(_level, area, source, messageTemplate, propertyValue0, propertyValue1, propertyValue2);
+        }
+
+        /// <summary>
+        /// Logs an event.
+        /// </summary>
+        /// <param name="area">The area that the event originates.</param>
+        /// <param name="source">The object from which the event originates.</param>
+        /// <param name="messageTemplate">The message template.</param>
+        /// <param name="propertyValues">The message property values.</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public void Log(
+            string area,
+            object source,
+            string messageTemplate,
+            params object[] propertyValues)
+        {
+            _sink.Log(_level, area, source, messageTemplate, propertyValues);
+        }
+    }
+}