serilog-contrib / SerilogSinksInMemory

In-memory sink for Serilog to use for testing
MIT License
53 stars 7 forks source link

Mention in the README.md that InMemorySink.Instance is AsyncLocal #26

Open hiredgunhouse opened 2 years ago

hiredgunhouse commented 2 years ago

It is not mentioned in the README.md that InMemorySink.Instance is actually AsyncLocal which is quite important piece of information. I thought that InMemorySink.Instance is buggy when it was not behaving as I was expected: Instance is typically a singleton. I only discovered that important fact through issues.

Also you could mention that it is possibly important if you mix InMemorySink with integration tests based on WebApplicationFactory, that was my use-case where the AsyncLocal completely surprised me.

BTW. So far I love it, thank you for your contribution, InMemorySink combined with the assertion library turns tests into little things of beauty :)

sandermvanvliet commented 2 years ago

Thanks for the feedback @hiredgunhouse!

I’ve not been focusing a lot on the package recently but should have some time soon to add some updates including some better docs around the thread safety and async local stuff.

I had been experimenting with something a bit more robust but that proves very difficult depending on test framework as well as the logger itself but I agree better docs would be helpful 👍

Skulblaka commented 1 year ago

I'm also using InMemorySink with WebApplicationFactory and ran into probably the same problem as @hiredgunhouse. What does your solution look like?

I ended up creating a separate instance of InMemorySink and registering it in the DI container (since we're using ReadFrom.Configuration anyway) using _factory.WithWebHostBuilder(builder => builder.ConfigureServices(services => services.AddSingleton<ILogEventSink>(sink))) for each test...

sandermvanvliet commented 1 year ago

That is the better approach and guarantees you’ve got isolated instances.

michaeltg17 commented 4 months ago

I tried to use the static InMemorySink.Instance but got nothing logged. I ended up creating a new InMemorySink instance for each test (in the test class constructor) and assigning it to a property in WebApplicationFactoryFixture. There it is being used when creating the host using the Map sink because otherwise I only get the first test logged.

configuration.WriteTo.Map(
    _ => InMemorySink,
    (_, writeTo) => writeTo.Sink(InMemorySink),
    sinkMapCountLimit: 1);

Maybe there is a better way...

In any case, great sink!