Microsoft.Extensions.Logging
is used for dependency injection, which is handy for unit testing: you can implement a logger with a LoggedText property to support Assert.IsTrue(_logger.LoggedText.Contains("expected value"))
. The following example illustrates such a class that implements Microsoft.Extensions.Logging.ILogger<T>
and also (for fun) uses Julian's suggestion of sending the message to NLog as well:
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyDomain.Tests
{
internal class WrappedNLogger<T> : ILogger<T>
{
private StringBuilder _sb = new StringBuilder(); //Support Assert.IsTrue(_logger.LoggedText == "expected value")
private NLog.Logger _nlog = NLog.LogManager.GetCurrentClassLogger(); //support use of NLog
public IDisposable BeginScope<TState>(TState state) => default;
public bool IsEnabled(LogLevel logLevel) => true;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
var jsonLine = JsonConvert.SerializeObject(new
{
timestamp = DateTime.Now.ToLongTimeString(),
logLevel,
eventId,
parameters = (state as IEnumerable<KeyValuePair<string, object>>)?.ToDictionary(i => i.Key, i => i.Value),
message = formatter(state, exception),
exception = exception?.GetType().Name
});
_sb.AppendLine(jsonLine);
NLog.LogLevel nloglevel = logLevel == LogLevel.Debug ? NLog.LogLevel.Debug
: logLevel == LogLevel.Information ? NLog.LogLevel.Info
: logLevel == LogLevel.Warning ? NLog.LogLevel.Warn
: logLevel == LogLevel.Error ? NLog.LogLevel.Error
: logLevel == LogLevel.Critical ? NLog.LogLevel.Fatal : NLog.LogLevel.Trace;
_nlog.Log(nloglevel, jsonLine);
}
public string LoggedText { get => _sb.ToString(); }
}
}