Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions docs/core/extensions/custom-logging-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Implement a custom logging provider in .NET
description: Learn how to implement a custom logging provider in your .NET applications.
author: IEvangelist
ms.author: dapine
ms.date: 05/06/2021
ms.date: 06/22/2021
ms.topic: how-to
---

Expand All @@ -28,13 +28,15 @@ The `ILogger` implementation category name is typically the logging source. For
The preceding code:

- Creates a logger instance per category name.
- Checks `_config.LogLevels.ContainsKey(logLevel)` in `IsEnabled`, so each `logLevel` has a unique logger. Loggers should also be enabled for all higher log levels:
- Checks `_getCurrentConfig().LogLevels.ContainsKey(logLevel)` in `IsEnabled`, so each `logLevel` has a unique logger. Loggers should also be enabled for all higher log levels:

:::code language="csharp" source="snippets/configuration/console-custom-logging/ColorConsoleLogger.cs" range="16-17":::

The logger is instantiated with the `name` and a `Func<ColorConsoleLoggerConfiguration>` which will return the current config &mdash; this handles updates to the config values as monitored through the <xref:Microsoft.Extensions.Options.IOptionsMonitor%601.OnChange%2A?displayProperty=nameWithType> callback.

## Custom logger provider

The `ILoggerProvider` object is responsible for creating logger instances. Maybe it is not needed to create a logger instance per category, but this makes sense for some loggers, like NLog or log4net. Doing this you are also able to choose different logging output targets per category if needed:
The `ILoggerProvider` object is responsible for creating logger instances. It's not necessary to create a logger instance per category, but it makes sense for some loggers, like NLog or log4net. This strategy allows you to choose different logging output targets per category, as in the following example:

:::code language="csharp" source="snippets/configuration/console-custom-logging/ColorConsoleLoggerProvider.cs":::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
public class ColorConsoleLogger : ILogger
{
private readonly string _name;
private readonly ColorConsoleLoggerConfiguration _config;
private readonly Func<ColorConsoleLoggerConfiguration> _getCurrentConfig;

public ColorConsoleLogger(
string name,
ColorConsoleLoggerConfiguration config) =>
(_name, _config) = (name, config);
Func<ColorConsoleLoggerConfiguration> getCurrentConfig) =>
(_name, _getCurrentConfig) = (name, getCurrentConfig);

public IDisposable BeginScope<TState>(TState state) => default;

public bool IsEnabled(LogLevel logLevel) =>
_config.LogLevels.ContainsKey(logLevel);
_getCurrentConfig().LogLevels.ContainsKey(logLevel);

public void Log<TState>(
LogLevel logLevel,
Expand All @@ -28,11 +28,12 @@ public void Log<TState>(
return;
}

if (_config.EventId == 0 || _config.EventId == eventId.Id)
ColorConsoleLoggerConfiguration config = _getCurrentConfig();
if (config.EventId == 0 || config.EventId == eventId.Id)
{
ConsoleColor originalColor = Console.ForegroundColor;

Console.ForegroundColor = _config.LogLevels[logLevel];
Console.ForegroundColor = config.LogLevels[logLevel];
Console.WriteLine($"[{eventId.Id,2}: {logLevel,-12}]");

Console.ForegroundColor = originalColor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ public ColorConsoleLoggerProvider(
}

public ILogger CreateLogger(string categoryName) =>
_loggers.GetOrAdd(categoryName, name => new ColorConsoleLogger(name, _currentConfig));
_loggers.GetOrAdd(categoryName, name => new ColorConsoleLogger(name, GetCurrentConfig));

private ColorConsoleLoggerConfiguration GetCurrentConfig() => _currentConfig;

public void Dispose()
{
Expand Down