Pattern to use Serilog (pass ILogger vs using static Serilog.Log)

前端 未结 1 1444
情歌与酒
情歌与酒 2021-02-04 04:27

Background

In a new project where Serilog was chosen as the logger I automatically started passing around ILogger interface. The c

1条回答
  •  时光说笑
    2021-02-04 05:08

    There is also a ForContext on Log.Logger, so I would not decide on that basis. If you're doing mocking/testing of logging, you don't want to do that via the single global instance. Instead, any library code that will do logging should admit an ILogger parameter as input, enabling the caller to instrument and/or just pass in Log.Logger as they see fit (don't add defaulting to Log.Logger internally, for the same reasons that having a default constructor that auto-constructs dependencies that you're seeking to decouple from is a bad idea). If you don't do this, you won't be able to meaningfully test logging outputs are correct (because any concurrent tests that end up running in parallel will be writing to the exact same logger instance), which is a big thing to give up.

    For me, the main tradeoff is actually whether you're willing to use Enrich.FromLogContext and the LogContext.* interfaces, which hang state off the .NET ExecutionContext, which you need to be careful to not go crazy with. (Yes, arguably you can use a collector sequestered in the ExecutionContext to hack around my previous point, but don't even go there.)

    Depending on how your DI is rigged, you may want to take an ILogger in your inputs, but again, unless someone needs to be able to instrument to grab the info, having a static ILogger _logger = Log.ForContext() is fine as long as the Log is wired up early enough.

    0 讨论(0)
提交回复
热议问题