Pooled NLogTestLoggerFactory for low-overhead unit testing
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
Research direction
The issue is about adding a pooled NLogTestLoggerFactory to NLog.Extensions.Logging. Start by examining the existing NLog.Extensions.Logging source, particularly the provider and factory classes. Look at how logging rules and MemoryTargets are configured. Understand the Microsoft.Extensions.Logging.ILogger integration and the existing test infrastructure. 'Done' means the factory can be rented from a pool, captures logs to a MemoryTarget, and cleans up safely, with appropriate exception handling and optional debugger support.
Written by the indexing model from the issue text.
Description
Add an NLogTestLoggerFactory to NLog.Extensions.Logging that makes it easy for unit tests to use a real Microsoft.Extensions.Logging.ILogger while capturing logs through an NLog MemoryTarget.
The primary goal is to make logging useful as test diagnostics, without encouraging tests to assert on log messages, properties, parameters, or exceptions as a way of verifying application behavior.
using var logging = NLogTestLoggerFactory.Rent();
var sut = new MyService(
repository,
logging.CreateLogger<MyService>());
await sut.DoSomething();
Assert.Equal(expected, result);
Assert.Empty(logging.DumpOnError());
The NLogTestLoggerFactory allocates an NLog MemoryTarget that captures all logevents (Bounded ringbuffer can be activated).
The NLogTestLoggerFactory.Rent() will allow unit-tests to execute faster without having the overhead from creating NLog LogFactory / NLog MemoryTarget-Buffer / etc. on every unit-test.
When NLogTestLoggerFactory is returned to pool, then the LoggingRules are cleared, and when calling CreateLogger a dedicated logging-rule is added with atomic-increment (matching only exactly matching that unique-logger-name). This is to protect against rogue background-tasks that continue logging after the unit-test have completed and returned to pool.
Guess the default NLogTestLoggerFactory.Rent() method will return instance-created-by-default-factory. If wanting to setup NLog LogFactory with different configuration, then one should inherit from NLogTestLoggerFactory and create new static Rent()-method that calls NLogTestLoggerFactory.Rent().
The NLogTestLoggerFactory Dispose will by default throw on exception, unless an exception is already in the wind:
private static bool IsExceptionUnwinding()
{
return Marshal.GetExceptionPointers() != IntPtr.Zero
|| Marshal.GetExceptionCode() != 0;
}
Should also have AddNLogTest() that by default removes all existing logger-providers, and by default uses NLogTestLoggerProvider.Rent(), where NLogTestLoggerProvider is allowed to throw on Dispose when exception/error logged.
Maybe the exception should be called: NLogUnexpectedErrorException
Maybe the NLogTestLoggerFactory should also support checking Debugger.IsAttached, and then setup DebuggerTarget with minLevel = Error (default LogLevel that can be adjusted). Maybe something like this Rent(bool throwOnError = false, LogLevel? debuggerAttachedLevel = null) should control whether to throw exceptions on dispose, or whether the caller handles inspection/checking for errors. And control if wanting to override the LogLevel for output-window when debugger-attached.
There should probably be two NLog MemoryTargets:
- Default lighweight NLog MemoryTarget
- Error-Only NLog MemoryTarget that includes ${stacktrace} - MaxLogCount = 1
Maybe also steal some ideas from Microsoft FakeLogger ? (Ex. DumpInitialError() to match FakeLogger-LatestRecord)
- Dominant language
- C#
- Stars
- 404
- Forks
- 149
- Avg merge
- 10h 59m
- Merged PRs (30d)
- 18
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from NLog/NLog.Extensions.Logging
-
feature up-for-grabs
Difficulty 3/5 1-2 days Newbie friendliness 35/100
NLog/NLog.Extensions.Logging#729 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement up-for-grabs
Difficulty 4/5 3-5 days Newbie friendliness 25/100
NLog/NLog.Extensions.Logging#667 ·
Maintainers usually reply within 1 day
All issues in NLog/NLog.Extensions.Logging
Similar issues
-
[中] 更新器下载缓存从不清理Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Remove duplicate Vimeo DI registration; use NimblePros.Vimeo AddVimeoServices and upgrade packageOpen
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
DevBetterCom/DevBetterWeb#1486 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
NimblePros/eShopOnWeb#333 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Natvs/Nt.Automaton#33 ·
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100