问题
I am using serilog and SEQ in my project Angular,web api, EF. I am new to both.
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
for example
Class Test
{
public void testing(){
// logger.Error("Error ....");}
}
Now,when I see the log it should display "29/09/2012 10:00:00, Test=>testing Error ....."
In, short DateTime, ClassName , MethodName and Message
回答1:
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.
Here is an example written by @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!");
}
}
}
Another alternative (if you only want to capture the method name in specific/more important places), is to create an extension method that you can call, which will add the method name to the logging context... E.g.
Logger.Here().Information("Hello, world!");
You can see an example of how to implement this Here
method on a different question here on StackOverflow:
https://stackoverflow.com/a/46905798
来源:https://stackoverflow.com/questions/52473924/serilog-logging-with-classname-method-name