Closed zmira closed 4 years ago
Hi José, apologies for the delay.
I'm really glad of your interest into this library.
The goal of this library is to have a generic test functionality for logs produced by any app or library through the Microsoft.Extensions.Logging, not tied to any specific implementation.
However, while this holds well for libraries, I understand that when writing applications it could make sense to rely on specific features of the logger implementation.
Currently, if you are looking for the structured properties, you could verify for the property named "@something" and verify that it holds the object you are after, however there is no way to test that the message will contain the destructured content, as this library works at the level of Microsoft Extensions Logging.
I was however working in adding example and docs on how to use this in combination with Serilog
and you question has motivated me to investigate how to support testing when Serilog
is setup to replace the Microsoft.Extensions.Logging
Logger
s.
I would hopefully have it merged in a few days (work is in #8).
I have a question for you: are you looking to add this in a ASP.NET Core application? if so, do you integrate Serilog using Serilog.AspNetCore
or Serilog.Extensions.Logging
?
Thank you, Alessio
Hi. Thanks for the reply.
I actually don't need the content of the @ variable, since I am validating the logged message based on a string template. But I was curious to know if the destructuring operator was ever applied.
Yes, this is being used in ASP.NET Core applications, and Serilog is integrated using Serilog.AspNetCore
.
When using Serilog.AspNetCore
you have to set up Serilog to use the Microsoft.Estensions.Logging
providers, in your Program.cs
:
public static readonly LoggerProviderCollection Providers = new LoggerProviderCollection();
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseStartup<Startup>()
.UseSerilog(providers: Providers);
});
You then have to set up Serilog in the tests, specifying to use the providers, for example using a custom factory.
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup>
where TStartup : class
{
public CustomWebApplicationFactory()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Providers(Program.Providers)
.CreateLogger();
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseTestLogging(options =>
{
options.UseScopeFromProperties = true;
options.FilterByNamespace(nameof(YourNamespace));
});
}
protected override void Dispose(bool disposing)
{
if (true)
{
Log.CloseAndFlush();
}
}
}
You don't need to use a WebApplicationFactory<>
, you can do that in the initialization of your tests, but be aware that given the Serilog logger is setup on a static global property, you would have to limit multiple test classes to run in parallel (e.g. using [Collection("Serilog Test Collection")]
). This is also true if you use more then one WebApplicationFactory<>
.
Once it is setup, you can then assert a destructured messaged.
I am updating the README to add this istrcutions as well as looking into helpers to get the Scope (with Serilog it is in a property called Scope
) and the properties easily.
Let me know if this works for you!
Serilog has a destructuring operator
@
(https://nblumhardt.com/2016/02/serilog-tip-dont-serialize-arbitrary-objects/) which, when used, tells it to deserialize and log an object passed as argument, instead of simply callingToString()
.How do I tell MELT to use serilog in my tests so that the object destructuring takes place when writing the logs?