Microsoft.Extensions.Logging的记录器包装器的实现和使用

时间:2016-09-21 07:27:18

标签: c# .net logging ms-extensions-logging

此问题与Steven的答案相关 - here。他提出了一个非常好的记录器包装器。我将在下面粘贴他的代码:

public interface ILogger
{
    void Log(LogEntry entry);
}

public static class LoggerExtensions
{
    public static void Log(this ILogger logger, string message)
    {
        logger.Log(new LogEntry(LoggingEventType.Information,
            message, null));
    }

    public static void Log(this ILogger logger, Exception exception)
    {
        logger.Log(new LogEntry(LoggingEventType.Error, 
            exception.Message, exception));
    }

    // More methods here.
}

所以,我的问题是创建实现代理Microsoft.Extensions.Logging 的正确方法是什么,以后在代码中使用它的最佳方式是什么

注意:此问题是this question about log4net的副本,但现在特定于Microsoft.Extensions.Logging。

2 个答案:

答案 0 :(得分:7)

  

所以,我的问题是创建代理Microsoft.Extensions.ILogger的实现的正确方法是什么?

你应该创建类似的东西:

public sealed class MicrosoftLoggingAdapter  : ILogger
{
    private readonly Microsoft.Extensions.ILogger adaptee;

    public MicrosoftLoggingAdapter (Microsoft.Extensions.ILogger adaptee) =>
        this.adaptee = adaptee;

    public void Log(LogEntry e) =>
        adaptee.Log(ToLevel(e.Severity), 0, e.Message, e.Exception, (s, _) => s);       

    private static LogLevel ToLevel(LoggingEventType s) =>
        s == LoggingEventType.Debug ? LogLevel.Debug  :
        s == LoggingEventType.Information ? LogLevel.Information :
        s == LoggingEventType.Warning ? LogLevel.Warning :
        s == LoggingEventType.Error ? LogLevel.Error :
        LogLevel.Critical;      
}
  

以后在代码中使用它的最佳方法是什么?

如果您使用DI容器,则只需使用DI容器将ILogger映射到MicrosoftLoggingAdapter。您还需要注册Microsoft.Extensions.ILogger,或者只是将一个MS logger实例提供给DI容器,以将其注入MicrosoftLoggingAdapter构造函数。

如果您不使用DI容器,即使用Pure DI,那么您可以执行以下操作:

var logger = loggerFactory.CreateLogger("Application");

ILogger logging_adapter = new MicrosoftLoggingAdapter(logger);

var myobject = new MyClass(other_dependencies_here, logging_adapter);

答案 1 :(得分:0)

这是我的解决方案。不太像史蒂文的。但是不完全一样。而且我倾向于dotNetCore,但是在dotnetFW中可以完成相同的事情。

DotNetCoreLogger是“ MY” ILogger的具体。然后将“ Microsoft” ILogger(Microsoft.Extensions.Logging.ILogger)注入“我的”具体记录器中。

还有一个SOF答案,“启发”了“我”的日志记录抽象...。从DotNetFramework(经典)转到DotNotCore之后,我很高兴我做了一个“我的” ILogger抽象。

using System;

namespace MyApplication.Infrastructure.Logging.LoggingAbstractBase
{
    public interface ILogger
    {
        void Log(LogEntry entry);
        void Log(string message);
        void Log(Exception exception);
    }
}


namespace MyApplication.Infrastructure.Logging.LoggingAbstractBase
{
    public enum LoggingEventTypeEnum
    {
        Debug,
        Information,
        Warning,
        Error,
        Fatal
    };
}



using System;

namespace MyApplication.Infrastructure.Logging.LoggingAbstractBase
{
    public class LogEntry
    {
        public readonly LoggingEventTypeEnum Severity;
        public readonly string Message;
        public readonly Exception Exception;

        public LogEntry(LoggingEventTypeEnum severity, string message, Exception exception = null)
        {
            if (message == null) throw new ArgumentNullException("message");
            if (message == string.Empty) throw new ArgumentException("empty", "message");

            this.Severity = severity;
            this.Message = message;
            this.Exception = exception;
        }
    }
}



using System;
using Microsoft.Extensions.Logging;

namespace MyApplication.Infrastructure.Logging.LoggingCoreConcrete
{
    public class DotNetCoreLogger<T> : MyApplication.Infrastructure.Logging.LoggingAbstractBase.ILogger
    {
        private readonly ILogger<T> concreteLogger;

        public DotNetCoreLogger(Microsoft.Extensions.Logging.ILogger<T> concreteLgr)
        {
            this.concreteLogger = concreteLgr ?? throw new ArgumentNullException("Microsoft.Extensions.Logging.ILogger is null");
        }

        public void Log(MyApplication.Infrastructure.Logging.LoggingAbstractBase.LogEntry entry)
        {
            if (null == entry)
            {
                throw new ArgumentNullException("LogEntry is null");
            }
            else
            {
                switch (entry.Severity)
                {
                    case LoggingAbstractBase.LoggingEventTypeEnum.Debug:
                        this.concreteLogger.LogDebug(entry.Message);
                        break;
                    case LoggingAbstractBase.LoggingEventTypeEnum.Information:
                        this.concreteLogger.LogInformation(entry.Message);
                        break;
                    case LoggingAbstractBase.LoggingEventTypeEnum.Warning:
                        this.concreteLogger.LogWarning(entry.Message);
                        break;
                    case LoggingAbstractBase.LoggingEventTypeEnum.Error:
                        this.concreteLogger.LogError(entry.Message, entry.Exception);
                        break;
                    case LoggingAbstractBase.LoggingEventTypeEnum.Fatal:
                        this.concreteLogger.LogCritical(entry.Message, entry.Exception);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException(string.Format("LogEntry.Severity out of range. (Severity='{0}')", entry.Severity));
                }
            }
        }

        public void Log(string message)
        {
            this.concreteLogger.LogInformation(message);
        }

        public void Log(Exception exception)
        {
            this.concreteLogger.LogError(exception.Message, exception);
        }
    }
}



/* IoC/DI below */


        private static System.IServiceProvider BuildDi(Microsoft.Extensions.Configuration.IConfiguration config)
        {
            //setup our DI
            IServiceProvider serviceProvider = new ServiceCollection()
                .AddLogging()
                .AddSingleton<IConfiguration>(config)
                .AddSingleton<MyApplication.Infrastructure.Logging.LoggingAbstractBase.ILogger, MyApplication.Infrastructure.Logging.LoggingCoreConcrete.DotNetCoreLogger<Program>>()
                .BuildServiceProvider();

            //configure console logging
            serviceProvider
                .GetService<ILoggerFactory>()
                .AddConsole(LogLevel.Debug);

            return serviceProvider;
        }