-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Background and motivation
Imagine you have logging setup so that all logging is supposed to be handled/go to one place. But some events you also want to handle separately.
.NET logging has support for that via multiple ILoggerProvider
all of which are used to create a composite logger and then all are invoked for every log event.
This is, however, not conditional. An ILoggerProvider must always provide an ILogger instance, no matter the category. And so, even if you need two (default and your additional one) ILogger (via default your additional one ILoggerProvider) only for one category, you still need to live with two Loggers for every category. Probably implementing it as returning NullLogger for every not-desired category.
This is rather wasteful.
API Proposal
namespace Microsoft.Extensions.Logging;
// Maybe it should be separate interface not "super" interface, I'm not sure how to decide which is better
public interface IMaybelLoggerProvider : ILoggerProvider // I'm not good at naming things 😅
{
/// <summary>
/// Create a new <see cref="ILogger"/> instance if provider wants to handle this <param=categoryName>.
/// </summary>
/// <param name="categoryName">The category name for messages produced by the logger.</param>
/// <returns>The instance of <see cref="ILogger"/> that was created or null.</returns>
ILogger? TryCreateLogger(string categoryName);
}
API Usage
public class MyLoggerProvider : IMaybelLoggerProvider
{
public ILogger CreateLogger(string categoryName) => new MyLogger();
public void Dispose() { }
public ILogger? TryCreateLogger(string categoryName)
=> categoryName == "TheOnlyCategoryWeAreInterestedIn"
? CreateLogger(categoryName)
: null;
}
The LoggerFactory's LoggerInformation[] CreateLoggers(string categoryName)
would also be adjusted to only create loggers where the provider returns not-null. And to invoke the Try version if available.
Alternative Designs
Separate interface instead of super interface :).
Alternatively, you can always just produce null loger as right now.
Risks
Complicate the API surface which can cause user confusion.
Creating array of loggers in performant and minimal-alloc (just the resulting array) will be more complex to do, as before running each provider the final amount of loggers is not known.