自定义Asp.net core——日志记录

前言

本文我将演示如何定制日志记录。默认的日志记录仅仅向控制台或者debug窗口输出日志,这样可以满足一些情况,但是你可能还需要把日志记录到一个磁盘文件或者数据库,或者你想为记录额外的信息。这样的场景你就需要知道如何修改默认的日志记录。


配置日志记录

在asp.net core 2.0以前的版本,日志记录是在Startup.cs中,从2.0开始startup.cs被简化,并且把大量的配置代码转移到了webhostBuider中(3.0 是CreateDefaultBuilder)。同样日志记录配置也被转移到了该地方。

1
2
3
4
5
6
7
8
9
10
11
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}

在asp.net core 中你几乎可以修改所有的东西。所以你也能够定制日志记录。IHostBuilder有很多可以覆盖默认行为的扩展方法。我们需要用ConfigureLogging方法去覆盖日志记录的默认逻辑。下面在CreateDefaultBuilder插入的代码演示了如何配置日志记录

1
2
3
4
5
6
7
8
9

Host.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
})
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });

这个方法需要一个获取HostBuilderContext的lambda表达式,HostBuilderContext包含了用于配置日志的hosting context和一个LoggingBuilder。

创建一个自定义的logger

为了演示如何自定义logger,我创建一个简单的logger,这个logger能够把指定的日志等级用带颜色的文字输出到控制台。我们创建一个名为ColoredConsoleLogger的类,我们同样写一个LoggerProvider用来增加与创建上面的logger。为了把输出指定的颜色和日志等级,我们还需要增加一个配置类,下面代码包含了上述三部分的具体实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public class ColoredConsoleLoggerConfiguration
{
public LogLevel LogLevel { get; set; } = LogLevel.Warning;
public int EventId { get; set; } = 0;
public ConsoleColor Color { get; set; } = ConsoleColor.Yellow;
}

public class ColoredConsoleLoggerProvider : ILoggerProvider
{
private readonly ColoredConsoleLoggerConfiguration _config;

private readonly ConcurrentDictionary<string, ColoredConsoleLogger> _loggers =
new ConcurrentDictionary<string, ColoredConsoleLogger>();

public ColoredConsoleLoggerProvider(ColoredConsoleLoggerConfiguration config)
{
_config = config;
}

public ILogger CreateLogger(string categoryName)
{
return _loggers.GetOrAdd(categoryName, name => new ColoredConsoleLogger(name, _config));
}

public void Dispose()
{
_loggers.Clear();
}
}

public class ColoredConsoleLogger : ILogger
{
private static object _lock = new Object();
private readonly string _name;
private readonly ColoredConsoleLoggerConfiguration _config;

public ColoredConsoleLogger(string name, ColoredConsoleLoggerConfiguration config)
{
_name = name;
_config = config;
}

public IDisposable BeginScope<TState>(TState state)
{
return null;
}

public bool IsEnabled(LogLevel logLevel)
{
return logLevel == _config.LogLevel;
}

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}

lock (_lock)
{
if (_config.EventId == 0 || _config.EventId == eventId.Id)
{
var color = Console.ForegroundColor;
Console.ForegroundColor = _config.Color;
Console.WriteLine(
$"{logLevel.ToString()} - {eventId.Id} - {_name} - {formatter(state, exception)}");
Console.ForegroundColor = color;
}
}
}
}

我们需要对具体的控制台输出加上锁,因为控制台不是线程安全的。接下来我们就可以把自定义的logger添加到ConfigureLogging方法中了:

1
2
3
4
5
6
7
8
9

logging.ClearProviders();

var config = new ColoredConsoleLoggerConfiguration
{
LogLevel = LogLevel.Information,
Color = ConsoleColor.Red
};
logging.AddProvider(new ColoredConsoleLoggerProvider(config));

我们可以清除之前已经添加的logger provider,然后我们通过AddProvider增加一个指定对应的日志记录设置ColoredConsoleLoggerProvider实例。我们也可以增加其他不同日志记录设置的实例。下图我们就可以看到我们自定义日志记录的效果输出

avatar

文章目录
  1. 1. 前言
  2. 2. 配置日志记录
  3. 3. 创建一个自定义的logger
|