Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The logger specified through the options is not the one actually used to log requests #324

Open
ydie22 opened this issue Apr 25, 2023 · 4 comments

Comments

@ydie22
Copy link

ydie22 commented Apr 25, 2023

Description
When specifying a logger through the Logger property of the options, it appears that this logger is not the one that will be used to log requests.

Reproduction
app.UseSerilogRequestLogging(options => { options.Logger = myLogger; });
Expected behavior
I expect that the middleware will directly use the logger instance provided through the options. However, it appears that the middleware calls a ForContext() on that logger to obtain the logger it will use. Therefore, the configuration of the provided logger is ignored, as it is not used.

Relevant package, tooling and runtime versions
.NET 6, Serilog.AspNetCore 6.1.0

Additional context
I was expecting to be able to use a logger for a context controlled outside of the middleware, as we are logging requests (for other protocols than HTTP) at other places in our apps and therefore have more general configuration than just the Serilog middleware context.

@ydie22 ydie22 added the bug label Apr 25, 2023
@nblumhardt
Copy link
Member

Thanks for the note. This is by design, but I can see where it could be surprising.

To mark your HTTP request logger, though, rather than use ForContext<T> (which the current implementation overrides), could you use ForContext("Protocol", "HTTP") to construct myLogger?

Any additional context like this, apart from the source type name, will be preserved by the middleware.

@ydie22
Copy link
Author

ydie22 commented Apr 27, 2023

Thanks for your quick reaction. Indeed I could use additional context like you suggested, but wouldn't I then lose the ability to define minimum level overrides for the logger I intend to use, as part of the logger hierarchy I'm defining? If my understanding is correct those overrides are applied using the source context, and the one being actually used is the one bound to Serilog's middleware type.
To be honest, I'm currently using a workaround consisting of using a decorator around ILogger that returns the logger implementation I'd like to use when ForContext is being called. Kind of a hack, but it does the job. I was just surprised that ForContext was called, and my logger ending up not being used actually. I can live with it if this is by design, but maybe the doc could be slightly updated, and the motivation for doing this made clear?

@nblumhardt
Copy link
Member

Thanks for the thoughtful reply; I can see how this is awkward.

Creating a whole new logging pipeline for the middleware that applies levelling and forwards to the "main" logger is another viable workaround:

var middlewareLogger = new LoggerConfiguration()
    .MinimumLevel.Warning()
    .WriteTo.Logger(Log.Logger)
    .CreateLogger();

There's not actually a lot of overhead with this approach, and it does save you from having to wrap ILogger - let me know if it's an improvement :-)

I'll take a look at the docs 👍

@joacar
Copy link

joacar commented Sep 12, 2023

Looking at the code, there seem to be no way to change the source context used by the logger SerilogRequestMiddleware, am I right? It would be useful to have the source context set as the rest of the application since then I can use it for filtering. At the moment it is not possible without setting up additional data, such as attaching a variable to the API key that will be added upon ingestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants