I have a .NET 6 application with a Scoped service that holds data from the context running, like trace id, correlation id, etc., I want to use this data to enrich my log that is a structured json using Serilog lib overriding the ILoggerFactory.
I have a custom log Provider used in the Serilog LoggerConfiguration to format the text to json and inject data from this Scoped service, the problem is that logger is a singleton and I can not access this scoped object inside it.
I can not use IHttpContextAccessor because usually the code running on it is a BackgroundService to read some Queue's not an HTTP Request, and I can not use the ServiceProvider to create a scope, because I would lose the real current scope.
internal class CustomFormatter : ITextFormatter
{
private readonly ILogProvider _provider;
private readonly IServiceProvider _serviceProvider;
static readonly JsonSerializerSettings _jsonOptions = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
public CustomFormatter(ILogProvider provider, IServiceProvider serviceProvider)
{
_provider = provider;
_serviceProvider = serviceProvider;
}
public void Format(LogEvent logEvent, TextWriter output)
{
var logObj = _provider.Create(logEvent);
// Error in this line, since ICustomContext is a scoped object
var customContext = _serviceProvider.GetRequiredService<ICustomContext>();
logObj.CorrelationId = customContext.correlationId;
output.WriteLine(JsonConvert.SerializeObject(logObj, _jsonOptions));
}
}
ILoggerFactoryand call toAddProviderwhich will eventually sort out how to correctly referenceIHttpContextAccessor