+-

我有一个扩展方法来支持其他日志级别,如下所示:
public static void Duration(this ILogger source, string message)
{
var logEventInfo = new LogEventInfo(LogLevel.Warn, source.Name, message);
logEventInfo.Properties.Add("specialLevel", "Duration");
source.Log(logEventInfo);
}
这有一个问题.
我的${callsite}现在总是报告持续时间.有什么方法可以将调用堆栈级别提高一级,以获得调用Duration的方法,还是为此需要自定义渲染器?
到目前为止我尝试过的是:
logEventInfo.Properties.Add("skipFrames", 1);
和
layout="${formattedDate} ${callsite:skipFrames=${event-properties:item=skipFrames}} ${message}"
丑陋的解决方法:
[LayoutRenderer("customCallSite")]
public class CustomCallSiteLayoutRenderer : CallSiteLayoutRenderer
{
private readonly CallSiteLayoutRenderer DefaultRenderer = new CallSiteLayoutRenderer();
/// <inheritdoc />
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
if (!logEvent.HasProperties)
{
builder.Append(DefaultRenderer.Render(logEvent));
return;
}
if (logEvent.Properties["skipFrames"] is int skipFrames)
{
builder.Append(GetRenderer(skipFrames).Render(logEvent));
}
else
{
builder.Append(logEvent.Level);
}
}
private static readonly ConcurrentDictionary<int, CallSiteLayoutRenderer> Renderers = new ConcurrentDictionary<int, CallSiteLayoutRenderer>();
private CallSiteLayoutRenderer GetRenderer(int skipFrames)
{
return Renderers.GetOrAdd(skipFrames, f => new CallSiteLayoutRenderer() {SkipFrames = skipFrames});
}
}
最佳答案
您可以遵循另一种方法
>将“持续时间”方法移至新装配
>通过调用AddHiddenAssembly将该程序集隐藏在堆栈跟踪中
LogManager.AddHiddenAssembly(yourAssemblyWithDurationMethod)
然后不需要自定义布局渲染器:)
PS:您的“持续时间”方法应命名为“ LogDuration”. ;)从API的角度来看,我认为这有点奇怪.
点击查看更多相关文章
转载注明原文:我如何操纵NLog的堆栈级别? - 乐贴网