Is there anyway to enrich all Serilog output with the Method Name.
For Instance consider If I have the following;
Public Class MyClassName
Privat
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.
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));
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:
// at the beginning of the class
private static Serilog.ILogger Log => Serilog.Log.ForContext<MyClass>();
// in the method
Log.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();
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
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 into the "root namespace" of a project.
For more info see: https://gist.github.com/litetex/b88fe0531e5acea82df1189643fb1f79