Как мне манипулировать уровнем стека NLog? - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть метод расширения для поддержки дополнительных уровней журнала, подобный этому:

    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.Есть ли способ повысить уровень стека вызовов на единицу, чтобы получить метод, который вызывает 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});
    }
}

1 Ответ

0 голосов
/ 20 февраля 2019

Существует другой подход, которому вы можете следовать

  1. Переместить метод «Продолжительность» в новую сборку
  2. Скрыть эту сборку в трассировке стека, вызвав AddHiddenAssembly

    LogManager.AddHiddenAssembly(yourAssemblyWithDurationMethod)
    

Тогда нет необходимости в пользовательских средствах визуализации макета:)

PS: Ваш метод «Duration» должен называться «LogDuration».;) С точки зрения API, на мой взгляд, это немного странный метод.

...