Ведение журнала Serilog с ClassName, именем метода - PullRequest
0 голосов
/ 24 сентября 2018

Я использую serilog и SEQ в своем проекте Angular, web api, EF.Я новичок в обоих.

1) Как я могу убедиться, что каждый раз, когда я пишу ошибку, информация, отладка должна содержать ClassName.Method Name.Я знаю, что должен создать Enrich, но не уверен, как получить ClassName.Method Name

например

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

Теперь, когда я вижу журнал, он должен отображать "29/09/201210:00:00, Test => Ошибка тестирования ..... "

In, короткие DateTime, ClassName, MethodName и Message

1 Ответ

0 голосов
/ 25 сентября 2018

Чтобы получить имя метода автоматически при каждом вызове регистрации, вам нужно будет использовать обогреватель, который отражает весь стек вызовов (что очень дорого) для захвата имени метода.

Здесьпример, написанный @ 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!");

Пример того, как реализовать этот метод Here, можно увидеть в другом вопросе.здесь на StackOverflow: https://stackoverflow.com/a/46905798

...