diff --git a/src/Readme.txt b/src/Readme.txt
index cdf5ff73..4453c0a1 100644
--- a/src/Readme.txt
+++ b/src/Readme.txt
@@ -64,6 +64,10 @@ For further details take a look at LICENSE.txt.
CHANGELOG
+4.8.13.0
+
+ * New: #445: Added support for better custom logging
+
4.8.11.0
* New: #426: Added file numbers to class report
diff --git a/src/ReportGenerator.Core/Logging/ConsoleLoggerFactory.cs b/src/ReportGenerator.Core/Logging/ConsoleLoggerFactory.cs
index 7ad2c347..dbff3b45 100644
--- a/src/ReportGenerator.Core/Logging/ConsoleLoggerFactory.cs
+++ b/src/ReportGenerator.Core/Logging/ConsoleLoggerFactory.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace Palmmedia.ReportGenerator.Core.Logging
{
@@ -13,7 +10,7 @@ internal class ConsoleLoggerFactory : ILoggerFactory
///
/// The cached logger.
///
- private static readonly ILogger Logger = new ConsoleLogger();
+ private readonly ILogger logger = new ConsoleLogger();
///
/// Gets or sets the verbosity of console loggers.
@@ -22,12 +19,12 @@ public VerbosityLevel VerbosityLevel
{
get
{
- return Logger.VerbosityLevel;
+ return this.logger.VerbosityLevel;
}
set
{
- Logger.VerbosityLevel = value;
+ this.logger.VerbosityLevel = value;
}
}
@@ -36,6 +33,6 @@ public VerbosityLevel VerbosityLevel
///
/// The type of the class that uses the logger.
/// The logger.
- public ILogger GetLogger(Type type) => Logger;
+ public ILogger GetLogger(Type type) => this.logger;
}
}
diff --git a/src/ReportGenerator.Core/Logging/DelegateLogger.cs b/src/ReportGenerator.Core/Logging/DelegateLogger.cs
new file mode 100644
index 00000000..998c634f
--- /dev/null
+++ b/src/ReportGenerator.Core/Logging/DelegateLogger.cs
@@ -0,0 +1,129 @@
+using System;
+
+namespace Palmmedia.ReportGenerator.Core.Logging
+{
+ ///
+ /// which executes a delegate.
+ ///
+ internal class DelegateLogger : ILogger
+ {
+ ///
+ /// The log delegate.
+ ///
+ private Action logDelegate;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The log delegate.
+ public DelegateLogger(Action logDelegate)
+ {
+ this.logDelegate = logDelegate ?? throw new ArgumentNullException(nameof(logDelegate));
+ }
+
+ ///
+ /// Gets or sets the verbosity level.
+ ///
+ public VerbosityLevel VerbosityLevel { get; set; }
+
+ ///
+ /// Log a message at DEBUG level.
+ ///
+ /// The message.
+ public void Debug(string message)
+ {
+ if (this.VerbosityLevel < VerbosityLevel.Info)
+ {
+ this.logDelegate(this.VerbosityLevel, message);
+ }
+ }
+
+ ///
+ /// Log a formatted message at DEBUG level.
+ ///
+ /// The template string.
+ /// The arguments.
+ public void DebugFormat(string format, params object[] args)
+ {
+ if (this.VerbosityLevel < VerbosityLevel.Info)
+ {
+ this.logDelegate(this.VerbosityLevel, string.Format(format, args));
+ }
+ }
+
+ ///
+ /// Log a message at INFO level.
+ ///
+ /// The message.
+ public void Info(string message)
+ {
+ if (this.VerbosityLevel < VerbosityLevel.Warning)
+ {
+ this.logDelegate(this.VerbosityLevel, message);
+ }
+ }
+
+ ///
+ /// Log a formatted message at INFO level.
+ ///
+ /// The template string.
+ /// The arguments.
+ public void InfoFormat(string format, params object[] args)
+ {
+ if (this.VerbosityLevel < VerbosityLevel.Warning)
+ {
+ this.logDelegate(this.VerbosityLevel, string.Format(format, args));
+ }
+ }
+
+ ///
+ /// Log a message at WARN level.
+ ///
+ /// The message.
+ public void Warn(string message)
+ {
+ if (this.VerbosityLevel < VerbosityLevel.Error)
+ {
+ this.logDelegate(this.VerbosityLevel, message);
+ }
+ }
+
+ ///
+ /// Log a formatted message at WARN level.
+ ///
+ /// The template string.
+ /// The arguments.
+ public void WarnFormat(string format, params object[] args)
+ {
+ if (this.VerbosityLevel < VerbosityLevel.Error)
+ {
+ this.logDelegate(this.VerbosityLevel, string.Format(format, args));
+ }
+ }
+
+ ///
+ /// Log a message at INFO level.
+ ///
+ /// The message.
+ public void Error(string message)
+ {
+ if (this.VerbosityLevel < VerbosityLevel.Off)
+ {
+ this.logDelegate(this.VerbosityLevel, message);
+ }
+ }
+
+ ///
+ /// Log a formatted message at ERROR level.
+ ///
+ /// The template string.
+ /// The arguments.
+ public void ErrorFormat(string format, params object[] args)
+ {
+ if (this.VerbosityLevel < VerbosityLevel.Off)
+ {
+ this.logDelegate(this.VerbosityLevel, string.Format(format, args));
+ }
+ }
+ }
+}
diff --git a/src/ReportGenerator.Core/Logging/DelegateLoggerFactory.cs b/src/ReportGenerator.Core/Logging/DelegateLoggerFactory.cs
new file mode 100644
index 00000000..0eaf3950
--- /dev/null
+++ b/src/ReportGenerator.Core/Logging/DelegateLoggerFactory.cs
@@ -0,0 +1,52 @@
+using System;
+
+namespace Palmmedia.ReportGenerator.Core.Logging
+{
+ ///
+ /// A logger factory creating delegate loggers.
+ ///
+ internal class DelegateLoggerFactory : ILoggerFactory
+ {
+ ///
+ /// The cached logger.
+ ///
+ private readonly ILogger logger;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The log delegate.
+ public DelegateLoggerFactory(Action logDelegate)
+ {
+ if (logDelegate == null)
+ {
+ throw new ArgumentNullException(nameof(logDelegate));
+ }
+
+ this.logger = new DelegateLogger(logDelegate);
+ }
+
+ ///
+ /// Gets or sets the verbosity of delegate loggers.
+ ///
+ public VerbosityLevel VerbosityLevel
+ {
+ get
+ {
+ return this.logger.VerbosityLevel;
+ }
+
+ set
+ {
+ this.logger.VerbosityLevel = value;
+ }
+ }
+
+ ///
+ /// Initializes the logger for the given type.
+ ///
+ /// The type of the class that uses the logger.
+ /// The logger.
+ public ILogger GetLogger(Type type) => this.logger;
+ }
+}
diff --git a/src/ReportGenerator.Core/Logging/LoggerFactory.cs b/src/ReportGenerator.Core/Logging/LoggerFactory.cs
index 1f9d501c..f2ac44fb 100644
--- a/src/ReportGenerator.Core/Logging/LoggerFactory.cs
+++ b/src/ReportGenerator.Core/Logging/LoggerFactory.cs
@@ -37,6 +37,15 @@ public static void Configure(ILoggerFactory factory)
innerFactory = factory ?? throw new ArgumentNullException(nameof(factory));
}
+ ///
+ /// Configures the inner logger factory.
+ ///
+ /// The log delegate.
+ public static void Configure(Action logDelegate)
+ {
+ innerFactory = new DelegateLoggerFactory(logDelegate) ?? throw new ArgumentNullException(nameof(logDelegate));
+ }
+
///
/// Initializes the logger for the given type.
///