为Serilog创建包装

时间:2019-04-19 00:08:59

标签: c# casting serilog

我正在使用Serilog。为了避免在每个微服务中进行配置,我创建了一个扩展名为

的私有NuGet包。
namespace DFX.Logging
{
    public static class Extensions
    {
        public static IWebHostBuilder UseLogging(this IWebHostBuilder webHostBuilder) =>
            webHostBuilder.UseSerilog((context, loggerConfiguration) =>
            {
                var logLevel = context.Configuration.GetValue<string>("Serilog:MinimumLevel");
                if (!Enum.TryParse<LogEventLevel>(logLevel, true, out var level))
                {
                    level = LogEventLevel.Information;
                }

                loggerConfiguration.Enrich
                    .FromLogContext()
                    .MinimumLevel.Is(level);

                loggerConfiguration
                    .ReadFrom.Configuration(context.Configuration)
                    .WriteTo.Console(
                        theme: AnsiConsoleTheme.Code,
                        outputTemplate: "[{Timestamp:yy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}");
            });
    }
}

在控制器(或其他地方)中创建记录器

private readonly ILogger _logger = Log.ForContext<Application>();

为此,我需要使用using Serilog;添加。我想避免使用它,而只使用我的命名空间using DFX.Logging;。我该如何发财呢?到目前为止,我已经尝试过:

namespace DFX.Logging
{
    // custom wrapper
    public static class Log
    {
        public static ILogger ForContext<TSource>()
        {
            return (ILogger)Serilog.Log.ForContext<TSource>();
        }
    }

    public interface ILogger : Serilog.ILogger
    {
    }
}

然后代码成功编译,但是在运行时我得到了

  

'无法转换类型为'Serilog.Core.Logger'的对象来键入   “ DFX.Logging.ILogger”。

我意识到我无法将Serilog.Core.Logger投向记录器,因为Serilog.Core.Logger未实现DFX.Logging.ILogger,但如何实现?

2 个答案:

答案 0 :(得分:5)

简短的答案是:不能。至少不如您的想法那么容易。

如果您真的想走这条路,可以选择以下选项:

  • 创建自己的静态pub trait Vector<'a> { type Item: 'a; type Iter: Iterator<Item = Self::Item> + 'a; // several functions fn iter(&'a self) -> Self::Iter; } pub struct VectorImplementation1<T> { numbers: Vec<T>, } impl<'a, T: 'a> Vector<'a> for VectorImplementation1<T> { type Item = &'a T; type Iter = std::slice::Iter<'a, T>; fn iter(&'a self) -> Self::Iter { self.numbers.iter() } } impl<'a, T: 'a> Vector<'a> for &'a VectorImplementation1<T> { type Item = &'a T; type Iter = std::slice::Iter<'a, T>; fn iter(&'a self) -> Self::Iter { self.numbers.iter() } } 类,该类实现您的LoggerProxy接口,并通过编写C#代码来包装Serilog ILogger的实例
  • 使用Castle.DynamicProxyLinFu.DynamicProxy之类的东西创建一个动态ILogger(又称LoggerProxy)类,该类在运行时生成。
  • 修改Serilog的代码以实现您的界面,然后重新编译
  • 例如通过使用Fody扩展名,通过.NET IL Weaving修改Serilog的程序集,以实现您的界面

答案 1 :(得分:1)

如果您不想依赖自己的日志代理,则可以使用具有serilog实现的dot net日志扩展。

https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger https://github.com/serilog/serilog-extensions-logging