【问题标题】:Serilog Logging with ClassName, Method Name使用类名、方法名进行 Serilog 日志记录
【发布时间】:2018-09-24 06:44:46
【问题描述】:

我在我的项目 Angular、web api、EF 中使用 serilog 和 SEQ。我都是新手。

1) 如何确保每次写入错误、信息、调试时都应包含 ClassName.Method Name。我知道我必须创建 Enrich,但不确定如何获取 ClassName.Method Name

例如

Class Test
{
  public void testing(){
  // logger.Error("Error ....");}
}

现在,当我看到日志时,它应该显示“29/09/2012 10:00:00, Test=>testing Error .....”

In、短 DateTime、ClassName、MethodName 和 Message

【问题讨论】:

    标签: logging serilog


    【解决方案1】:

    要在每次记录调用时自动获取方法名称,您必须使用反映调用堆栈的丰富器(这样做非常昂贵)来捕获方法名称。

    这是@nblumhardt写的一个例子: https://github.com/serilog/serilog/issues/1084#issuecomment-358117004

    using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using Serilog;
    using Serilog.Configuration;
    using Serilog.Core;
    using Serilog.Events;
    
    namespace ConsoleApp24
    {
        class CallerEnricher : ILogEventEnricher
        {
            public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
            {
                var skip = 3;
                while (true)
                {
                    var stack = new StackFrame(skip);
                    if (!stack.HasMethod())
                    {
                        logEvent.AddPropertyIfAbsent(new LogEventProperty("Caller", new ScalarValue("<unknown method>")));
                        return;
                    }
    
                    var method = stack.GetMethod();
                    if (method.DeclaringType.Assembly != typeof(Log).Assembly)
                    {
                        var caller = $"{method.DeclaringType.FullName}.{method.Name}({string.Join(", ", method.GetParameters().Select(pi => pi.ParameterType.FullName))})";
                        logEvent.AddPropertyIfAbsent(new LogEventProperty("Caller", new ScalarValue(caller)));
                    }
    
                    skip++;
                }
            }
        }
    
        static class LoggerCallerEnrichmentConfiguration
        {
            public static LoggerConfiguration WithCaller(this LoggerEnrichmentConfiguration enrichmentConfiguration)
            {
                return enrichmentConfiguration.With<CallerEnricher>();
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Log.Logger = new LoggerConfiguration()
                    .Enrich.WithCaller()
                    .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message} (at {Caller}){NewLine}{Exception}")
                    .CreateLogger();
    
                Log.Information("Hello, world!");
    
                SayGoodbye();
    
                Log.CloseAndFlush();
            }
    
            [MethodImpl(MethodImplOptions.NoInlining)]
            static void SayGoodbye()
            {
                Log.Information("Goodbye!");
            }
        }
    }
    

    另一种选择(如果您只想在特定/更重要的位置捕获方法名称)是创建一个您可以调用的扩展方法,它将方法名称添加到日志记录上下文中......例如

    Logger.Here().Information("Hello, world!");
    

    您可以在 StackOverflow 上的另一个问题上看到如何实现此 Here 方法的示例: https://stackoverflow.com/a/46905798

    【讨论】:

    • 值得在上一个示例中标记为MethodImplOption.NoInlining 的助手中显示CallerMethodName
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2018-05-14
    • 1970-01-01
    • 2016-05-28
    相关资源
    最近更新 更多