Använda en loggare för att lägga till anpassade loggmeddelanden
.NET tillhandahåller API:er som du kan använda för att logga anpassade telemetridata. OpenTelemetry kan exportera dessa data.
I den här lektionen får du lära dig hur du skriver effektiv kod som skickar händelser till strukturerade loggar.
ILogger-objekt
.NET Aspire-verktyget konfigurerar OpenTelemetry-API:et automatiskt när du skapar ett projekt baserat på mallarna eller lägger till ett befintligt projekt i .NET Aspire-orkestrering. När du vill registrera telemetri behöver du inte skapa egna loggnings-, mått- eller spårningsobjekt. I stället kan du hämta dem med hjälp av beroendeinmatning i dina mikrotjänster.
I följande BasketService
klass ingår till exempel ett ILogger
objekt i klassdeklarationen. Du kan använda loggaren var som helst i klassen för att skriva händelser:
public class BasketService(
IBasketRepository repository,
ILogger<BasketService> logger) : Basket.BasketBase
{
[AllowAnonymous]
public override async Task<CustomerBasketResponse> GetBasket(
GetBasketRequest request, ServerCallContext context)
{
var userId = context.GetUserIdentity();
// Use the logger to write events
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug("Begin GetBasketById call from method {Method} for basket id {userId}", context.Method, userId);
}
var data = await repository.GetBasketAsync(userId);
return new();
}
}
Effektiv loggning
Loggning hjälper till att göra din mikrotjänst observerbar. När appen testas, mellanlagras och distribueras till produktion kan en grundlig loggkod möjliggöra snabb diagnos av fel eller flaskhalsar. Det är därför frestande att logga allt. Men även om loggningen är snabb har den ingen kostnad och du bör vara noga med att logga effektivt.
Leverantörer fakturerar vanligtvis API:er (Application Performance Management) system baserat på mängden data som de matar in. Om du väljer lämplig loggnivå för dina meddelanden och standardsamlingsnivåerna kan det ha stor effekt på månadsfakturan. Logginsamlingsnivåer kan anges per provider, vilket vanligtvis är det typnamn som används i ILogger<T>
.
Använd följande tekniker varje gång du loggar:
- Kontrollera att loggningsnivån som du vill använda är aktiverad. Tillgängliga nivåer inkluderar information, varning, fel och kritisk. Administratörer kan aktivera olika nivåer vid testning, mellanlagring och distribution till produktion. Loggutdata styrs via
IConfiguration
, vanligtvis med hjälp avappsettings.json
eller miljövariabler. - Undvik stränginterpolation i det loggade meddelandet. Interpolerade strängar definieras med symbolen
$
och utvärderas även om den valda loggningsnivån inte är aktiverad. Använd i stället en loggmetod somLogInformation()
ellerLogDebug()
och skicka parametrar i argumentlistan. - Använd kompileringstidskällan för att ytterligare optimera loggningsprestandan och skapa en unik identifierare för varje loggmeddelande, vilket är användbart när du frågar efter loggmeddelanden i en APM.
Kompilera generering av tidskälla
Kompilera tidskällans generering med ILogger
objekt minskar kostnaden för loggning genom att utföra stränganalysen en gång i stället för på varje loggningsbegäran. Den innehåller också ett ID för varje typ av loggmeddelande. Om du vill använda den här tekniken definierar du partiella loggningsmetoder med loggningsparametrarna och tillämpar på LoggerMessageAttribute
dem. .NET genererar automatiskt den fullständiga loggningsmetoden när koden kompileras.
Kom ihåg att du inte behöver skapa en ILogger i .NET Aspire, utan i stället kan du hämta den från beroendeinmatningen:
public partial class BasketService(
IBasketRepository repository,
ILogger<BasketService> logger) : Basket.BasketBase
{
[LoggerMessage(
EventId = 0,
Level = LogLevel.Information,
Message = "Obtaining a basket from method {Method} for basket {basketId}")]
public partial void LogGetBasket(string Method, int basketId);
}