簡體   English   中英

我如何操縱NLog的堆棧級別?

[英]How do i manipulate the stack level of NLog?

我有一個擴展方法來支持這樣的額外日志級別:

    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}現在總是報告持續時間。 有沒有辦法將調用堆棧級別增加一個,以獲取調用持續時間的方法,或者我需要一個自定義渲染器嗎?

到目前為止我嘗試了什么:

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});
    }
}

您可以遵循另一種方法

  1. 將“Duration”方法移動到新程序集
  2. 通過調用AddHiddenAssembly在堆棧跟蹤中隱藏該程序集

     LogManager.AddHiddenAssembly(yourAssemblyWithDurationMethod) 

不需要自定義布局渲染器然后:)

PS:您的“持續時間”方法應命名為“LogDuration”。 ;)從API的角度來看,我認為這有點奇怪。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM