Rub*_*ink 3 porting nlog target sink serilog
作为从NLog切换到Serilog的一个步骤,我想将NLog标准调用的标准接线重定向LogManager.GetLogger(name)到桥接任何记录到NLog的代码,立即转发到环境Serilog Log.Logger- 即我只想转发一个简单转发的配置消息,没有像Log4net.Appender.SerilogLog4net 那样缓冲.
任何人都可以编造或指向一个规范的片段,正确有效地做到这一点吗?我能想到的要求:
nlog.Warn应该相当于serilog.WarningLogEvent在Serilog术语中)我认为最好的选择确实是自定义NLog目标.这样的事情:(C#)
using NLog;
using NLog.Targets;
using Serilog;
using Serilog.Events;
namespace MyNamespace
{
[Target("SerilogTarget")]
public sealed class SerilogTarget : TargetWithLayout
{
protected override void Write(LogEventInfo logEvent)
{
var log = Log.ForContext(Serilog.Core.Constants.SourceContextPropertyName, logEvent.LoggerName);
var logEventLevel = ConvertLevel(logEvent.Level);
if ((logEvent.Parameters?.Length ?? 0) == 0)
{
// NLog treats a single string as a verbatim string; Serilog treats it as a String.Format format and hence collapses doubled braces
// This is the most direct way to emit this without it being re-processed by Serilog (via @nblumhardt)
var template = new Serilog.Events.MessageTemplate(new[] { new Serilog.Parsing.TextToken(logEvent.FormattedMessage) });
log.Write(new Serilog.Events.LogEvent(DateTimeOffset.Now, logEventLevel, logEvent.Exception, template, Enumerable.Empty<Serilog.Events.LogEventProperty>()));
}
else
// Risk: tunneling an NLog format and assuming it will Just Work as a Serilog format
#pragma warning disable Serilog004 // Constant MessageTemplate verifier
log.Write(logEventLevel, logEvent.Exception, logEvent.Message, logEvent.Parameters);
#pragma warning restore Serilog004
}
static Serilog.Events.LogEventLevel ConvertLevel(LogLevel logEventLevel)
{
if (logEventLevel == LogLevel.Info)
return Serilog.Events.LogEventLevel.Information;
else if (logEventLevel == LogLevel.Trace)
return Serilog.Events.LogEventLevel.Verbose;
else if (logEventLevel == LogLevel.Debug)
return Serilog.Events.LogEventLevel.Debug;
else if (logEventLevel == LogLevel.Error)
return Serilog.Events.LogEventLevel.Error;
return Serilog.Events.LogEventLevel.Fatal;
}
}
}
Run Code Online (Sandbox Code Playgroud)
将其注册到您的main()或app_start:
// Register so it can be used by config file parsing etc
Target.Register<MyNamespace.SerilogTarget>("SerilogTarget");
Run Code Online (Sandbox Code Playgroud)
在进行任何日志记录之前,Target需要连接的内容LogManager.GetLogger()实际上可以触发调用SerilogTarget.Write
public static void ReplaceAllNLogTargetsWithSingleSerilogForwarder()
{
// sic: blindly overwrite the forwarding rules every time
var target = new SerilogTarget();
var cfg = new NLog.Config.LoggingConfiguration();
cfg.AddTarget(nameof(SerilogTarget), target);
cfg.LoggingRules.Add(new NLog.Config.LoggingRule("*", LogLevel.Trace, target));
// NB assignment must happen last; rules get ingested upon assignment
LogManager.Configuration = cfg;
}
Run Code Online (Sandbox Code Playgroud)
另见:https://github.com/nlog/nlog/wiki/How-to-write-a-custom-target
这样做的最佳方式,不会产生任何可避免的冲击力等.
这是NLog的最佳方式,对NLog的站点没有性能影响.
什么是
TargetAttribute我买?
那么在这种情况下你不需要它.该TargetAttribute注册完全组装时使用,而是因为我们手动注册,这是没有必要的.我认为这是最好的做法,但你可以把它留下来.
还有什么能
Register买我的
使用编程配置时确实不需要这样做.但是如果你有XML配置,你需要注册.
我习惯于编写各种方式的目标(手动注册,按汇编注册,从代码配置,从XML配置).我能理解这可能令人困惑.
| 归档时间: |
|
| 查看次数: |
681 次 |
| 最近记录: |