Dưới đây là một ví dụ
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
loggerFactory.AddCustomLogger(serviceProvider.GetService<IHttpContextAccessor>());
//
}
Tuỳ chỉnh Logger:
public class CustomLogProvider : ILoggerProvider
{
private readonly Func<string, LogLevel, bool> _filter;
private readonly IHttpContextAccessor _accessor;
public CustomLogProvider(Func<string, LogLevel, bool> filter, IHttpContextAccessor accessor)
{
_filter = filter;
_accessor = accessor;
}
public ILogger CreateLogger(string categoryName)
{
return new CustomLogger(categoryName, _filter, _accessor);
}
public void Dispose()
{
}
}
public class CustomLogger : ILogger
{
private string _categoryName;
private Func<string, LogLevel, bool> _filter;
private readonly IHttpContextAccessor _accessor;
public CustomLogger(string categoryName, Func<string, LogLevel, bool> filter, IHttpContextAccessor accessor)
{
_categoryName = categoryName;
_filter = filter;
_accessor = accessor;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return (_filter == null || _filter(_categoryName, logLevel));
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
if (formatter == null)
{
throw new ArgumentNullException(nameof(formatter));
}
var message = formatter(state, exception);
if (string.IsNullOrEmpty(message))
{
return;
}
message = $"{ logLevel }: {message}";
if (exception != null)
{
message += Environment.NewLine + Environment.NewLine + exception.ToString();
}
if(_accessor.HttpContext != null) // you should check HttpContext
{
message += Environment.NewLine + Environment.NewLine + _accessor.HttpContext.Request.Path;
}
// your implementation
}
}
public static class CustomLoggerExtensions
{
public static ILoggerFactory AddCustomLogger(this ILoggerFactory factory, IHttpContextAccessor accessor,
Func<string, LogLevel, bool> filter = null)
{
factory.AddProvider(new CustomLogProvider(filter, accessor));
return factory;
}
}
Mặc dù trên cách làm việc, tôi muốn thực hiện tùy chỉnh IRequestLogger
thay vì tiêm HttpContextAccessor
. Thực hiện là như dưới đây (nó không được kiểm tra):
public interface IRequestLogger<T>
{
void Log(LogLevel logLevel, EventId eventId, string message); // you can change this
}
public class RequestLogger<T> : IRequestLogger<T>
{
private readonly IHttpContextAccessor _accessor;
private readonly ILogger _logger;
public RequestLogger(ILogger<T> logger, IHttpContextAccessor accessor)
{
_accessor = accessor;
_logger = logger;
}
public void Log(LogLevel logLevel, EventId eventId, string message)
{
Func<object, Exception, string> _messageFormatter = (object state, Exception error) =>
{
return state.ToString();
};
_logger.Log(LogLevel.Critical, 0, new FormattedLogValues(message), null, _messageFormatter);
}
}
Và việc sử dụng đơn giản:
public class LogType
{
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton(typeof(IRequestLogger<>), typeof(RequestLogger<>));
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(true);
app.Run(async (context) =>
{
var requestLogger = context.RequestServices.GetService<IRequestLogger<LogType>>();
requestLogger.Log(LogLevel.Critical, 11, "<message>");
//
});
}
Xin lỗi, tôi đăng câu trả lời của tôi và sau đó nhìn thấy bạn đánh bại tôi vào nó. Điều này là hoàn chỉnh hơn anyway, vì vậy tôi đã bỏ phiếu nó lên. –