这完全没问题。通常,实例化一个记录器很便宜,所以在性能方面完全可以这样做。
不过,请考虑 (1) 使用 Serilog 拥有的全局日志实例或 (2) 使用在字段声明中初始化的静态字段。同样,不是出于性能原因,而是为了避免用不那么相关的东西污染您的构造函数。
UPD 实施更新 (1)
基本上,这只是决定将记录器初始化代码放在哪里的问题。在 ASP.NET Core 中,它将是 Main 方法的第一行(Log 是来自 Serilog 命名空间的静态类):
Log.Logger = new LoggerConfiguration().WriteTo.LiterateConsole(LogEventLevel.Debug, LogTemplate)
.WriteTo.File(@"C:\logs\elbakogdabot.log", LogEventLevel.Debug, LogTemplate)
.Enrich.FromLogContext()
.CreateLogger();
(为了清楚一点:我从我的一个真实项目中获取代码,但您的记录器的实际配置可能不同)。
然后我会像这样在任何地方使用它:
Log.Warning($"got a message for an unknown user: userid=[{userId}]");
这一行可以放入任何类中,您不必为该类进行任何额外的初始化。
UPD 实施更新 (2)
我想在典型的企业应用程序中,每次记录某些内容时始终记得将类名放在消息中会很不方便。所以我大部分时间都会使用static readonly 字段。使用 Serilog,您可以这样做:
public class XYZService
{
private static readonly Serilog.ILogger log = Log.ForContext<XYZService>();
...
这样你就不会污染构造函数,并且会自动在你的所有日志消息中获取类名。我曾经在 ReSharper sn-p 中有这一行,所以我只需要在每个新类中输入 lg<TAB>。