diff --git a/README.md b/README.md index 401ef4e12..65240b4ef 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,10 @@ this.Log().ErrorException("Tried to do a thing and failed", exception); ``` For static methods, `LogHost.Default` can be used as the object to write a log -entry for. +entry for. The Static logger uses a different interface from the main logger to allow capture of additional +caller context as it doesn't have the details of the class instance etc. when compared to the normal logger. +To get the benefit of these you don't need to do much as they are optional parameters at the end of the methods +that are utilised by the compiler\framework. Currently we only capture [CallerMemberName](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callermembernameattribute). ### Available logging adapters diff --git a/src/Splat.Tests/API/ApiApprovalTests.SplatProject.net5.0.approved.txt b/src/Splat.Tests/API/ApiApprovalTests.SplatProject.net5.0.approved.txt index f632d6cea..d5e2f3080 100644 --- a/src/Splat.Tests/API/ApiApprovalTests.SplatProject.net5.0.approved.txt +++ b/src/Splat.Tests/API/ApiApprovalTests.SplatProject.net5.0.approved.txt @@ -418,6 +418,44 @@ namespace Splat object GetService(System.Type serviceType, string contract = null); System.Collections.Generic.IEnumerable GetServices(System.Type serviceType, string contract = null); } + public interface IStaticFullLogger + { + Splat.LogLevel Level { get; } + void Debug([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Write([System.ComponentModel.Localizable(false)] string message, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Write(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Write([System.ComponentModel.Localizable(false)] string message, [System.ComponentModel.Localizable(false)] System.Type type, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Write(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.ComponentModel.Localizable(false)] System.Type type, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + } public static class Locator { public static Splat.IReadonlyDependencyResolver Current { get; } @@ -430,7 +468,7 @@ namespace Splat } public static class LogHost { - public static Splat.IFullLogger Default { get; } + public static Splat.IStaticFullLogger Default { get; } public static Splat.IFullLogger Log(this T logClassInstance) where T : Splat.IEnableLogger { } } @@ -535,6 +573,45 @@ namespace Splat public static System.Drawing.SizeF ScaledBy(this System.Drawing.SizeF value, float factor) { } public static bool WithinEpsilonOf(this System.Drawing.SizeF value, System.Drawing.SizeF other, float epsilon) { } } + public sealed class StaticFullLogger : Splat.IStaticFullLogger + { + public StaticFullLogger(Splat.IFullLogger fullLogger) { } + public Splat.LogLevel Level { get; } + public void Debug(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Write(string message, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Write(System.Exception exception, string message, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Write([System.ComponentModel.Localizable(false)] string message, [System.ComponentModel.Localizable(false)] System.Type type, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Write(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.ComponentModel.Localizable(false)] System.Type type, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + } public static class TargetFrameworkExtensions { public static string GetTargetFrameworkName(this System.Reflection.Assembly assembly) { } @@ -641,6 +718,8 @@ namespace Splat.ApplicationPerformanceMonitoring public static class EnableFeatureUsageTrackingExtensions { public static Splat.ApplicationPerformanceMonitoring.IFeatureUsageTrackingSession FeatureUsageTrackingSession(this Splat.ApplicationPerformanceMonitoring.IEnableFeatureUsageTracking instance, string featureName) { } + public static void WithFeatureUsageTrackingSession(this Splat.ApplicationPerformanceMonitoring.IEnableFeatureUsageTracking instance, string featureName, System.Action action) { } + public static void WithSubFeatureUsageTrackingSession(this Splat.ApplicationPerformanceMonitoring.IFeatureUsageTrackingSession instance, string featureName, System.Action action) { } } public class FuncFeatureUsageTrackingManager : Splat.ApplicationPerformanceMonitoring.IFeatureUsageTrackingManager { diff --git a/src/Splat.Tests/API/ApiApprovalTests.SplatProject.netcoreapp3.1.approved.txt b/src/Splat.Tests/API/ApiApprovalTests.SplatProject.netcoreapp3.1.approved.txt index 614a971bd..bc03fe6e0 100644 --- a/src/Splat.Tests/API/ApiApprovalTests.SplatProject.netcoreapp3.1.approved.txt +++ b/src/Splat.Tests/API/ApiApprovalTests.SplatProject.netcoreapp3.1.approved.txt @@ -418,6 +418,44 @@ namespace Splat object GetService(System.Type serviceType, string contract = null); System.Collections.Generic.IEnumerable GetServices(System.Type serviceType, string contract = null); } + public interface IStaticFullLogger + { + Splat.LogLevel Level { get; } + void Debug([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Debug(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Error(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Fatal(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Info(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn([System.ComponentModel.Localizable(false)] string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Warn(System.IFormatProvider formatProvider, [System.ComponentModel.Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Write([System.ComponentModel.Localizable(false)] string message, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Write(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Write([System.ComponentModel.Localizable(false)] string message, [System.ComponentModel.Localizable(false)] System.Type type, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + void Write(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.ComponentModel.Localizable(false)] System.Type type, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null); + } public static class Locator { public static Splat.IReadonlyDependencyResolver Current { get; } @@ -430,7 +468,7 @@ namespace Splat } public static class LogHost { - public static Splat.IFullLogger Default { get; } + public static Splat.IStaticFullLogger Default { get; } public static Splat.IFullLogger Log(this T logClassInstance) where T : Splat.IEnableLogger { } } @@ -535,6 +573,45 @@ namespace Splat public static System.Drawing.SizeF ScaledBy(this System.Drawing.SizeF value, float factor) { } public static bool WithinEpsilonOf(this System.Drawing.SizeF value, System.Drawing.SizeF other, float epsilon) { } } + public sealed class StaticFullLogger : Splat.IStaticFullLogger + { + public StaticFullLogger(Splat.IFullLogger fullLogger) { } + public Splat.LogLevel Level { get; } + public void Debug(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Debug(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Error(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Fatal(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Info(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(System.Exception exception, string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(string message, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(System.IFormatProvider formatProvider, string message, TArgument argument, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Warn(System.IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Write(string message, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Write(System.Exception exception, string message, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Write([System.ComponentModel.Localizable(false)] string message, [System.ComponentModel.Localizable(false)] System.Type type, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + public void Write(System.Exception exception, [System.ComponentModel.Localizable(false)] string message, [System.ComponentModel.Localizable(false)] System.Type type, Splat.LogLevel logLevel, [System.Runtime.CompilerServices.CallerMemberName] string callerMemberName = null) { } + } public static class TargetFrameworkExtensions { public static string GetTargetFrameworkName(this System.Reflection.Assembly assembly) { } @@ -641,6 +718,8 @@ namespace Splat.ApplicationPerformanceMonitoring public static class EnableFeatureUsageTrackingExtensions { public static Splat.ApplicationPerformanceMonitoring.IFeatureUsageTrackingSession FeatureUsageTrackingSession(this Splat.ApplicationPerformanceMonitoring.IEnableFeatureUsageTracking instance, string featureName) { } + public static void WithFeatureUsageTrackingSession(this Splat.ApplicationPerformanceMonitoring.IEnableFeatureUsageTracking instance, string featureName, System.Action action) { } + public static void WithSubFeatureUsageTrackingSession(this Splat.ApplicationPerformanceMonitoring.IFeatureUsageTrackingSession instance, string featureName, System.Action action) { } } public class FuncFeatureUsageTrackingManager : Splat.ApplicationPerformanceMonitoring.IFeatureUsageTrackingManager { diff --git a/src/Splat.Tests/ApplicationPerformanceMonitoring/EnableFeatureUsageTrackingExtensionsTests.cs b/src/Splat.Tests/ApplicationPerformanceMonitoring/EnableFeatureUsageTrackingExtensionsTests.cs index 70400c487..fd51d1efe 100644 --- a/src/Splat.Tests/ApplicationPerformanceMonitoring/EnableFeatureUsageTrackingExtensionsTests.cs +++ b/src/Splat.Tests/ApplicationPerformanceMonitoring/EnableFeatureUsageTrackingExtensionsTests.cs @@ -100,5 +100,49 @@ public void SubFeatureHandlesOnException() } } } + + /// + /// Unit tests for the WithFeatureUsageTrackingSession Method. + /// + public sealed class WithFeatureUsageTrackingSessionMethod + { + /// + /// Test to ensure a default feature usage tracking session is set up. + /// + [Fact] + public void HandlesAction() + { + var instance = new TestObjectThatSupportsFeatureUsageTracking(); + var handled = false; + + instance.WithFeatureUsageTrackingSession( + "FeatureName", + _ => handled = true); + + Assert.True(handled); + } + } + + /// + /// Unit tests for the WithSubFeatureUsageTrackingSession Method. + /// + public sealed class WithSubFeatureUsageTrackingSessionMethod + { + /// + /// Test to ensure a default feature usage tracking session is set up. + /// + [Fact] + public void HandlesAction() + { + var instance = new TestObjectThatSupportsFeatureUsageTracking(); + var handled = false; + + instance.WithFeatureUsageTrackingSession( + "FeatureName", + session => session.WithSubFeatureUsageTrackingSession("SubFeature", _ => handled = true)); + + Assert.True(handled); + } + } } } diff --git a/src/Splat.Tests/Logging/StaticLoggerTests.cs b/src/Splat.Tests/Logging/StaticLoggerTests.cs new file mode 100644 index 000000000..87a27e0f2 --- /dev/null +++ b/src/Splat.Tests/Logging/StaticLoggerTests.cs @@ -0,0 +1,465 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using Splat.Tests.Mocks; +using Xunit; + +namespace Splat.Tests.Logging +{ + /// + /// Unit Tests for the Static Logging wrapper implementation. + /// + [ExcludeFromCodeCoverage] + public sealed class StaticLoggerTests + { + private const string Message = "Message"; + + private static char[] NewLine => Environment.NewLine.ToCharArray(); + + /// + /// Unit tests focusing on the debug logging in the static logger. + /// + public class DebugStaticLoggerTests : BaseStaticLoggerTests + { + /// + protected override LogLevel GetLogLevel() + { + return LogLevel.Debug; + } + + /// + protected override Action GetMethodWithGenericTypeShouldWriteMessageAndType() + { + return (logger, message) => logger.Debug(message); + } + + /// + protected override Action GetMethodToWriteMessage() + { + return (logger, s) => logger.Debug(s); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCulture() + { + return (logger, formatProvider, message, arg1) => logger.Debug(formatProvider, message, arg1); + } + + /// + protected override Action GetMethodToWriteExceptionAndMessage() + { + return (logger, exception, message) => logger.Debug(exception, message); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithTwoGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2) => logger.Debug(formatProvider, message, arg1, arg2); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithThreeGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2, arg3) => logger.Debug(formatProvider, message, arg1, arg2, arg3); + } + } + + /// + /// Unit tests focusing on the info logging in the static logger. + /// + public class InfoStaticLoggerTests : BaseStaticLoggerTests + { + /// + protected override LogLevel GetLogLevel() + { + return LogLevel.Info; + } + + /// + protected override Action GetMethodWithGenericTypeShouldWriteMessageAndType() + { + return (logger, message) => logger.Info(message); + } + + /// + protected override Action GetMethodToWriteMessage() + { + return (logger, s) => logger.Info(s); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCulture() + { + return (logger, formatProvider, message, arg1) => logger.Info(formatProvider, message, arg1); + } + + /// + protected override Action GetMethodToWriteExceptionAndMessage() + { + return (logger, exception, message) => logger.Info(exception, message); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithTwoGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2) => logger.Info(formatProvider, message, arg1, arg2); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithThreeGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2, arg3) => logger.Info(formatProvider, message, arg1, arg2, arg3); + } + } + + /// + /// Unit tests focusing on the warning logging in the static logger. + /// + public class WarningStaticLoggerTests : BaseStaticLoggerTests + { + /// + protected override LogLevel GetLogLevel() + { + return LogLevel.Warn; + } + + /// + protected override Action GetMethodWithGenericTypeShouldWriteMessageAndType() + { + return (logger, message) => logger.Warn(message); + } + + /// + protected override Action GetMethodToWriteMessage() + { + return (logger, s) => logger.Warn(s); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCulture() + { + return (logger, formatProvider, message, arg1) => logger.Warn(formatProvider, message, arg1); + } + + /// + protected override Action GetMethodToWriteExceptionAndMessage() + { + return (logger, exception, message) => logger.Warn(exception, message); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithTwoGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2) => logger.Warn(formatProvider, message, arg1, arg2); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithThreeGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2, arg3) => logger.Warn(formatProvider, message, arg1, arg2, arg3); + } + } + + /// + /// Unit tests focusing on the error logging in the static logger. + /// + public class ErrorStaticLoggerTests : BaseStaticLoggerTests + { + /// + protected override LogLevel GetLogLevel() + { + return LogLevel.Error; + } + + /// + protected override Action GetMethodWithGenericTypeShouldWriteMessageAndType() + { + return (logger, message) => logger.Error(message); + } + + /// + protected override Action GetMethodToWriteMessage() + { + return (logger, s) => logger.Error(s); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCulture() + { + return (logger, formatProvider, message, arg1) => logger.Error(formatProvider, message, arg1); + } + + /// + protected override Action GetMethodToWriteExceptionAndMessage() + { + return (logger, exception, message) => logger.Error(exception, message); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithTwoGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2) => logger.Error(formatProvider, message, arg1, arg2); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithThreeGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2, arg3) => logger.Error(formatProvider, message, arg1, arg2, arg3); + } + } + + /// + /// Unit tests focusing on the fatal logging in the static logger. + /// + public class FatalStaticLoggerTests : BaseStaticLoggerTests + { + /// + protected override LogLevel GetLogLevel() + { + return LogLevel.Fatal; + } + + /// + protected override Action GetMethodWithGenericTypeShouldWriteMessageAndType() + { + return (logger, message) => logger.Fatal(message); + } + + /// + protected override Action GetMethodToWriteMessage() + { + return (logger, s) => logger.Fatal(s); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCulture() + { + return (logger, formatProvider, message, arg1) => logger.Fatal(formatProvider, message, arg1); + } + + /// + protected override Action GetMethodToWriteExceptionAndMessage() + { + return (logger, exception, message) => logger.Fatal(exception, message); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithTwoGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2) => logger.Fatal(formatProvider, message, arg1, arg2); + } + + /// + protected override Action GetMethodToWriteMessageWithInvariantCultureWithThreeGenericArgs() + { + return (logger, formatProvider, message, arg1, arg2, arg3) => logger.Fatal(formatProvider, message, arg1, arg2, arg3); + } + } + + /// + /// Base tests for the static logger. + /// + public abstract class BaseStaticLoggerTests + { + /// + /// Test to make sure the generic type parameter is passed to the logger. + /// + [Fact] + public void Method_With_Generic_Type_Should_Write_Message_And_Type() + { + var textLogger = new TextLogger { Level = GetLogLevel() }; + var logger = GetLogger(textLogger); + + GetMethodWithGenericTypeShouldWriteMessageAndType()(logger, "This is a test."); + + Assert.Equal($"This is a test. ({nameof(GetMethodWithGenericTypeShouldWriteMessageAndType)})", textLogger.Logs.Last().message.Trim(NewLine).Trim()); + } + + /// + /// Test to make sure the generic type parameter is passed to the logger. + /// + [Fact] + public void Method_With_Generic_Type_Should_Write_Message_And_Type_Provided() + { + var textLogger = new TextLogger { Level = GetLogLevel() }; + var logger = GetLogger(textLogger); + + GetMethodWithGenericTypeShouldWriteMessageAndType()(logger, "This is a test."); + + Assert.Equal($"This is a test. ({nameof(GetMethodWithGenericTypeShouldWriteMessageAndType)})", textLogger.Logs.Last().message.Trim(NewLine).Trim()); + } + + /// + /// Test to ensure debug writes. + /// + [Fact] + public void Method_Writes_Message() + { + Test_Write_Message(logger => GetMethodToWriteMessage()(logger, "Message")); + } + + /// + /// Test to ensure invariant culture formatted string writes. + /// + [Fact] + public void Method_Writes_Message_InvariantCulture() + { + Test_Write_Message(logger => GetMethodToWriteMessageWithInvariantCulture()(logger, CultureInfo.InvariantCulture, "{0}", "Message")); + } + + /// + /// Test to ensure invariant culture formatted string writes. + /// + [Fact] + public void Method_Writes_Message_InvariantCulture_With_Generic_Two_Args() + { + Test_Write_Message(logger => GetMethodToWriteMessageWithInvariantCultureWithTwoGenericArgs()(logger, CultureInfo.InvariantCulture, "{0}", "Message", 1)); + } + + /// + /// Test to ensure invariant culture formatted string writes. + /// + [Fact] + public void Method_Writes_Message_InvariantCulture_With_Generic_Three_Args() + { + Test_Write_Message(logger => GetMethodToWriteMessageWithInvariantCultureWithThreeGenericArgs()(logger, CultureInfo.InvariantCulture, "{0}", "Message", 1, 2.3f)); + } + + /// + /// Test to ensure debug writes. + /// + [Fact] + public void Method_Writes_Exception_And_Message() + { + var staticLogger = GetLogger(GetLogLevel()); + GetMethodToWriteExceptionAndMessage()(staticLogger, new ArgumentException("TEST"), "Message"); + } + + /// + /// Test to ensure writes method works. + /// + [Fact] + public void Direct_Write_At_Level_Message() + { + var staticLogger = GetLogger(GetLogLevel()); + staticLogger.Write("Message", GetLogLevel()); + } + + /// + /// Test to ensure writes method works. + /// + [Fact] + public void Direct_Write_At_Level_Message_And_Type() + { + var staticLogger = GetLogger(GetLogLevel()); + staticLogger.Write("Message", typeof(DummyObjectClass1), GetLogLevel()); + } + + /// + /// Test to ensure writes method works. + /// + [Fact] + public void Direct_Write_At_Level_Message_And_Exception() + { + var staticLogger = GetLogger(GetLogLevel()); + var exception = new InvalidOperationException("bleh"); + staticLogger.Write(exception, "Message", GetLogLevel()); + } + + /// + /// Test to ensure writes method works. + /// + [Fact] + public void Direct_Write_At_Level_Message_Exception_And_Type() + { + var staticLogger = GetLogger(GetLogLevel()); + var exception = new InvalidOperationException("bleh"); + staticLogger.Write(exception, "Message", typeof(DummyObjectClass1), GetLogLevel()); + } + + /// + /// Test to make sure the message writes. + /// + [Fact] + public void Logger_Level_AtBoundary_Should_Be_correct() + { + var level = GetLogLevel(); + var logger = GetLogger(level); + + Assert.Equal(level, logger.Level); + } + + /// + /// Gets the logger action for Write with a generic type. + /// + /// The generic type to log. + /// Action to call. + protected abstract Action GetMethodWithGenericTypeShouldWriteMessageAndType(); + + /// + /// Gets the logger action for Writing a string message. + /// + /// Action to call. + protected abstract Action GetMethodToWriteMessage(); + + /// + /// Gets the logger action for Writing a string message. + /// + /// Action to call. + protected abstract Action GetMethodToWriteMessageWithInvariantCulture(); + + /// + /// Gets the logger action for Writing a string message. + /// + /// Action to call. + protected abstract Action GetMethodToWriteMessageWithInvariantCultureWithTwoGenericArgs(); + + /// + /// Gets the logger action for Writing a string message. + /// + /// Action to call. + protected abstract Action GetMethodToWriteMessageWithInvariantCultureWithThreeGenericArgs(); + + /// + /// Gets the logger action for Writing an exception and string message. + /// + /// Action to call. + protected abstract Action GetMethodToWriteExceptionAndMessage(); + + /// + /// Gets the log level boundary for the test. + /// + /// Log Level. + protected abstract Splat.LogLevel GetLogLevel(); + + private static StaticFullLogger GetLogger(TextLogger textLogger) => new StaticFullLogger(new WrappingFullLogger(textLogger)); + + private static StaticFullLogger GetLogger(LogLevel logLevel) + { + var textLogger = new TextLogger(); + textLogger.Level = logLevel; + + var wrappingFullLogger = new WrappingFullLogger(textLogger); + return new StaticFullLogger(wrappingFullLogger); + } + + private static void Test_Write_Message(Action testMethodFunc) + { + var textLogger = new TextLogger(); + Assert.Equal(0, textLogger.Logs.Count); + var staticLogger = GetLogger(textLogger); + + testMethodFunc(staticLogger); + Assert.Equal(1, textLogger.Logs.Count); + var line = textLogger.Logs.First(); + + var startOfCallerMemberSuffix = line.message.IndexOf("(", StringComparison.Ordinal); + Assert.True(startOfCallerMemberSuffix > 0); + + var endOfCallerMemberSuffix = line.message.IndexOf(")", startOfCallerMemberSuffix, StringComparison.Ordinal); + Assert.True(endOfCallerMemberSuffix > startOfCallerMemberSuffix + 1); + } + } + } +} diff --git a/src/Splat/ApplicationPerformanceMonitoring/EnableFeatureUsageTrackingExtensions.cs b/src/Splat/ApplicationPerformanceMonitoring/EnableFeatureUsageTrackingExtensions.cs index e14576391..4bc6310fb 100644 --- a/src/Splat/ApplicationPerformanceMonitoring/EnableFeatureUsageTrackingExtensions.cs +++ b/src/Splat/ApplicationPerformanceMonitoring/EnableFeatureUsageTrackingExtensions.cs @@ -31,5 +31,55 @@ public static IFeatureUsageTrackingSession FeatureUsageTrackingSession( return featureUsageTrackingSession.GetFeatureUsageTrackingSession(featureName); } + + /// + /// Helper for wrapping an action with a Feature Usage Tracking Session. + /// + /// instance of class that uses IEnableFeatureUsageTracking. + /// Name of the feature. + /// Action to carry out. + public static void WithFeatureUsageTrackingSession( + this IEnableFeatureUsageTracking instance, + string featureName, + Action action) + { + using (var session = instance.FeatureUsageTrackingSession(featureName)) + { + try + { + action(session); + } + catch (Exception exception) + { + session.OnException(exception); + throw; + } + } + } + + /// + /// Helper for wrapping an action with a SubFeature Usage Tracking Session. + /// + /// instance of class that uses IEnableFeatureUsageTracking. + /// Name of the feature. + /// Action to carry out. + public static void WithSubFeatureUsageTrackingSession( + this IFeatureUsageTrackingSession instance, + string featureName, + Action action) + { + using (var session = instance.SubFeature(featureName)) + { + try + { + action(session); + } + catch (Exception exception) + { + session.OnException(exception); + throw; + } + } + } } } diff --git a/src/Splat/Logging/IStaticFullLogger.cs b/src/Splat/Logging/IStaticFullLogger.cs new file mode 100644 index 000000000..fdbe2b1da --- /dev/null +++ b/src/Splat/Logging/IStaticFullLogger.cs @@ -0,0 +1,361 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. 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. +// See the LICENSE file in the project root for full license information. + +using System; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace Splat +{ + /// + /// Represents the logging interface for the Static Default Logger. + /// + public interface IStaticFullLogger + { + /// + /// Gets the level at which the target will emit messages. + /// + LogLevel Level { get; } + + /// + /// Emits a debug log message with an exception. + /// + /// The exception. + /// The message. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Debug(Exception exception, [Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the debug log. + /// + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Debug([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the debug log. + /// + /// The calling type. + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Debug([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the debug log. + /// + /// The type of the argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Debug(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument argument, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the debug log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Debug(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the debug log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The type of the third argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// The third argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Debug(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a info log message with exception. + /// This will emit details about a exception. + /// This type of logging is not able to be localized. + /// + /// The exception which to emit in the log. + /// A message to emit. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Info(Exception exception, [Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the info log. + /// + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Info([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the info log. + /// + /// The calling type. + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Info([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the info log. + /// + /// The type of the argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Info(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument argument, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the info log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Info(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the info log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The type of the third argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// The third argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Info(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a warning log message with exception. + /// This will emit details about a exception. + /// This type of logging is not able to be localized. + /// + /// The exception which to emit in the log. + /// A message to emit. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Warn(Exception exception, [Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the warning log. + /// + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Warn([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the warning log. + /// + /// The calling type. + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Warn([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the warning log. + /// + /// The type of the argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Warn(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument argument, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the warning log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Warn(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the warning log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The type of the third argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// The third argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Warn(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a error log message with exception. + /// This will emit details about a exception. + /// This type of logging is not able to be localized. + /// + /// The exception which to emit in the log. + /// A message to emit. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Error(Exception exception, [Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the error log. + /// + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Error([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the error log. + /// + /// The calling type. + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Error([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the error log. + /// + /// The type of the argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Error(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument argument, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the error log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Error(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the error log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The type of the third argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// The third argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Error(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a fatal log message with exception. + /// This will emit details about a exception. + /// This type of logging is not able to be localized. + /// + /// The exception which to emit in the log. + /// A message to emit. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Fatal(Exception exception, [Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the fatal log. + /// + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Fatal([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message to the fatal log. + /// + /// The calling type. + /// A non-localizable message to send to the log. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Fatal([Localizable(false)] string message, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the fatal log. + /// + /// The type of the argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Fatal(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument argument, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the fatal log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Fatal(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null); + + /// + /// Emits a message using formatting to the fatal log. + /// + /// The type of the first argument which is used in the formatting. + /// The type of the second argument which is used in the formatting. + /// The type of the third argument which is used in the formatting. + /// The format provider to use. + /// A message to emit to the log which includes the standard formatting tags. + /// The first argument for formatting purposes. + /// The second argument for formatting purposes. + /// The third argument for formatting purposes. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Fatal(IFormatProvider formatProvider, [Localizable(false)] string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null); + + /// + /// Writes a message to the target. + /// + /// The message to write. + /// The severity level of the log message. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Write([Localizable(false)] string message, LogLevel logLevel, [CallerMemberName]string callerMemberName = null); + + /// + /// Writes a message to the target. + /// + /// The exception that occured. + /// The message to write. + /// The severity level of the log message. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Write(Exception exception, [Localizable(false)] string message, LogLevel logLevel, [CallerMemberName]string callerMemberName = null); + + /// + /// Writes a messge to the target. + /// + /// The message. + /// The type. + /// The log level. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Write([Localizable(false)] string message, [Localizable(false)] Type type, LogLevel logLevel, [CallerMemberName]string callerMemberName = null); + + /// + /// Writes a messge to the target. + /// + /// The exception that occured. + /// The message. + /// The type. + /// The log level. + /// Allows you to pass the method or property name of the caller to the method, used to allow the capture in the static logger of some additional context for support and debugging. + void Write(Exception exception, [Localizable(false)] string message, [Localizable(false)] Type type, LogLevel logLevel, [CallerMemberName]string callerMemberName = null); + } +} diff --git a/src/Splat/Logging/LogHost.cs b/src/Splat/Logging/LogHost.cs index e7747b13b..e981871fa 100644 --- a/src/Splat/Logging/LogHost.cs +++ b/src/Splat/Logging/LogHost.cs @@ -17,17 +17,27 @@ public static class LogHost /// Gets the default registered within the . /// [SuppressMessage("Design", "CA1065: Do not raise exceptions in properties", Justification = "Very rare scenario")] - public static IFullLogger Default + public static IStaticFullLogger Default { get { + /* + * DV - this will need an extension of the dependency resolver. + * RegisterLazy(Func factory); + * which will allow a lazy instance of the static logger. + * + * return Locator.Current.GetService(); + */ + var factory = Locator.Current.GetService(); if (factory == null) { throw new LoggingException("ILogManager is null. This should never happen, your dependency resolver is broken"); } - return factory.GetLogger(typeof(LogHost)); + var fullLogger = factory.GetLogger(typeof(LogHost)); + + return new StaticFullLogger(fullLogger); } } diff --git a/src/Splat/Logging/StaticFullLogger.cs b/src/Splat/Logging/StaticFullLogger.cs new file mode 100644 index 000000000..9fb31f551 --- /dev/null +++ b/src/Splat/Logging/StaticFullLogger.cs @@ -0,0 +1,301 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. 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. +// See the LICENSE file in the project root for full license information. + +using System; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace Splat +{ + /// + /// A full logger which used by the default static logger to allow capture of .NET framework caller data. Wraps a . + /// + public sealed class StaticFullLogger : IStaticFullLogger + { + private readonly IFullLogger _fullLogger; + + /// + /// Initializes a new instance of the class. + /// + /// The to wrap in this class. + public StaticFullLogger(IFullLogger fullLogger) + { + _fullLogger = fullLogger ?? throw new ArgumentNullException(nameof(fullLogger)); + } + + /// + public LogLevel Level => _fullLogger.Level; + + /// + public void Debug(Exception exception, string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Debug(exception, GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Debug(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Debug(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Debug(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Debug(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Debug(IFormatProvider formatProvider, string message, TArgument argument, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Debug( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument); + } + + /// + public void Debug(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Debug( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2); + } + + /// + public void Debug(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Debug( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2, + argument3); + } + + /// + public void Info(Exception exception, string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Info(exception, GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Info(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Info(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Info(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Info(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Info(IFormatProvider formatProvider, string message, TArgument argument, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Info( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument); + } + + /// + public void Info(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Info( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2); + } + + /// + public void Info(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Info( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2, + argument3); + } + + /// + public void Warn(Exception exception, string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Warn(exception, GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Warn(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Warn(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Warn(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Warn(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Warn(IFormatProvider formatProvider, string message, TArgument argument, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Warn( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument); + } + + /// + public void Warn(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Warn( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2); + } + + /// + public void Warn(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Warn( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2, + argument3); + } + + /// + public void Error(Exception exception, string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Error(exception, GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Error(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Error(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Error(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Error(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Error(IFormatProvider formatProvider, string message, TArgument argument, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Error( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument); + } + + /// + public void Error(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Error( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2); + } + + /// + public void Error(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Error( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2, + argument3); + } + + /// + public void Fatal(Exception exception, string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Fatal(exception, GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Fatal(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Fatal(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Fatal(string message, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Fatal(GetSuffixedCallerData(message, callerMemberName)); + } + + /// + public void Fatal(IFormatProvider formatProvider, string message, TArgument argument, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Fatal( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument); + } + + /// + public void Fatal(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Fatal( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2); + } + + /// + public void Fatal(IFormatProvider formatProvider, string message, TArgument1 argument1, TArgument2 argument2, TArgument3 argument3, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Fatal( + formatProvider, + GetSuffixedCallerData(message, callerMemberName), + argument1, + argument2, + argument3); + } + + /// + public void Write(string message, LogLevel logLevel, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Write(GetSuffixedCallerData(message, callerMemberName), logLevel); + } + + /// + public void Write(Exception exception, string message, LogLevel logLevel, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Write(exception, GetSuffixedCallerData(message, callerMemberName), logLevel); + } + + /// + public void Write([Localizable(false)] string message, [Localizable(false)] Type type, LogLevel logLevel, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Write(GetSuffixedCallerData(message, callerMemberName), type, logLevel); + } + + /// + public void Write(Exception exception, [Localizable(false)] string message, [Localizable(false)] Type type, LogLevel logLevel, [CallerMemberName]string callerMemberName = null) + { + _fullLogger.Write(exception, GetSuffixedCallerData(message, callerMemberName), type, logLevel); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static string GetSuffixedCallerData(string message, string callerMemberName) + { + return message + " (" + callerMemberName + ")"; + } + } +} diff --git a/version.json b/version.json index 1860d25cc..8e3407c73 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { - "version": "9.8", + "version": "10.0", "publicReleaseRefSpec": [ "^refs/heads/main$", // we release out of master "^refs/heads/preview/.*", // we release previews