Serilog - Output/Enrich All Messages with MethodName from which log entry was Called

耗尽温柔 提交于 2019-11-27 00:58:19

问题


Is there anyway to enrich all Serilog output with the Method Name.

For Instance consider If I have the following;

Public Class MyClassName

  Private Function MyFunctionName() As Boolean
      Logger.Information("Hello World")
      Return True
  End Function

End Class

The desired output would be as follows;

2015-04-06 18:41:35.361 +10:00 [Information] [MyFunctionName] Hello World!

Actually the Fully Qualified Name would be good.

2015-04-06 18:41:35.361 +10:00 [Information] [MyClassName.MyFunctionName] Hello World!

It seems that "Enrichers" are only good for Static Information and won't work each time.


回答1:


It's possible to do this with an enricher by reflecting over the call stack, but very expensive to do so, so Serilog doesn't offer it.

Instead you can use something like:

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

and implement the Here() method as an extension method on ILogger:

<Extension>
Public Sub Here(ByVal logger as ILogger,
    <CallerMemberName> Optional memberName As String = Nothing)

    Return logger.ForContext("MemberName", memberName)
End Sub 



回答2:


in case you need a version in C#:

public static class LoggerExtensions
{
    public static ILogger Here(this ILogger logger,
        [CallerMemberName] string memberName = "",
        [CallerFilePath] string sourceFilePath = "",
        [CallerLineNumber] int sourceLineNumber = 0) {
        return logger
            .ForContext("MemberName", memberName)
            .ForContext("FilePath", sourceFilePath)
            .ForContext("LineNumber", sourceLineNumber);
    }
}

use like this:

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

Remember to add those properties in the message template. You can use something like this:

var outputTemplate = "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}in method {MemberName} at {FilePath}:{LineNumber}{NewLine}{Exception}{NewLine}";

Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Warning()
            .Enrich.FromLogContext()
            .WriteTo.RollingFile("log/{Date}.log", outputTemplate, LogEventLevel.Warning)
            .WriteTo.Console(LogEventLevel.Warning, outputTemplate, theme: AnsiConsoleTheme.Literate)
            .CreateLogger();



回答3:


In outputTemplate for the Serilog , configure for logs to write Properties. Method name will be written as part of ActionName column.

ActionName can also be configured individually (instead of all properties) in outputTemplate.

Configuring Properties/ActionName will write the method name in Namespace.ClassName.MethodName format.




回答4:


The version on C# could be simplified. Just use AutofacSerilogIntegration:

var path = Server.MapPath("~/");

        var outputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext} {Message} {NewLine}{Exception}";
        Log.Logger = new LoggerConfiguration()
                    .MinimumLevel.Debug()
                    .WriteTo.File($"{path}/log/serilog-.log", LogEventLevel.Debug, outputTemplate, rollingInterval: RollingInterval.Day)
                    .CreateLogger();

        var builder = new ContainerBuilder();
        builder.RegisterLogger();  // from AutofacSerilogIntegration
        builder.RegisterControllers(typeof(MvcApplication).Assembly);
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));



回答5:


Based on MovGP0's answer (for C#),

I created a solution that doesn't require the Here()-Method in every line where you want to log, by simply adding a custom Log.cs-Class in the root namespace.

For more info see: https://gist.github.com/litetex/b88fe0531e5acea82df1189643fb1f79



来源:https://stackoverflow.com/questions/29470863/serilog-output-enrich-all-messages-with-methodname-from-which-log-entry-was-ca

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!