Utbildning
Modul
Formatera alfanumeriska data för presentation i C# - Training
Utforska grundläggande metoder i C# för att formatera alfanumeriska data.
Den här webbläsaren stöds inte längre.
Uppgradera till Microsoft Edge och dra nytta av de senaste funktionerna och säkerhetsuppdateringarna, samt teknisk support.
.NET stöder hög prestanda, strukturerad loggning via API:et ILogger för att övervaka programmets beteende och diagnostisera problem. Loggar kan skrivas till olika mål genom att konfigurera olika loggningsproviders. Grundläggande loggningsproviders är inbyggda och det finns även många tredjepartsleverantörer tillgängliga.
Det här första exemplet visar grunderna, men det är bara lämpligt för en trivial konsolapp. Den här exempelkonsolappen förlitar sig på följande NuGet-paket:
I nästa avsnitt ser du hur du kan förbättra koden med tanke på skalning, prestanda, konfiguration och typiska programmeringsmönster.
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");
Föregående exempel:
ILoggerFactory
all konfiguration som avgör var loggmeddelanden skickas. I det här fallet konfigurerar du konsolens loggningsprovider så att loggmeddelanden skrivs till konsolen.string
som är associerad med varje meddelande som loggas av ILogger
objektet. Den används för att gruppera loggmeddelanden från samma klass (eller kategori) tillsammans vid sökning eller filtrering av loggar.Information
nivån. Loggnivån anger allvarlighetsgraden för den loggade händelsen och används för att filtrera bort mindre viktiga loggmeddelanden. Loggposten innehåller även en meddelandemall "Hello World! Logging is {Description}."
och ett nyckel/värde-par Description = fun
. Nyckelnamnet (eller platshållaren) kommer från ordet inuti klammerparenteserna i mallen och värdet kommer från det återstående metodargumentet.Den här projektfilen för det här exemplet innehåller två NuGet-paket:
<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>
Tips
All källkod för loggningsexemplet är tillgänglig i Exempelwebbläsaren för nedladdning. Mer information finns i Bläddra bland kodexempel: Loggning i .NET.
Det finns flera ändringar som du bör överväga att göra i föregående exempel när du loggar in i ett mindre trivialt scenario:
Om ditt program använder beroendeinmatning (DI) eller en värd, till exempel ASP. NET:s webapplication eller generiska värd bör du använda ILoggerFactory
och ILogger
objekt från deras respektive DI-containrar i stället för att skapa dem direkt. Mer information finns i Integrering med DI och Värdar.
Loggning av kompileringstidskälla är vanligtvis ett bättre alternativ till ILogger
tilläggsmetoder som LogInformation
. Loggningskällans generering ger bättre prestanda, starkare typning och undviker att sprida string
konstanter i dina metoder. Kompromissen är att användning av den här tekniken kräver lite mer kod.
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
för att göra den här namngivningen enkel att göra.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");
Om ditt program använder beroendeinmatning (DI) eller en värd, till exempel ASP. NET:s webapplication eller generiska värd bör du använda ILoggerFactory
och ILogger
objekt från DI-containern i stället för att skapa dem direkt.
Det här exemplet hämtar ett ILogger-objekt i en värdbaserad app med ASP.NET minimala API:er:
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);
}
Föregående exempel:
ExampleHandler
och mappade inkommande webbbegäranden för att köra ExampleHandler.HandleRequest
funktionen.ILogger<ExampleHandler>
. ILogger<TCategoryName> härleds från ILogger och anger vilken kategori objektet ILogger
har. DI-containern letar upp en ILogger
med rätt kategori och tillhandahåller den som konstruktorargument. Om det inte finns någon ILogger
med den kategorin ännu skapar DI-containern den automatiskt från ILoggerFactory
i tjänstleverantören.logger
som togs emot i konstruktorn användes för loggning i HandleRequest
funktionen.Värdskapare initierar standardkonfigurationen och lägger sedan till ett konfigurerat ILoggerFactory
objekt i värdens DI-container när värden skapas. Innan värden skapas kan du justera loggningskonfigurationen via HostApplicationBuilder.Logging, WebApplicationBuilder.Loggingeller liknande API:er på andra värdar. Värdar tillämpar även loggningskonfiguration från standardkonfigurationskällor som appsettings.json och miljövariabler. Mer information finns i Konfiguration i .NET.
Det här exemplet expanderar på föregående för att anpassa den ILoggerFactory
som tillhandahålls av WebApplicationBuilder
. Den lägger till OpenTelemetry som en loggningsprovider som skickar loggarna via OTLP (OpenTelemetry protocol):
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddOpenTelemetry(logging => logging.AddOtlpExporter());
builder.Services.AddSingleton<ExampleHandler>();
var app = builder.Build();
Om du använder en DI-container utan värd använder du AddLogging för att konfigurera och lägga till ILoggerFactory
i containern.
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);
}
}
Föregående exempel:
ILoggerFactory
konfigurerad för att skriva till konsolenExampleService
har lagts till i containernExampleService
från DI-containern som också automatiskt skapade en ILogger<ExampleService>
som ska användas som konstruktorargument.ExampleService.DoSomeWork
som använde ILogger<ExampleService>
för att logga ett meddelande till konsolen.Loggningskonfigurationen anges i kod eller via externa källor, till exempel konfigurationsfiler och miljövariabler. Det är fördelaktigt att använda extern konfiguration när det är möjligt eftersom det kan ändras utan att programmet återskapas. Vissa uppgifter, till exempel att ange loggningsproviders, kan dock bara konfigureras från kod.
För appar som använder en värd tillhandahålls loggningskonfiguration ofta i "Logging"
avsnittet apparinställningar.{Environment}
.json filer. För appar som inte använder en värd konfigureras externa konfigurationskällor explicit eller konfigureras i kod i stället.
Följande apparinställningar. Development.json filen genereras av .NET Worker-tjänstmallarna:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
I JSON-koden ovan:
"Default"
, "Microsoft"
och "Microsoft.Hosting.Lifetime"
loggnivå anges."Default"
tillämpas på alla kategorier som inte anges på annat sätt, vilket i praktiken gör alla standardvärden för alla kategorier "Information"
. Du kan åsidosätta det här beteendet genom att ange ett värde för en kategori."Microsoft"
gäller för alla kategorier som börjar med "Microsoft"
."Microsoft"
på loggnivå Warning
och högre."Microsoft.Hosting.Lifetime"
är mer specifik än "Microsoft"
kategorin, så "Microsoft.Hosting.Lifetime"
kategoriloggarna på loggnivå "Information"
och högre.LogLevel
den gäller för alla aktiverade loggningsproviders förutom Windows EventLog.Egenskapen Logging
kan ha LogLevel egenskaper för loggprovidern. LogLevel
Anger den lägsta nivå som ska loggas för valda kategorier. I föregående JSON Information
Warning
och loggnivåer anges. LogLevel
anger loggens allvarlighetsgrad och sträcker sig från 0 till 6:
Trace
= 0, Debug
= 1, Information
= 2, Warning
= 3, Error
= 4, Critical
= 5 och None
= 6.
När en LogLevel
har angetts aktiveras loggning för meddelanden på den angivna nivån och högre. I föregående JSON Default
loggas kategorin för Information
och högre. Till exempel Information
loggas , Warning
, Error
och Critical
meddelanden. Om nej LogLevel
har angetts är loggning standardvärdet för Information
nivån. Mer information finns i Loggnivåer.
En provideregenskap kan ange en LogLevel
egenskap. LogLevel
under en provider anger nivåer för att logga för den providern och åsidosätter logginställningarna som inte är provider. Överväg följande appsettings.json fil:
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Warning"
},
"Debug": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting": "Trace"
}
},
"EventSource": {
"LogLevel": {
"Default": "Warning"
}
}
}
}
Inställningar i Logging.{ProviderName}.LogLevel
åsidosättningsinställningar i Logging.LogLevel
. I föregående JSON Debug
är providerns standardloggnivå inställd Information
på :
Logging:Debug:LogLevel:Default:Information
Föregående inställning anger Information
loggnivån för varje Logging:Debug:
kategori utom Microsoft.Hosting
. När en specifik kategori visas åsidosätter den specifika kategorin standardkategorin. I föregående JSON åsidosätter Logging:Debug:LogLevel
kategorierna "Microsoft.Hosting"
och "Default"
inställningarna i Logging:LogLevel
Minsta loggnivå kan anges för något av följande:
Logging:EventSource:LogLevel:Default:Information
Logging:LogLevel:Microsoft:Warning
Logging:LogLevel:Default:Warning
Loggar under miniminivån är inte:
Om du vill ignorera alla loggar anger du LogLevel.None. LogLevel.None
har värdet 6, vilket är högre än LogLevel.Critical
(5).
Om en provider stöder loggomfattningar anger IncludeScopes
du om de är aktiverade. Mer information finns i loggomfattningar
Följande appsettings.json fil innehåller inställningar för alla inbyggda leverantörer:
{
"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"
}
}
}
}
I föregående exempel:
Logging.{ProviderName}.LogLevel
åsidosättningsinställningar i Logging.LogLevel
. Nivån i Debug.LogLevel.Default
åsidosätter till exempel nivån i LogLevel.Default
.Console
Debug
EventSource
EventLog
AzureAppServicesFile
AzureAppServicesBlob
ApplicationInsights
Loggnivån kan anges av någon av konfigurationsprovidrar. Du kan till exempel skapa en bevarad miljövariabel med namnet Logging:LogLevel:Microsoft
med värdet Information
.
Skapa och tilldela en bevarad miljövariabel med tanke på loggnivåvärdet.
:: Assigns the env var to the value
setx "Logging__LogLevel__Microsoft" "Information" /M
I en ny instans av kommandotolken läser du miljövariabeln.
:: Prints the env var value
echo %Logging__LogLevel__Microsoft%
Den föregående miljöinställningen sparas i miljön. Om du vill testa inställningarna när du använder en app som skapats med .NET Worker-tjänstmallarna använder du dotnet run
kommandot i projektkatalogen när miljövariabeln har tilldelats.
dotnet run
Tips
När du har angett en miljövariabel startar du om din integrerade utvecklingsmiljö (IDE) för att säkerställa att nyligen tillagda miljövariabler är tillgängliga.
I Azure App Service väljer du Ny programinställning på sidan Konfiguration av inställningar>. Azure App Service-programinställningar är:
Mer information om hur du anger .NET-konfigurationsvärden med hjälp av miljövariabler finns i miljövariabler.
Om du vill konfigurera loggning i kod använder du API:et ILoggingBuilder . Detta kan nås från olika platser:
ILoggerFactory
direkt konfigurerar du i LoggerFactory.Create.Det här exemplet visar hur du ställer in konsolens loggningsprovider och flera filter.
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");
I föregående exempel AddFilter används för att justera loggnivån som är aktiverad för olika kategorier. AddConsole används för att lägga till konsolens loggningsprovider. Som standard är loggar med Debug
allvarlighetsgrad inte aktiverade, men eftersom konfigurationen justerade filtren visas felsökningsmeddelandet "Hello Everyone" i konsolen.
När ett ILogger<TCategoryName> objekt skapas ILoggerFactory väljer objektet en enda regel per provider som ska tillämpas på den loggaren. Alla meddelanden som skrivs av en ILogger
instans filtreras baserat på de valda reglerna. Den mest specifika regeln för varje provider och kategoripar väljs från de tillgängliga reglerna.
Följande algoritm används för varje provider när en ILogger
skapas för en viss kategori:
När ett ILogger
objekt skapas anges en kategori . Den kategorin ingår i varje loggmeddelande som skapas av den instansen av ILogger
. Kategoristrängen är godtycklig, men konventionen är att använda det fullständigt kvalificerade klassnamnet. I ett program med en tjänst som definierats som följande objekt kan kategorin till exempel vara "Example.DefaultService"
:
namespace Example
{
public class DefaultService : IService
{
private readonly ILogger<DefaultService> _logger;
public DefaultService(ILogger<DefaultService> logger) =>
_logger = logger;
// ...
}
}
Om ytterligare kategorisering önskas är konventionen att använda ett hierarkiskt namn genom att lägga till en underkategori i det fullständigt kvalificerade klassnamnet och uttryckligen ange kategorin med hjälp av LoggerFactory.CreateLogger:
namespace Example
{
public class DefaultService : IService
{
private readonly ILogger _logger;
public DefaultService(ILoggerFactory loggerFactory) =>
_logger = loggerFactory.CreateLogger("Example.DefaultService.CustomCategory");
// ...
}
}
Att anropa CreateLogger
med ett fast namn kan vara användbart när det används i flera klasser/typer så att händelserna kan ordnas efter kategori.
ILogger<T>
motsvarar anrop CreateLogger
med det fullständigt kvalificerade typnamnet T
.
I följande tabell visas LogLevel värdena, metoden för bekvämlighetstillägg Log{LogLevel}
och den föreslagna användningen:
Loggnivå | Värde | Metod | beskrivning |
---|---|---|---|
Spårning | 0 | LogTrace | Innehåller de mest detaljerade meddelandena. Dessa meddelanden kan innehålla känsliga appdata. Dessa meddelanden är inaktiverade som standard och bör inte aktiveras i produktion. |
Debug | 1 | LogDebug | För felsökning och utveckling. Använd med försiktighet i produktionen på grund av den höga volymen. |
Information | 2 | LogInformation | Spårar appens allmänna flöde. Kan ha ett långsiktigt värde. |
Varning! | 3 | LogWarning | För onormala eller oväntade händelser. Innehåller vanligtvis fel eller villkor som inte gör att appen misslyckas. |
Fel | 4 | LogError | För fel och undantag som inte kan hanteras. Dessa meddelanden anger ett fel i den aktuella åtgärden eller begäran, inte ett appomfattande fel. |
Kritisk | 5 | LogCritical | För fel som kräver omedelbar uppmärksamhet. Exempel: scenarier för dataförlust, slut på diskutrymme. |
None | 6 | Anger att inga meddelanden ska skrivas. |
I föregående tabell LogLevel
visas från lägsta till högsta allvarlighetsgrad.
Log-metodens första parameter, LogLevel, anger loggens allvarlighetsgrad. I stället för att anropa Log(LogLevel, ...)
anropa anropar de flesta utvecklare log{LogLevel} -tilläggsmetoderna. Tilläggsmetoderna Log{LogLevel}
Log
anropar metoden och anger LogLevel
. Följande två loggningsanrop är till exempel funktionellt likvärdiga och skapar samma logg:
public void LogDetails()
{
var logMessage = "Details for log.";
_logger.Log(LogLevel.Information, AppLogEvents.Details, logMessage);
_logger.LogInformation(AppLogEvents.Details, logMessage);
}
AppLogEvents.Details
är händelse-ID:t och representeras implicit av ett konstant Int32 värde. AppLogEvents
är en klass som exponerar olika namngivna identifierarkonstanter och som visas i avsnittet Logghändelse-ID .
Följande kod skapar Information
och Warning
loggar:
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;
}
I föregående kod är den första Log{LogLevel}
parametern, AppLogEvents.Read
, logghändelse-ID. Den andra parametern är en meddelandemall med platshållare för argumentvärden som tillhandahålls av de återstående metodparametrarna. Metodparametrarna beskrivs i avsnittet med meddelandemallar senare i den här artikeln.
Konfigurera lämplig loggnivå och anropa rätt Log{LogLevel}
metoder för att styra hur mycket loggutdata som skrivs till ett visst lagringsmedium. Till exempel:
Trace
nivåerna eller Debug
ger en stor mängd detaljerade loggmeddelanden. För att kontrollera kostnader och inte överskrida datalagringsgränser loggar Trace
och Debug
nivåmeddelanden till ett datalager med hög volym och låg kostnad. Överväg att Trace
begränsa och Debug
till specifika kategorier.Warning
via Critical
nivåer bör ge få loggmeddelanden.
Warning
.Trace
eller Debug
meddelanden vid felsökning. Om du vill begränsa utdata anger Trace
du eller Debug
endast för de kategorier som undersöks.Följande JSON-uppsättningar Logging:Console:LogLevel:Microsoft:Information
:
{
"Logging": {
"LogLevel": {
"Microsoft": "Warning"
},
"Console": {
"LogLevel": {
"Microsoft": "Information"
}
}
}
}
Varje logg kan ange en händelseidentifierare, EventId är en struktur med en Id
och valfri skrivskyddad Name
egenskap. Exempelkällan använder AppLogEvents
klassen för att definiera händelse-ID:t:
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;
// ...
}
Tips
Mer information om hur du konverterar en int
till en EventId
finns i EventId.Implicit(Int32 till EventId)-operator.
Ett händelse-ID associerar en uppsättning händelser. Till exempel kan alla loggar som rör läsningsvärden från en lagringsplats vara 1001
.
Loggningsprovidern kan logga händelse-ID:t i ett ID-fält, i loggningsmeddelandet eller inte alls. Felsökningsprovidern visar inte händelse-ID:t. Konsolprovidern visar händelse-ID:t inom hakparenteser efter kategorin:
info: Example.DefaultService.GetAsync[1001]
Reading value for a1b2c3
warn: Example.DefaultService.GetAsync[4000]
GetAsync(a1b2c3) not found
Vissa loggningsleverantörer lagrar händelse-ID:t i ett fält, vilket möjliggör filtrering på ID:t.
Varje logg-API använder en meddelandemall. Meddelandemallen kan innehålla platshållare för vilka argument anges. Använd namn för platshållarna, inte siffror. Platshållarnas ordning, inte deras namn, avgör vilka parametrar som används för att ange deras värden. I följande kod är parameternamnen ur sekvens i meddelandemallen:
string p1 = "param1";
string p2 = "param2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);
Föregående kod skapar ett loggmeddelande med parametervärdena i följd:
Parameter values: param1, param2
Anteckning
Tänk på när du använder flera platshållare i en enda meddelandemall, eftersom de är ordningsbaserade. Namnen används inte för att justera argumenten mot platshållarna.
Med den här metoden kan loggningsproviders implementera semantisk eller strukturerad loggning. Själva argumenten skickas till loggningssystemet, inte bara den formaterade meddelandemallen. Detta gör det möjligt för loggningsprovidrar att lagra parametervärdena som fält. Överväg följande loggningsmetod:
_logger.LogInformation("Getting item {Id} at {RunTime}", id, DateTime.Now);
När du till exempel loggar till Azure Table Storage:
ID
och RunTime
egenskaper.RunTime
intervall utan att behöva parsa tidsgränsen för textmeddelandet.Loggmeddelandemallar stöder platshållarformatering. Mallar kan ange valfritt giltigt format för det angivna typargumentet. Tänk till exempel på följande Information
mall för loggningsmeddelande:
_logger.LogInformation("Logged on {PlaceHolderName:MMMM dd, yyyy}", DateTimeOffset.UtcNow);
// Logged on January 06, 2022
I föregående exempel är instansen DateTimeOffset
den typ som motsvarar mallen PlaceHolderName
i loggningsmeddelandet. Det här namnet kan vara vad som helst eftersom värdena är ordningsbaserade. Formatet MMMM dd, yyyy
är giltigt för DateTimeOffset
typen.
Mer information om DateTime
och DateTimeOffset
formatering finns i Anpassade datum- och tidsformatsträngar.
I följande exempel visas hur du formaterar en meddelandemall med platshållarsyntaxen {}
. Dessutom visas ett exempel på hur platshållarsyntaxen {}
kan undvikas med dess utdata. Slutligen visas även stränginterpolation med platshållare för mallar:
logger.LogInformation("Number: {Number}", 1); // Number: 1
logger.LogInformation("{{Number}}: {Number}", 3); // {Number}: 3
logger.LogInformation($"{{{{Number}}}}: {{Number}}", 5); // {Number}: 5
Tips
Loggningsmetoderna har överlagringar som tar en undantagsparameter:
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);
}
}
Undantagsloggning är providerspecifik.
Om standardloggnivån inte har angetts är Information
standardvärdet för loggnivå .
Tänk till exempel på följande arbetstjänstapp:
Med den föregående konfigurationen genererar navigering till sekretess- eller startsidan många Trace
, Debug
och Information
meddelanden med Microsoft
i kategorinamnet.
Följande kod anger standardloggnivån när standardloggnivån inte har angetts i konfigurationen:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Warning);
using IHost host = builder.Build();
await host.RunAsync();
En filterfunktion anropas för alla leverantörer och kategorier som inte har regler tilldelade till sig genom konfiguration eller kod:
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();
Föregående kod visar konsolloggar när kategorin innehåller Example
eller Microsoft
och loggnivån är Information
eller högre.
Ett omfång grupperar en uppsättning logiska åtgärder. Den här grupperingen kan användas för att koppla samma data till varje logg som skapas som en del av en uppsättning. Varje logg som skapas som en del av bearbetningen av en transaktion kan till exempel innehålla transaktions-ID:t.
Ett omfång:
Följande leverantörer stöder omfång:
Använd ett omfång genom att omsluta loggningsanrop i ett using
block:
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;
}
Följande JSON aktiverar omfång för konsolprovidern:
{
"Logging": {
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft": "Warning",
"Default": "Information"
}
},
"LogLevel": {
"Default": "Debug"
}
}
}
Följande kod aktiverar omfång för konsolprovidern:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole(options => options.IncludeScopes = true);
using IHost host = builder.Build();
await host.RunAsync();
Följande kod loggar in Main
genom att hämta en ILogger
instans från DI när värden har skapats:
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();
Föregående kod förlitar sig på två NuGet-paket:
Projektfilen skulle se ut ungefär så här:
<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>
Loggning bör vara så snabb att det inte är värt prestandakostnaden för asynkron kod. Om ett loggningsdatalager är långsamt ska du inte skriva till det direkt. Överväg att skriva loggmeddelandena till en snabb butik först och sedan flytta dem till det långsamma arkivet senare. När du till exempel loggar till SQL Server ska du inte göra det direkt i en Log
metod, eftersom Log
metoderna är synkrona. Lägg i stället synkront till loggmeddelanden i en minnesintern kö och låt en bakgrundsarbetare hämta meddelandena från kön för att utföra det asynkrona arbetet med att skicka data till SQL Server.
Loggnings-API:et innehåller inget scenario för att ändra loggnivåer när en app körs. Vissa konfigurationsprovidrar kan dock läsa in konfigurationen igen, vilket omedelbart påverkar loggningskonfigurationen. Till exempel läser filkonfigurationsprovidern in loggningskonfigurationen igen som standard. Om konfigurationen ändras i kod medan en app körs kan appen anropa IConfigurationRoot.Reload för att uppdatera appens loggningskonfiguration.
Gränssnitten ILogger<TCategoryName> och ILoggerFactory implementeringarna och ingår i de flesta .NET SDK:er som implicit paketreferens. De är också uttryckligen tillgängliga i följande NuGet-paket när de inte refereras implicit:
Mer information om vilka .NET SDK som innehåller implicita paketreferenser finns i .NET SDK: table to implicit namespace (.NET SDK: table to implicit namespace).
Feedback om .NET
.NET är ett öppen källkod projekt. Välj en länk för att ge feedback:
Utbildning
Modul
Formatera alfanumeriska data för presentation i C# - Training
Utforska grundläggande metoder i C# för att formatera alfanumeriska data.