Menerapkan penyedia pengelogan kustom di .NET
Terdapat banyak penyedia layanan pencatatan log tersedia untuk kebutuhan pencatatan log yang umum. Anda mungkin perlu menerapkan ILoggerProvider kustom ketika salah satu penyedia yang tersedia tidak sesuai dengan kebutuhan aplikasi Anda. Dalam artikel ini, Anda akan mempelajari cara menerapkan penyedia pengelogan kustom yang dapat digunakan untuk mewarnai log di konsol.
Nasihat
Contoh kode sumber penyedia pengelogan kustom tersedia di repositori GitHub Docs . Untuk informasi selengkapnya, lihat GitHub: .NET Docs - Console Custom Logging.
Contoh konfigurasi pencatat kustom
Sampel membuat entri konsol warna yang berbeda per tingkat log dan ID peristiwa menggunakan jenis konfigurasi berikut:
using Microsoft.Extensions.Logging;
public sealed class ColorConsoleLoggerConfiguration
{
public int EventId { get; set; }
public Dictionary<LogLevel, ConsoleColor> LogLevelToColorMap { get; set; } = new()
{
[LogLevel.Information] = ConsoleColor.Green
};
}
Kode sebelumnya mengatur tingkat default ke Information
, warna ke Green
, dan EventId
secara implisit 0
.
Membuat pencatat kustom
Nama kategori implementasi ILogger
biasanya merupakan sumber pengelogan. Misalnya, jenis pencatat yang dibuat:
using Microsoft.Extensions.Logging;
public sealed class ColorConsoleLogger(
string name,
Func<ColorConsoleLoggerConfiguration> getCurrentConfig) : ILogger
{
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => default!;
public bool IsEnabled(LogLevel logLevel) =>
getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel);
public void Log<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception? exception,
Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
ColorConsoleLoggerConfiguration config = getCurrentConfig();
if (config.EventId == 0 || config.EventId == eventId.Id)
{
ConsoleColor originalColor = Console.ForegroundColor;
Console.ForegroundColor = config.LogLevelToColorMap[logLevel];
Console.WriteLine($"[{eventId.Id,2}: {logLevel,-12}]");
Console.ForegroundColor = originalColor;
Console.Write($" {name} - ");
Console.ForegroundColor = config.LogLevelToColorMap[logLevel];
Console.Write($"{formatter(state, exception)}");
Console.ForegroundColor = originalColor;
Console.WriteLine();
}
}
}
Kode sebelumnya:
- Membuat instans pencatat per nama kategori.
- Memeriksa
_getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel)
diIsEnabled
, sehingga setiaplogLevel
memiliki perekam unik. Dalam implementasi ini, setiap tingkat log memerlukan entri konfigurasi eksplisit untuk dicatat.
Ini adalah praktik yang baik untuk memanggil ILogger.IsEnabled dalam implementasi ILogger.Log karena Log
dapat dipanggil oleh konsumen mana pun, dan tidak ada jaminan bahwa itu sebelumnya diperiksa. Metode IsEnabled
harus sangat cepat dalam sebagian besar implementasi.
TState state,
Exception? exception,
Logger dibuat dengan name
dan Func<ColorConsoleLoggerConfiguration>
, yang mengembalikan konfigurasi saat iniāini menangani pembaruan nilai konfigurasi yang dipantau melalui callback IOptionsMonitor<TOptions>.OnChange.
Penting
Implementasi ILogger.Log memeriksa apakah nilai config.EventId
ditetapkan. Ketika config.EventId
tidak diatur atau ketika sesuai tepat dengan logEntry.EventId
, log dicatat dalam warna.
Penyedia pencatat kustom
Objek ILoggerProvider
bertanggung jawab untuk membuat instans pencatat. Tidak perlu membuat instans pencatat per kategori, tetapi masuk akal untuk beberapa pencatat, seperti NLog atau log4net. Strategi ini memungkinkan Anda memilih target output pengelogan yang berbeda per kategori, seperti dalam contoh berikut:
using System.Collections.Concurrent;
using System.Runtime.Versioning;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
[UnsupportedOSPlatform("browser")]
[ProviderAlias("ColorConsole")]
public sealed class ColorConsoleLoggerProvider : ILoggerProvider
{
private readonly IDisposable? _onChangeToken;
private ColorConsoleLoggerConfiguration _currentConfig;
private readonly ConcurrentDictionary<string, ColorConsoleLogger> _loggers =
new(StringComparer.OrdinalIgnoreCase);
public ColorConsoleLoggerProvider(
IOptionsMonitor<ColorConsoleLoggerConfiguration> config)
{
_currentConfig = config.CurrentValue;
_onChangeToken = config.OnChange(updatedConfig => _currentConfig = updatedConfig);
}
public ILogger CreateLogger(string categoryName) =>
_loggers.GetOrAdd(categoryName, name => new ColorConsoleLogger(name, GetCurrentConfig));
private ColorConsoleLoggerConfiguration GetCurrentConfig() => _currentConfig;
public void Dispose()
{
_loggers.Clear();
_onChangeToken?.Dispose();
}
}
Dalam kode sebelumnya, CreateLogger membuat satu instans ColorConsoleLogger
per nama kategori dan menyimpannya di ConcurrentDictionary<TKey,TValue>
. Selain itu, antarmuka IOptionsMonitor<TOptions> diperlukan untuk memperbarui perubahan pada objek ColorConsoleLoggerConfiguration
yang mendasar.
Untuk mengontrol konfigurasi ColorConsoleLogger
, Anda menentukan alias pada penyedianya:
[UnsupportedOSPlatform("browser")]
[ProviderAlias("ColorConsole")]
public sealed class ColorConsoleLoggerProvider : ILoggerProvider
Kelas ColorConsoleLoggerProvider
mendefinisikan dua atribut cakupan kelas:
-
UnsupportedOSPlatformAttribute: Jenis
ColorConsoleLogger
tidak didukung di"browser"
. -
ProviderAliasAttribute: Bagian konfigurasi dapat menentukan opsi menggunakan kunci
"ColorConsole"
.
Konfigurasi dapat ditentukan dengan penyedia konfigurasi yang valid . Pertimbangkan file appsettings.json berikut:
{
"Logging": {
"ColorConsole": {
"LogLevelToColorMap": {
"Information": "DarkGreen",
"Warning": "Cyan",
"Error": "Red"
}
}
}
}
Ini mengonfigurasi tingkat log ke nilai berikut:
- LogLevel.Information: ConsoleColor.DarkGreen
- LogLevel.Warning: ConsoleColor.Cyan
- LogLevel.Error: ConsoleColor.Red
Tingkat log Information diatur ke DarkGreen, yang menggantikan nilai default yang diatur dalam objek ColorConsoleLoggerConfiguration
.
Penggunaan dan pendaftaran pencatat kustom
Menurut konvensi, mendaftarkan layanan untuk injeksi dependensi terjadi sebagai bagian dari rutinitas startup aplikasi. Pendaftaran terjadi di kelas Program
, atau dapat didelegasikan ke kelas Startup
. Dalam contoh ini, Anda akan mendaftar langsung dari Program.cs.
Untuk menambahkan penyedia pengelogan kustom dan pencatat terkait, tambahkan ILoggerProvider dengan ILoggingBuilder dari HostingHostBuilderExtensions.ConfigureLogging(IHostBuilder, Action<ILoggingBuilder>):
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddColorConsoleLogger(configuration =>
{
// Replace warning value from appsettings.json of "Cyan"
configuration.LogLevelToColorMap[LogLevel.Warning] = ConsoleColor.DarkCyan;
// Replace warning value from appsettings.json of "Red"
configuration.LogLevelToColorMap[LogLevel.Error] = ConsoleColor.DarkRed;
});
using IHost host = builder.Build();
var logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogDebug(1, "Does this line get hit?"); // Not logged
logger.LogInformation(3, "Nothing to see here."); // Logs in ConsoleColor.DarkGreen
logger.LogWarning(5, "Warning... that was odd."); // Logs in ConsoleColor.DarkCyan
logger.LogError(7, "Oops, there was an error."); // Logs in ConsoleColor.DarkRed
logger.LogTrace(5, "== 120."); // Not logged
await host.RunAsync();
ILoggingBuilder
membuat satu atau beberapa instans ILogger
. Instans ILogger
digunakan oleh kerangka kerja untuk mencatat informasi.
Konfigurasi dari file appsettings.json mengambil alih nilai berikut:
Menurut konvensi, metode ekstensi pada ILoggingBuilder
digunakan untuk mendaftarkan penyedia kustom:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Configuration;
public static class ColorConsoleLoggerExtensions
{
public static ILoggingBuilder AddColorConsoleLogger(
this ILoggingBuilder builder)
{
builder.AddConfiguration();
builder.Services.TryAddEnumerable(
ServiceDescriptor.Singleton<ILoggerProvider, ColorConsoleLoggerProvider>());
LoggerProviderOptions.RegisterProviderOptions
<ColorConsoleLoggerConfiguration, ColorConsoleLoggerProvider>(builder.Services);
return builder;
}
public static ILoggingBuilder AddColorConsoleLogger(
this ILoggingBuilder builder,
Action<ColorConsoleLoggerConfiguration> configure)
{
builder.AddColorConsoleLogger();
builder.Services.Configure(configure);
return builder;
}
}
Menjalankan aplikasi sederhana ini akan merender output warna ke jendela konsol yang mirip dengan gambar berikut: