Author : MD TAREQ HASSAN | Updated : 2020/09/08
Class Name
Using ForContext
SourceContext
property in outputTemplate- Use
ForContext
while creating logger - Links:
- Source Contexts: https://github.com/serilog/serilog/wiki/Writing-Log-Events#source-contexts
- Corelating logs:
- https://github.com/serilog/serilog/wiki/Writing-Log-Events#correlation
- https://benfoster.io/blog/serilog-best-practices/ (search ‘Correlating logs’)
appsettings.Development.json
{
"Serilog": {
"MinimumLevel": "Warning",
"Enrich": [
"FromLogContext"
],
"Properties": {
"ApplicationName": "HoverApp"
},
"Using": [ "Serilog.Sinks.File" ],
"WriteTo": [
{
"Name": "File",
"Args": {
"outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm:ss} {Level:u10}] {SourceContext:l} {Message:lj} {NewLine}{Exception}{NewLine}",
"path": "C:/Serilog/HoverApp.log",
"rollingInterval": "Day",
"shared": "true",
"fileSizeLimitBytes": "1000000",
"rollOnFileSizeLimit": true,
"flushToDiskInterval": "1"
}
}
]
}
}
Creating logger and using it
protected readonly ILogger _logger = Log.ForContext<DeleteBase>();
protected override async Task OnInitializedAsync()
{
// ... ... ...
// use _logger
}
Simplifying by extension method
using Serilog;
namespace Serilog {
static class SerilogForContextExtensions {
public static ILogger ForClass<T>(this ILogger that) => that.ForContext(Serilog.Core.Constants.SourceContextPropertyName, typeof(T).Name);
}
}
static class Logger {
public static ILogger ForClass<T>() => Log.Logger.ForContext(Serilog.Core.Constants.SourceContextPropertyName, typeof(T).Name);
}
// usage
class Thing{
static ILogger _log = Logger.ForClass<Thing>();
// ... ... ...
}
Using Dependency Injection
- StackOverflow Question: https://stackoverflow.com/questions/48470090/serilog-format-sourcecontext-for-showing-only-assembly-name
- Working Answer: https://stackoverflow.com/a/48473441/4802664
Method name and line number
LoggerExtensions.cs
using System;
using System.Runtime.CompilerServices;
using Serilog;
using Serilog.Context;
public static class LoggerExtensions
{
public static void LogAppError(this ILogger logger, Exception exception, string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
using var prop = LogContext.PushProperty("Method", memberName);
LogContext.PushProperty("FilePath", sourceFilePath);
LogContext.PushProperty("LineNumber", sourceLineNumber);
logger.Error(exception, message);
}
public static void LogAppWarning(this ILogger logger, string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
using var prop = LogContext.PushProperty("Method", memberName);
LogContext.PushProperty("FilePath", sourceFilePath);
LogContext.PushProperty("LineNumber", sourceLineNumber);
logger.Warning(message);
}
}
outputTemplate in appsettings.Development.json
{
"Serilog": {
"MinimumLevel": "Warning",
"Enrich": [
"FromLogContext"
],
"Properties": {
"ApplicationName": "HoverApp"
},
"Using": [ "Serilog.Sinks.File" ],
"WriteTo": [
{
"Name": "File",
"Args": {
"outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm:ss} {Level:u10}] [Line: {LineNumber}, Method: {Method}, Class: {SourceContext:l}] {Message:lj} {NewLine}{Exception}{NewLine}",
"path": "C:/Serilog/HoverApp.log",
"rollingInterval": "Day",
"shared": "true",
"fileSizeLimitBytes": "1000000",
"rollOnFileSizeLimit": true,
"flushToDiskInterval": "1"
}
}
]
}
}
Use ForContext in BaseComponent to set class name
using static Serilog.Logger
public class BaseComponent: ComponentBase, IDisposable
{
// ... ... ...
protected void InitDependencies()
{
Logger = ForContext("SourceContext", GetType().Name);
// setup other things i.e. DbContext
}
// ... ... ...
}
Using logger in page component
public class DeleteBase : BaseComponent
{
// ... ... ...
protected override async Task OnInitializedAsync()
{
InitDependencies();
// ... ... ...
}
protected async Task PerformDeletion()
{
// ... ... ...
try
{
var itemToDelete = await DbContext.Items.FindAsync(Id);
// EF Core Operations
DbContext.Items.Remove(itemToDelete);
await DbContext.SaveChangesAsync();
Logger.LogAppWarning("Item of {Id} was deleted", Id);
NavigationManager.NavigateTo("/items?deleted");
}
catch (Exception ex)
{
Logger.LogAppError("Error occured while attepmting to delete item");
}
}
// ... ... ...
}