Verwenden eines Loggers zum Hinzufügen von benutzerdefinierten Protokollnachrichten
.NET stellt APIs bereit, mit denen Sie benutzerdefinierte Telemetriedaten protokollieren können. OpenTelemetry kann diese Daten exportieren.
In dieser Lektion erfahren Sie, wie Sie effizienten Code schreiben, der Ereignisse an strukturierte Protokolle sendet.
ILogger-Objekte
Das .NET Aspire-Tool richtet die OpenTelemetry-API automatisch ein, wenn Sie ein Projekt basierend auf den Vorlagen erstellen oder ein vorhandenes Projekt zur .NET Aspire-Orchestrierung hinzufügen. Wenn Sie Telemetrie aufzeichnen möchten, müssen Sie keine eigenen Protokollierungs-, Metrik- oder Ablaufverfolgungsobjekte erstellen. Stattdessen können Sie sie mithilfe der Abhängigkeitsinjektion in Ihren Microservices abrufen.
In der folgenden BasketService
-Klasse ist beispielsweise ein ILogger
-Objekt in der Klassendeklaration enthalten. Sie können diesen Logger an einer beliebigen Stelle in der Klasse verwenden, um Ereignisse zu schreiben:
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();
}
}
Effiziente Protokollierung
Die Protokollierung hilft Ihnen, Ihren Microservice erkennbar zu machen. Wenn die App getestet, gestaged und in der Produktion bereitgestellt wird, kann ein gründlicher Protokollcode die schnelle Diagnose von Fehlern oder Engpässen ermöglichen. Es ist daher verlockend, alles zu protokollieren. Obwohl die Protokollierung schnell ist, hat sie keine Nullkosten, und Sie sollten darauf achten, effizient zu protokollieren.
Anbieter rechnen häufig APMs (Application Performance Management)-Systeme auf der Grundlage des Datenvolumens, das sie erfassen, ab. Die Auswahl der entsprechenden Protokollebene für Ihre Nachrichten und die Standardsammlungsebenen können einen großen Einfluss auf die monatliche Rechnung haben. Protokollsammlungsebenen können auf Anbieterbasis festgelegt werden, was in der Regel der Typname ist, der in ILogger<T>
verwendet wird.
Verwenden Sie bei jeder Anmeldung die folgenden Techniken:
- Überprüfen Sie, ob die Protokollierungsebene, die Sie verwenden möchten, aktiviert ist. Verfügbare Ebenen umfassen Informationen, Warnungen, Fehler und Kritisches. Administratoren können beim Testen, Staging und Bereitstellen in der Produktion unterschiedliche Ebenen aktivieren. Die Protokollausgabe wird über
IConfiguration
gesteuert, in der Regel mithilfe vonappsettings.json
oder Umgebungsvariablen. - Vermeiden Sie die Interpolation von Zeichenfolgen in der protokollierten Nachricht. Interpolierte Zeichenfolgen werden mit dem
$
-Symbol definiert und auch dann ausgewertet, wenn die ausgewählte Protokollierungsebene nicht aktiviert ist. Verwenden Sie stattdessen eine Protokollmethode wieLogInformation()
oderLogDebug()
, und übergeben Sie Parameter in der Argumentliste. - Verwenden Sie die Kompilierungszeitquelle, um die Protokollierungsleistung weiter zu optimieren und für jede Protokollnachricht einen eindeutigen Bezeichner zu erstellen, der beim Abfragen von Protokollnachrichten in einer APM nützlich ist.
Erstellung der Kompilierungszeitquelle
Die Erstellung der Kompilierungszeitquelle mit ILogger
-Objekten reduziert die Protokollierungskosten, indem die Zeichenfolgenanalyse einmal ausgeführt wird, anstatt auf jeder Protokollierungsanforderung. Sie enthält auch eine ID für jede Art von Protokollnachrichten. Um diese Technik zu verwenden, definieren Sie partielle Protokollierungsmethoden mit den Protokollierungsparametern und wenden Sie sie auf LoggerMessageAttribute
an. .NET generiert automatisch die vollständige Protokollierungsmethode, wenn der Code kompiliert wird.
Denken Sie daran, dass Sie in .NET Aspire keinen ILogger erstellen müssen, sondern ihn stattdessen aus der Abhängigkeitsinjektion abrufen können:
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);
}