关联范围内的日志消息

时间:2014-12-10 13:03:58

标签: c# log4net trace nlog

我想使用日志记录范围关联日志记录消息。我正在寻找log4net,NLog或System.Diagnostics.Trace的实现。以下是演示该概念的基本实现。该程序的输出是:

First level: Logging in the run method
First level: Logging one level down
Second scope: Another message
First level: Back from scope

是否有更强大/通用/已证明/易于使用的框架版本,以下所做的是什么?

class Program
{
    private static readonly Log Log = new Log();

    private static void Main()
    {
        using (new LoggingScope("First level"))
        {
            Run();
        }
    }

    private static void Run()
    {
        Log.Info("Logging in the run method");
        Run2();
    }

    private static void Run2()
    {
        Log.Info("Logging one level down");
        using (new LoggingScope("Second scope"))
        {
            Log.Info("Another message");
        }

        Log.Info("Back from scope");
    }
}

internal class Log
{
    static Log()
    {
        CurrentScope = new Stack<string>();
    }

    private static Stack<string> CurrentScope { get; set; }

    public static void PushScope(string name)
    {
        CurrentScope.Push(name);
    }

    public static void PopScope()
    {
        CurrentScope.Pop();
    }

    public void Info(string message)
    {
        var currentScope = CurrentScope.Count == 0 ? string.Empty : CurrentScope.Peek();
        Console.WriteLine("{0}: {1}", currentScope, message);
    }
}

internal class LoggingScope : IDisposable
{
    private readonly string _name;

    public LoggingScope(string id)
    {
        _name = Guid.NewGuid().ToString();
        Log.PushScope(id);
        CallContext.SetData(_name, id);
    }

    public void Dispose()
    {
        Log.PopScope();
        CallContext.FreeNamedDataSlot(_name);
    }
}

3 个答案:

答案 0 :(得分:1)

您正在寻找嵌套诊断上下文(NDC):

    Log.Info("Logging one level down");
    using(ThreadContext.Stacks["NDC"].Push( requestid))
    {
        Log.Info("Another message");
    }
    Log.Info("Back from scope");

要获取日志输出中的范围,请在转换模式中使用%property {NDC}:

    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />

log4net.ThreadContext.Stacks

log4net.NDC (deprecated)

答案 1 :(得分:1)

NLog 具有嵌套诊断逻辑上下文 (NDLC),可以像这样使用:

using (NLog.NestedDiagnosticsLogicalContext.Push("First Level"))
{
    Run();
}

您可以在 Layout 输出中使用 ${ndlc} 提取 NLog 范围。

答案 2 :(得分:0)

Microsoft 扩展日志记录具有 ILogger.BeginScope() 方法。

你可以这样使用:

using (_logger.BeginScope("First Level"))
{
   _logger.LogDebug("Logon from {0}", request.UserId);
}

您可以在 Layout 输出中使用 ${ndlc} 提取 NLog 范围。

另见:https://github.com/NLog/NLog.Extensions.Logging/wiki/NLog-properties-with-Microsoft-Extension-Logging