为Serilog创建包装 [英] Create a wrapper for Serilog
问题描述
我正在使用Serilog.为了避免在每个微服务中进行配置,我创建了一个扩展名为
I'm using Serilog. To avoid configuration in each microservice I create a private NuGet package with extension like
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}");
});
}
}
在控制器(或其他地方)中创建记录器
in controller (or somewhere else) I create logger
private readonly ILogger _logger = Log.ForContext<Application>();
为此,我需要使用Serilog; 添加.我想避免使用它,而仅使用DFX.Logging; 命名空间.我该如何发财呢?到目前为止,我已经尝试过:
for that I need to add using using Serilog;
. I want to avoid it and use only my namespace using DFX.Logging;
. How can I rich that? What I have tried so far:
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
{
}
}
然后代码成功编译,但是在运行时我得到了
Then the code compile successfully but at the runtime I got
'无法转换类型为'Serilog.Core.Logger'的对象来键入"DFX.Logging.ILogger".
'Unable to cast object of type 'Serilog.Core.Logger' to type 'DFX.Logging.ILogger'.'
我意识到我无法将 Serilog.Core.Logger
强制转换为记录器,因为 Serilog.Core.Logger
未实现 DFX.Logging.ILogger
,但是如何实现?
I realize that I can't cast Serilog.Core.Logger
to my logger because Serilog.Core.Logger
not implement DFX.Logging.ILogger
, but how it can be implemented?
推荐答案
简短的答案是:您不能.至少不如您的想法那么容易.
The short answer is: You can't. At least not as easily as how you are thinking.
如果您真的想走这条路,可能有一些选择:
If you really want to go this route, some options could be:
- 创建自己的静态
LoggerProxy
类,该类实现您的ILogger
接口,并通过编写C#来包装Serilog的ILogger
实例.代码 - 使用 LinFu.DynamicProxy
- 修改Serilog的代码以实现您的界面,然后重新编译
- 例如,使用 Fody 扩展名,通过.NET IL Weaving修改Serilog的程序集,以实现您的界面
- Create your own static
LoggerProxy
class that implements yourILogger
interface, and wraps an instance of Serilog'sILogger
by ... writing the C# code - Create a dynamic
LoggerProxy
(a.k.a.LoggerInterceptor
) class that gets generated during runtime, using something like Castle.DynamicProxy or LinFu.DynamicProxy - Modify Serilog's code to implement your interface, and recompile it
- Modify Serilog's assembly via .NET IL Weaving, for example, using a Fody extension, to implement your interface
这篇关于为Serilog创建包装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!