问题
Background
In a new project where Serilog was chosen as the logger I automatically started passing around ILogger
interface. The code accesses Log.Logger
once and from then the classes that desire logging accept ILogger
via constructor injection.
I was challenged on this practice and the advice was to use the static methods on the Log
class, e.g. Serilog.Log.Debug(...)
. The argument is that there is a set;
on Log.Logger
so mocking is easy.
Looking at the api I can see that one of the benefits of passing ILogger
are the ForContext
methods.
I spent some time on the webs and in the Serilog's documentation but I could not find information about a canonical way to access the log throughout the application code.
Question
Is there a canonical, i.e. better-in-most-cases, way to access/pass around the Serilog logger and if there is, is it passing ILogger
or using the static api on the Serilog.Log
class?
回答1:
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 global instance - any library code which will do logging in this way should require a ILogger
as input, allowing the caller to instrument and/or just pass in Log.Logger
as they see fit. If you don't do this, the tests can never run in parallel, 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<T>
in your inputs, but again, unless someone needs to be able to instrument to grab the info, having a static ILogger _logger = Log.ForContext<MyClass>()
is fine as long as the Log
is wired up early enough.
来源:https://stackoverflow.com/questions/50712720/pattern-to-use-serilog-pass-ilogger-vs-using-static-serilog-log