Školení
Modul
Formátování alfanumerických dat pro prezentaci v jazyce C# - Training
Prozkoumejte základní metody v jazyce C# pro formátování alfanumerických dat.
Tento prohlížeč se už nepodporuje.
Upgradujte na Microsoft Edge, abyste mohli využívat nejnovější funkce, aktualizace zabezpečení a technickou podporu.
.NET podporuje vysoké výkonné strukturované protokolování prostřednictvím ILogger rozhraní API, které pomáhá monitorovat chování aplikací a diagnostikovat problémy. Protokoly je možné zapisovat do různých cílů konfigurací různých poskytovatelů protokolování. Základní zprostředkovatelé protokolování jsou integrované a k dispozici je také mnoho poskytovatelů třetích stran.
Tento první příklad ukazuje základy, ale je vhodný pouze pro triviální konzolovou aplikaci. Tato ukázková konzolová aplikace spoléhá na následující balíčky NuGet:
V další části se dozvíte, jak zlepšit kód s ohledem na škálování, výkon, konfiguraci a typické programovací vzory.
using Microsoft.Extensions.Logging;
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger("Program");
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
Předchozí příklad:
ILoggerFactory
veškerou konfiguraci, která určuje, kam se odesílají zprávy protokolu. V takovém případě nakonfigurujete zprostředkovatele protokolování konzoly tak, aby zprávy protokolu byly zapsány do konzoly.string
ke každé zprávě protokolované objektemILogger
. Používá se k seskupení zpráv protokolu ze stejné třídy (nebo kategorie) společně při vyhledávání nebo filtrování protokolů.Information
úrovni Úroveň protokolu označuje závažnost protokolované události a používá se k odfiltrování méně důležitých zpráv protokolu. Položka protokolu obsahuje také šablonu "Hello World! Logging is {Description}."
zprávy a pár Description = fun
klíč-hodnota . Název klíče (nebo zástupný symbol) pochází z slova uvnitř složených závorek v šabloně a hodnota pochází ze zbývajícího argumentu metody.Tento soubor projektu v tomto příkladu obsahuje dva balíčky NuGet:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
</ItemGroup>
</Project>
Tip
Veškerý zdrojový kód příkladu protokolování je k dispozici v prohlížeči ukázek ke stažení. Další informace najdete v tématu Procházení ukázek kódu: Protokolování v .NET.
Při protokolování v méně triviálním scénáři byste měli zvážit provedení několika změn v předchozím příkladu:
Pokud vaše aplikace používá injektáž závislostí (DI) nebo hostitele, jako je ASP. WebApplication nebo Generic Host technologie NET pak byste měli místo jejich přímého vytváření použít ILoggerFactory
a ILogger
objekty z příslušných kontejnerů DI. Další informace najdete v tématu Integrace s DI a hostiteli.
Protokolování generování zdroje času kompilace je obvykle lepší alternativou k ILogger
rozšiřujícím metodám, jako je LogInformation
. Generování zdroje protokolování nabízí lepší výkon, silnější psaní a zabraňuje šíření string
konstant v rámci vašich metod. Nevýhodou je, že použití této techniky vyžaduje trochu více kódu.
using Microsoft.Extensions.Logging;
internal partial class Program
{
static void Main(string[] args)
{
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger("Program");
LogStartupMessage(logger, "fun");
}
[LoggerMessage(Level = LogLevel.Information, Message = "Hello World! Logging is {Description}.")]
static partial void LogStartupMessage(ILogger logger, string description);
}
Type
snadného pojmenování.using Microsoft.Extensions.Logging;
internal class Program
{
static void Main(string[] args)
{
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger<Program>();
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
}
}
using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs;
using ILoggerFactory factory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(logging =>
{
logging.AddOtlpExporter();
});
});
ILogger logger = factory.CreateLogger("Program");
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
Pokud vaše aplikace používá injektáž závislostí (DI) nebo hostitele, jako je ASP. WebApplication nebo Generic Host technologie NET pak byste měli místo přímého vytváření použít ILoggerFactory
a ILogger
objekty z kontejneru DI.
Tento příklad získá objekt ILogger v hostované aplikaci pomocí ASP.NET minimálních rozhraní API:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ExampleHandler>();
var app = builder.Build();
var handler = app.Services.GetRequiredService<ExampleHandler>();
app.MapGet("/", handler.HandleRequest);
app.Run();
partial class ExampleHandler(ILogger<ExampleHandler> logger)
{
public string HandleRequest()
{
LogHandleRequest(logger);
return "Hello World";
}
[LoggerMessage(LogLevel.Information, "ExampleHandler.HandleRequest was called")]
public static partial void LogHandleRequest(ILogger logger);
}
Předchozí příklad:
ExampleHandler
a mapovala příchozí webové požadavky pro spuštění ExampleHandler.HandleRequest
funkce.ILogger<ExampleHandler>
. ILogger<TCategoryName> je odvozen od ILogger a označuje, která kategorie ILogger
objekt má. Kontejner DI vyhledá ILogger
správnou kategorii a poskytne ji jako argument konstruktoru. Pokud tato kategorie ještě neexistuje ILogger
, kontejner DI ho ILoggerFactory
automaticky vytvoří z poskytovatele služeb.logger
přijatý v konstruktoru byl použit pro protokolování funkce HandleRequest
.Tvůrci hostitelů inicializují výchozí konfiguraci a po sestavení hostitele pak do kontejneru DI hostitele přidají nakonfigurovaný ILoggerFactory
objekt. Před vytvořením hostitele můžete upravit konfiguraci protokolování prostřednictvím HostApplicationBuilder.Loggingrozhraní , WebApplicationBuilder.Loggingnebo podobných rozhraní API na jiných hostitelích. Hostitelé také používají konfiguraci protokolování z výchozích zdrojů konfigurace jako appsettings.json a proměnné prostředí. Další informace naleznete v tématu Konfigurace v .NET.
Tento příklad se rozšiřuje na předchozí, aby přizpůsobil poskytnutého ILoggerFactory
uživatelem WebApplicationBuilder
. Přidá OpenTelemetry jako zprostředkovatele protokolování, který přenáší protokoly přes protokol OTLP (protokol OpenTelemetry):
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddOpenTelemetry(logging => logging.AddOtlpExporter());
builder.Services.AddSingleton<ExampleHandler>();
var app = builder.Build();
Pokud používáte kontejner DI bez hostitele, použijte AddLogging ke konfiguraci a přidání ILoggerFactory
do kontejneru.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
// Add services to the container including logging
var services = new ServiceCollection();
services.AddLogging(builder => builder.AddConsole());
services.AddSingleton<ExampleService>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
// Get the ExampleService object from the container
ExampleService service = serviceProvider.GetRequiredService<ExampleService>();
// Do some pretend work
service.DoSomeWork(10, 20);
class ExampleService(ILogger<ExampleService> logger)
{
public void DoSomeWork(int x, int y)
{
logger.LogInformation("DoSomeWork was called. x={X}, y={Y}", x, y);
}
}
Předchozí příklad:
ILoggerFactory
zápis do konzoly.ExampleService
do kontejneruExampleService
kontejneru DI, která také automaticky vytvořila ILogger<ExampleService>
použití jako argument konstruktoru.ExampleService.DoSomeWork
, které použilo ILogger<ExampleService>
k protokolování zprávy do konzoly.Konfigurace protokolování se nastavuje v kódu nebo prostřednictvím externích zdrojů, jako jsou konfigurační soubory a proměnné prostředí. Použití externí konfigurace je výhodné, pokud je to možné, protože se dá změnit bez opětovného sestavení aplikace. Některé úlohy, například nastavení zprostředkovatelů protokolování, se ale dají nakonfigurovat jenom z kódu.
Pro aplikace, které používají hostitele, se konfigurace protokolování běžně poskytuje v "Logging"
části souborů appsettings.{Environment}
.json. U aplikací, které nepoužívají hostitele, jsou externí zdroje konfigurace nastavené explicitně nebo nakonfigurované v kódu .
Následující nastavení aplikace. Development.json soubor je generován šablonami služby .NET Worker:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
V předchozím fragmentu kódu JSON:
"Default"
kategorie na úrovni protokolu "Microsoft"
a "Microsoft.Hosting.Lifetime"
."Default"
se použije pro všechny kategorie, které nejsou jinak zadány, a tím se efektivně nastaví všechny výchozí hodnoty pro všechny kategorie "Information"
. Toto chování můžete přepsat zadáním hodnoty pro kategorii."Microsoft"
se vztahuje na všechny kategorie, které začínají na "Microsoft"
."Microsoft"
se protokoluje na úrovni Warning
protokolu a vyšší."Microsoft.Hosting.Lifetime"
je konkrétnější než "Microsoft"
kategorie, takže "Microsoft.Hosting.Lifetime"
protokoly kategorií na úrovni "Information"
protokolu a vyšší.LogLevel
vztahuje na všechny povolené zprostředkovatele protokolování s výjimkou zprostředkovatele Windows EventLog.Vlastnost Logging
může obsahovat vlastnost LogLevel a vlastnosti zprostředkovatele protokolování. Vlastnost LogLevel
určuje minimální úroveň protokolování pro vybrané kategorie. V předchozím kódu JSON Information
a Warning
úrovně protokolu jsou zadané. Vlastnost LogLevel
označuje závažnost protokolu v rozsahu od 0 do 6:
Trace
= 0, Debug
= 1, Information
= 2, Warning
= 3, Error
= 4, Critical
= 5 a None
= 6.
Když je zadaná vlastnost LogLevel
, protokolování se povolí pro zprávy na zadané úrovni a vyšší. V předchozím kódu JSON Default
se kategorie zaprotokoluje a Information
je vyšší. Protokolují se například zprávy úrovně Information
, Warning
, Error
a Critical
. Pokud není zadaná žádná vlastnost LogLevel
, nastaví se výchozí úroveň protokolování Information
. Další informace najdete v části Úrovně protokolování.
Vlastnost LogLevel
může být zadaná ve vlastnosti zprostředkovatele. Vlastnost LogLevel
v rámci zprostředkovatele určuje úrovně protokolování pro daného zprostředkovatele a přepisuje nastavení protokolování pro všechny zprostředkovatele. Zvažte následující appsettings.json soubor:
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Warning"
},
"Debug": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting": "Trace"
}
},
"EventSource": {
"LogLevel": {
"Default": "Warning"
}
}
}
}
Nastavení ve vlastnosti Logging.{ProviderName}.LogLevel
přepíše nastavení ve vlastnosti Logging.LogLevel
. V předchozím kódu JSON Debug
je výchozí úroveň protokolu poskytovatele nastavená na Information
:
Logging:Debug:LogLevel:Default:Information
Výše uvedené nastavení určuje úroveň protokolování Information
pro všechny kategorie Logging:Debug:
s výjimkou kategorie Microsoft.Hosting
. Pokud je uvedená konkrétní kategorie, tato konkrétní kategorie přepíše výchozí kategorii. V předchozím kódu JSON Logging:Debug:LogLevel
kategorie "Microsoft.Hosting"
a "Default"
přepsání nastavení v Logging:LogLevel
Minimální úroveň protokolování je možné zadat pro:
Logging:EventSource:LogLevel:Default:Information
Logging:LogLevel:Microsoft:Warning
Logging:LogLevel:Default:Warning
Žádné protokoly pod minimální úrovní se:
Pokud chcete potlačit všechny protokoly, zadejte LogLevel.None. Vlastnost LogLevel.None
má hodnotu 6, která je vyšší než hodnota vlastnosti LogLevel.Critical
(5).
Pokud zprostředkovatel podporuje obory protokolování, vlastnost IncludeScopes
označuje, jestli jsou povolené. Další informace najdete v části Obory protokolování.
Následující soubor appsettings.json obsahuje nastavení pro všechny předdefinované zprostředkovatele:
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning"
},
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft.Extensions.Hosting": "Warning",
"Default": "Information"
}
},
"EventSource": {
"LogLevel": {
"Microsoft": "Information"
}
},
"EventLog": {
"LogLevel": {
"Microsoft": "Information"
}
},
"AzureAppServicesFile": {
"IncludeScopes": true,
"LogLevel": {
"Default": "Warning"
}
},
"AzureAppServicesBlob": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft": "Information"
}
},
"ApplicationInsights": {
"LogLevel": {
"Default": "Information"
}
}
}
}
Ve výše uvedené ukázce:
Logging.{ProviderName}.LogLevel
přepíše nastavení ve vlastnosti Logging.LogLevel
. Například úroveň ve vlastnosti Debug.LogLevel.Default
přepíše úroveň ve vlastnosti LogLevel.Default
.Console
Debug
EventSource
EventLog
AzureAppServicesFile
AzureAppServicesBlob
ApplicationInsights
Úroveň protokolování může nastavit jakýkoli zprostředkovatel konfigurace. Můžete například vytvořit trvalou proměnnou prostředí s názvem Logging:LogLevel:Microsoft
hodnota Information
.
Vytvořte a přiřaďte trvalou proměnnou prostředí vzhledem k hodnotě na úrovni protokolu.
:: Assigns the env var to the value
setx "Logging__LogLevel__Microsoft" "Information" /M
V nové instanci příkazového řádku načtěte proměnnou prostředí.
:: Prints the env var value
echo %Logging__LogLevel__Microsoft%
Předchozí nastavení prostředí je trvalé v prostředí. Pokud chcete otestovat nastavení při použití aplikace vytvořené pomocí šablon služby .NET Worker, použijte dotnet run
příkaz v adresáři projektu po přiřazení proměnné prostředí.
dotnet run
Tip
Po nastavení proměnné prostředí restartujte integrované vývojové prostředí (IDE), aby byly k dispozici nově přidané proměnné prostředí.
V Azure App Service vyberte Nové nastavení aplikace na stránce Nastavení > Konfigurace. Nastavení aplikace Azure App Service se:
Další informace o nastavení hodnot konfigurace .NET pomocí proměnných prostředí najdete v tématu proměnné prostředí.
Ke konfiguraci protokolování v kódu použijte ILoggingBuilder rozhraní API. K tomuto přístupu je možné přistupovat z různých míst:
ILoggerFactory
přímo nakonfigurujte v LoggerFactory.Createsouboru .Tento příklad ukazuje nastavení zprostředkovatele protokolování konzoly a několik filtrů.
using Microsoft.Extensions.Logging;
using var loggerFactory = LoggerFactory.Create(static builder =>
{
builder
.AddFilter("Microsoft", LogLevel.Warning)
.AddFilter("System", LogLevel.Warning)
.AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
.AddConsole();
});
ILogger logger = loggerFactory.CreateLogger<Program>();
logger.LogDebug("Hello {Target}", "Everyone");
V předchozím příkladu AddFilter se používá k úpravě úrovně protokolu, která je povolená pro různé kategorie. AddConsole slouží k přidání zprostředkovatele protokolování konzoly. Ve výchozím nastavení nejsou protokoly se Debug
závažností povolené, ale protože konfigurace upravila filtry, zobrazí se v konzole zpráva ladění "Hello Everyone".
Když se vytvoří objekt ILogger<TCategoryName>, objekt ILoggerFactory vybere pro každého zprostředkovatele jedno pravidlo, které se použije na daný protokolovací nástroj. Všechny zprávy zapsané instancí ILogger
se filtrují na základě vybraných pravidel. Pro každou dvojici zprostředkovatele a kategorie se z dostupných pravidel vybere nejkonkrétnější pravidlo.
Při vytvoření objektu ILogger
pro danou kategorii se u každého zprostředkovatele použije následující algoritmus:
Při vytvoření objektu ILogger
se určí kategorie. Tato kategorie je součástí každé zprávy protokolu vytvořené danou instancí ILogger
. Řetězec kategorie je libovolný, ale konvence je použít plně kvalifikovaný název třídy. Například v aplikaci se službou definovanou jako následující objekt může být "Example.DefaultService"
kategorie:
namespace Example
{
public class DefaultService : IService
{
private readonly ILogger<DefaultService> _logger;
public DefaultService(ILogger<DefaultService> logger) =>
_logger = logger;
// ...
}
}
Pokud je požadovaná další kategorizace, je konvence použít hierarchický název připojením podkategorie k plně kvalifikovanému názvu třídy a explicitně zadat kategorii pomocí LoggerFactory.CreateLogger:
namespace Example
{
public class DefaultService : IService
{
private readonly ILogger _logger;
public DefaultService(ILoggerFactory loggerFactory) =>
_logger = loggerFactory.CreateLogger("Example.DefaultService.CustomCategory");
// ...
}
}
Volání CreateLogger
s pevným názvem může být užitečné při použití ve více třídách nebo typech, aby události mohly být uspořádány podle kategorie.
Výraz ILogger<T>
je ekvivalentní volání metody CreateLogger
s plně kvalifikovaným názvem typu T
.
Následující tabulka uvádí hodnoty vlastnosti LogLevel, vhodnou rozšiřující metodu Log{LogLevel}
a navrhované použití:
ÚroveňProtokolu | Hodnota | metoda | Popis |
---|---|---|---|
Trasování | 0 | LogTrace | Obsahuje nejpodrobnější zprávy. Tyto zprávy můžou obsahovat citlivá data aplikace. Tyto zprávy jsou ve výchozím nastavení zakázané a neměly by se povolovat v produkčním prostředí. |
Debug | 0 | LogDebug | Slouží pro účely ladění a vývoje. Vzhledem k velkému objemu používejte tuto úroveň opatrně v produkčním prostředí. |
Informace | 2 | LogInformation | Sleduje obecný tok aplikace. Může mít dlouhodobou hodnotu. |
Upozorňující | 3 | LogWarning | Slouží k protokolování neobvyklých nebo neočekávaných událostí. Obvykle zahrnuje chyby nebo podmínky, které nezpůsobují selhání aplikace. |
Chyba | 4 | LogError | Slouží k protokolování chyb a výjimek, které není možné zpracovat. Tyto zprávy značí selhání v aktuální operaci nebo požadavku, nikoli selhání na úrovni aplikace. |
Kritická | 5 | LogCritical | Slouží k protokolování událostí, které vyžadují okamžitou pozornost. Příklady: scénáře ztráty dat, nedostatek místa na disku. |
Nic | 6 | Určuje, že by se neměly zapisovat žádné zprávy. |
Ve výše uvedené tabulce jsou hodnoty vlastnosti LogLevel
uvedené v pořadí od nejnižší po nejvyšší závažnost.
První parametr metody Log, LogLevel, označuje závažnost protokolu. Většina vývojářů místo volání metody Log(LogLevel, ...)
volá rozšiřující metody Log{LogLevel}. Rozšiřující Log{LogLevel}
metody volají metodu Log
a určují LogLevel
. Například následující dvě volání protokolování jsou funkčně ekvivalentní a generují stejné protokoly:
public void LogDetails()
{
var logMessage = "Details for log.";
_logger.Log(LogLevel.Information, AppLogEvents.Details, logMessage);
_logger.LogInformation(AppLogEvents.Details, logMessage);
}
AppLogEvents.Details
je ID události a implicitně je reprezentována konstantní Int32 hodnotou. AppLogEvents
je třída, která zveřejňuje různé pojmenované identifikátor konstanty a je zobrazena v oddílu ID události protokolu.
Následující kód vytvoří protokoly Information
a Warning
:
public async Task<T> GetAsync<T>(string id)
{
_logger.LogInformation(AppLogEvents.Read, "Reading value for {Id}", id);
var result = await _repository.GetAsync(id);
if (result is null)
{
_logger.LogWarning(AppLogEvents.ReadNotFound, "GetAsync({Id}) not found", id);
}
return result;
}
V předchozím kódu je prvním Log{LogLevel}
parametrem AppLogEvents.Read
ID události protokolu. Druhý parametr je šablona zprávy se zástupnými symboly pro hodnoty argumentů, které poskytují zbývající parametry metody. Parametry metody jsou vysvětleny v části šablony zprávy dále v tomto článku.
Nakonfigurujte odpovídající úroveň protokolu a volejte správné Log{LogLevel}
metody, abyste mohli řídit, kolik výstupu protokolu se zapisuje do konkrétního média úložiště. Příklad:
Trace
nebo Debug
generuje velké množství podrobných zpráv protokolu. Pokud chcete mít náklady pod kontrolou a nepřekročit limity úložiště dat, protokolujte zprávy úrovně Trace
a Debug
do velkoobjemového a nízkonákladového úložiště dat. Zvažte omezení úrovní Trace
a Debug
na konkrétní kategorie.Warning
až Critical
by mělo generovat malé množství zpráv protokolu.
Warning
.Trace
nebo Debug
. Pokud chcete omezit výstup, nastavte úroveň Trace
nebo Debug
pouze pro kategorie, které zkoumáte.Následující sady Logging:Console:LogLevel:Microsoft:Information
JSON:
{
"Logging": {
"LogLevel": {
"Microsoft": "Warning"
},
"Console": {
"LogLevel": {
"Microsoft": "Information"
}
}
}
}
Každý protokol může zadat identifikátor události, jedná se EventId o strukturu s volitelnými Name
vlastnostmi Id
jen pro čtení. Ukázkový zdrojový kód používá AppLogEvents
třídu k definování ID událostí:
using Microsoft.Extensions.Logging;
internal static class AppLogEvents
{
internal static EventId Create = new(1000, "Created");
internal static EventId Read = new(1001, "Read");
internal static EventId Update = new(1002, "Updated");
internal static EventId Delete = new(1003, "Deleted");
// These are also valid EventId instances, as there's
// an implicit conversion from int to an EventId
internal const int Details = 3000;
internal const int Error = 3001;
internal static EventId ReadNotFound = 4000;
internal static EventId UpdateNotFound = 4001;
// ...
}
Tip
Další informace o převodu int
na operátor EventId
EventId.Implicit(Int32 na Id události)
ID události spojuje sadu událostí. Například všechny protokoly související se čtením hodnot z úložiště můžou být 1001
.
Zprostředkovatel protokolování může protokolovat ID události v poli ID, ve zprávě protokolování nebo vůbec. Zprostředkovatel Debug nezobrazuje ID událostí. Zprostředkovatel Console zobrazuje ID událostí v závorkách za kategorií:
info: Example.DefaultService.GetAsync[1001]
Reading value for a1b2c3
warn: Example.DefaultService.GetAsync[4000]
GetAsync(a1b2c3) not found
Někteří zprostředkovatelé protokolování uchovávají ID událostí v poli, což umožňuje filtrování podle ID.
Každé rozhraní API pro protokoly používá šablony zprávy. Šablona zprávy může obsahovat zástupné symboly, pro které se poskytnou argumenty. Jako zástupné symboly používejte názvy, a ne čísla. Pořadí zástupných symbolů, nikoli jejich názvů, určuje, které parametry se použijí k zadání jejich hodnot. V následujícím kódu jsou názvy parametrů mimo pořadí v šabloně zprávy:
string p1 = "param1";
string p2 = "param2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);
Předchozí kód vytvoří zprávu protokolu s hodnotami parametrů v posloupnosti:
Parameter values: param1, param2
Poznámka
Při použití více zástupných symbolů v rámci jedné šablony zprávy mějte na paměti, protože jsou založené na řadách. Názvy se nepoužívají k zarovnání argumentů na zástupné symboly.
Tento přístup umožňuje zprostředkovatelům protokolování implementovat sémantické neboli strukturované protokolování. Do systému protokolování se předávají samotné argumenty, nikoli pouze formátovaná šablona zprávy. To umožňuje zprostředkovatelům protokolování uchovávat hodnoty parametrů jako pole. Zvažte následující metodu loggeru:
_logger.LogInformation("Getting item {Id} at {RunTime}", id, DateTime.Now);
Například při protokolování do služby Azure Table Storage:
ID
a RunTime
.RunTime
, aniž by musel parsovat čas z textové zprávy.Šablony zpráv protokolu podporují formátování zástupných symbolů. Šablony mohou zadat libovolný platný formát pro daný argument typu. Představte si například následující Information
šablonu zprávy protokolovacího nástroje:
_logger.LogInformation("Logged on {PlaceHolderName:MMMM dd, yyyy}", DateTimeOffset.UtcNow);
// Logged on January 06, 2022
V předchozím příkladu DateTimeOffset
je instance typem, který odpovídá PlaceHolderName
šabloně zprávy protokolovacího nástroje. Tento název může být libovolný, protože hodnoty jsou řaděné. Formát MMMM dd, yyyy
je platný pro DateTimeOffset
typ.
Další informace o DateTime
formátování a DateTimeOffset
formátování naleznete v tématu Vlastní řetězce formátu data a času.
Následující příklady ukazují, jak formátovat šablonu zprávy pomocí {}
zástupné syntaxe. Kromě toho se pomocí výstupu zobrazí příklad escapingu {}
zástupné syntaxe. Nakonec se zobrazí interpolace řetězců se zástupnými symboly šablon:
logger.LogInformation("Number: {Number}", 1); // Number: 1
logger.LogInformation("{{Number}}: {Number}", 3); // {Number}: 3
logger.LogInformation($"{{{{Number}}}}: {{Number}}", 5); // {Number}: 5
Tip
Metody protokolovacího nástroje obsahují přetížení, která jako parametr přebírají výjimku:
public void Test(string id)
{
try
{
if (id is "none")
{
throw new Exception("Default Id detected.");
}
}
catch (Exception ex)
{
_logger.LogWarning(
AppLogEvents.Error, ex,
"Failed to process iteration: {Id}", id);
}
}
Protokolování výjimek se u jednotlivých zprostředkovatelů liší.
Pokud není nastavená výchozí úroveň protokolování, má výchozí úroveň protokolování hodnotu Information
.
Představte si například následující aplikaci pracovní služby:
V případě výše uvedeného nastavení se při přechodu na stránku ochrany osobních údajů nebo domovskou stránku vygeneruje velké množství zpráv úrovně Trace
, Debug
a Information
s textem Microsoft
v názvu kategorie.
Následující kód nastaví výchozí úroveň protokolování, pokud není nastavená v konfiguraci:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Warning);
using IHost host = builder.Build();
await host.RunAsync();
Funkce filtru se volá pro všechny zprostředkovatele a kategorie, ke kterým nejsou v konfiguraci nebo kódu přiřazená pravidla:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddFilter((provider, category, logLevel) =>
{
return provider.Contains("ConsoleLoggerProvider")
&& (category.Contains("Example") || category.Contains("Microsoft"))
&& logLevel >= LogLevel.Information;
});
using IHost host = builder.Build();
await host.RunAsync();
Výše uvedený kód zobrazí protokoly konzoly v případě, že kategorie obsahuje Example
nebo Microsoft
a úroveň protokolování je Information
nebo vyšší.
Obor seskupí sadu logických operací. Toto seskupení je možné využít k připojení stejných dat ke všem protokolům vytvořeným v rámci sady. Například všechny protokoly vytvořené v rámci zpracování transakce můžou obsahovat ID transakce.
Obor:
Obory podporují následující zprostředkovatelé:
Obor můžete použít tak, že zabalíte volání protokolovacího nástroje do bloku using
:
public async Task<T> GetAsync<T>(string id)
{
T result;
var transactionId = Guid.NewGuid().ToString();
using (_logger.BeginScope(new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("TransactionId", transactionId),
}))
{
_logger.LogInformation(
AppLogEvents.Read, "Reading value for {Id}", id);
var result = await _repository.GetAsync(id);
if (result is null)
{
_logger.LogWarning(
AppLogEvents.ReadNotFound, "GetAsync({Id}) not found", id);
}
}
return result;
}
Následující kód JSON umožňuje obory pro zprostředkovatele konzoly:
{
"Logging": {
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft": "Warning",
"Default": "Information"
}
},
"LogLevel": {
"Default": "Debug"
}
}
}
Následující kód povoluje obory pro poskytovatele konzoly:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole(options => options.IncludeScopes = true);
using IHost host = builder.Build();
await host.RunAsync();
Následující kód po sestavení hostitele získá z injektáže závislostí instanci ILogger
a nastaví protokolování v třídě Main
:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using IHost host = Host.CreateApplicationBuilder(args).Build();
var logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Host created.");
await host.RunAsync();
Předchozí kód spoléhá na dva balíčky NuGet:
Soubor projektu by vypadal nějak takto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
</ItemGroup>
</Project>
Protokolování by mělo být tak rychlé, že asynchronní kód nedává smysl z hlediska dopadu na výkon. Pokud je úložiště dat protokolování pomalé, nezapisujte do něj přímo. Zvažte možnost nejprve zapisovat zprávy protokolu do rychlého úložiště a přesouvat je do pomalého úložiště později. Pokud například využíváte protokolování na SQL Server, neprovádějte to přímo v metodě Log
, protože metody Log
jsou synchronní. Místo toho synchronně přidávejte zprávy protokolu do fronty v paměti a nastavte pracovní proces na pozadí, který bude zprávy přetahovat z fronty a asynchronně publikovat data na SQL Server.
Rozhraní API pro protokolování neumožňuje změnit úrovně protokolování, když je aplikace spuštěná. Někteří zprostředkovatelé konfigurace však podporují opětovné načtení konfigurace, která se okamžitě projeví na konfiguraci protokolování. Poskytovatel konfigurace souborů například ve výchozím nastavení znovu načte konfiguraci protokolování. Pokud se konfigurace změní v kódu, když je aplikace spuštěná, může aplikace volat IConfigurationRoot.Reload , aby aktualizovala konfiguraci protokolování aplikace.
Rozhraní ILogger<TCategoryName> a ILoggerFactory implementace jsou součástí většiny sad .NET SDK jako implicitní odkaz na balíčky. Jsou také explicitně k dispozici v následujících balíčcích NuGet, pokud na tyto balíčky nejsou implicitně odkazovány:
Další informace o tom, která sada .NET SDK obsahuje implicitní odkazy na balíčky, najdete v tématu .NET SDK: tabulka pro implicitní obor názvů.
Zpětná vazba k produktu .NET
.NET je open source projekt. Vyberte odkaz pro poskytnutí zpětné vazby:
Školení
Modul
Formátování alfanumerických dat pro prezentaci v jazyce C# - Training
Prozkoumejte základní metody v jazyce C# pro formátování alfanumerických dat.