使用类名,方法名的Serilog日志记录 [英] Serilog Logging with ClassName, Method Name

查看:87
本文介绍了使用类名,方法名的Serilog日志记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Angular,Web API,EF项目中使用serilog和SEQ.我都是新来的.

I am using serilog and SEQ in my project Angular,web api, EF. I am new to both.

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

1) How can I make sure every time I write error, information, debug it should contain ClassName.Method Name. I know I have to create Enrich but not sure how to get ClassName.Method Name

例如

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

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

Now,when I see the log it should display "29/09/2012 10:00:00, Test=>testing Error ....."

在简短的DateTime,ClassName,MethodName和Message中

In, short DateTime, ClassName , MethodName and Message

推荐答案

要在每个日志记录调用中自动获取方法名称,您必须使用可反映调用堆栈的扩展器(这样做非常昂贵)捕获方法名称.

To get the method name automatically on every logging call, you'll have to use an enricher that reflects over the call stack (which is very expensive to do) to capture the method name.

以下是 @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

You can see an example of how to implement this Here method on a different question here on StackOverflow: https://stackoverflow.com/a/46905798

这篇关于使用类名,方法名的Serilog日志记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆