Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A forrásalapú naplózást úgy tervezték, hogy magas szintű használható és nagy teljesítményű naplózási megoldást biztosítson a modern .NET-alkalmazásokhoz. Az automatikusan generált forráskód a ILogger interfészre támaszkodik a LoggerMessage.Define funkcionalitással együtt.
A forrásgenerátor akkor aktiválódik, ha LoggerMessageAttribute-t használnak partial naplózási módszereken. Aktiváláskor automatikusan létrehozza az általa dekorált metódusok implementálását partial . Ha probléma merül fel, fordítási idejű diagnosztikát hoz létre a megfelelő használatra vonatkozó tippekkel. Ez a fordítási idő naplózási megoldása futásidőben jelentősen gyorsabb, mint a korábban elérhető naplózási módszerek. Kiküszöböli a boxolást, az ideiglenes foglalásokat és a másolatokat a lehető legnagyobb mértékben.
Alapszintű használat
A LoggerMessageAttribute használatához a fogyasztó osztálynak és metódusnak partial-nek kell lennie. A kódgenerátor fordításkor aktiválódik, és létrehozza a metódus implementációját partial .
public static partial class Log
{
[LoggerMessage(
EventId = 0,
Level = LogLevel.Critical,
Message = "Could not open socket to `{HostName}`")]
public static partial void CouldNotOpenSocket(
ILogger logger, string hostName);
}
Az előző példában a naplózási módszer, static a naplószint pedig az attribútumdefinícióban van megadva. Ha statikus környezetben használja LoggerMessageAttribute , a ILogger példányt argumentumként kell átadni. Vagy adja hozzá a this módosítót a paraméterhez a ILogger metódus bővítménymetódusként való definiálásához.
public static partial class Log
{
[LoggerMessage(
EventId = 0,
Level = LogLevel.Critical,
Message = "Could not open socket to `{HostName}`")]
public static partial void CouldNotOpenSocket(
this ILogger logger, string hostName);
}
Az attribútumot nem statikus környezetben is használhatja. Vegye figyelembe az alábbi példát, ahol a naplózási módszer példánymetódusként van deklarálva. Ebben az összefüggésben a naplózási módszer a naplózót a tartalmazó osztály egyik ILogger mezőjének elérésével kapja meg.
public partial class InstanceLoggingExample
{
private readonly ILogger _logger;
public InstanceLoggingExample(ILogger logger)
{
_logger = logger;
}
[LoggerMessage(
EventId = 0,
Level = LogLevel.Critical,
Message = "Could not open socket to `{HostName}`")]
public partial void CouldNotOpenSocket(string hostName);
}
A .NET 9-től kezdődően a naplózási módszer emellett lekérheti a naplózót egy ILogger elsődleges konstruktorparaméterből az adott osztályban.
public partial class InstanceLoggingExample(ILogger logger)
{
[LoggerMessage(
EventId = 0,
Level = LogLevel.Critical,
Message = "Could not open socket to `{HostName}`")]
public partial void CouldNotOpenSocket(string hostName);
}
Ha van egy ILogger mező és egy elsődleges konstruktor paraméter, akkor a naplózási módszer a naplózót a mezőből szerzi.
Dinamikus naplószint
Néha a naplószintnek dinamikusnak kell lennie, nem pedig statikusan beépítve a kódba. Ezt úgy teheti meg, hogy kihagyja a naplószintet az attribútumból, és ehelyett paraméterként kell megadnia a naplózási módszerhez.
public static partial class Log
{
[LoggerMessage(
EventId = 0,
Message = "Could not open socket to `{HostName}`")]
public static partial void CouldNotOpenSocket(
ILogger logger,
LogLevel level, /* Dynamic log level as parameter, rather than defined in attribute. */
string hostName);
}
Message ingatlan
A(z) Message tulajdonság a(z) LoggerMessageAttribute esetében opcionális. Ha kihagyja, String.Empty a rendszer az üzenethez használja. Ha azonban a naplózási módszer paraméterekkel rendelkezik a megfelelő sablonhelyőrzők nélkül, a fordító SYSLIB1015 figyelmeztetést ad ki. Ezek a paraméterek naplóállapotban vannak tárolva, de nem jelennek meg a formázott naplókimenetben. Csak olyan strukturált naplózási szolgáltatók jelenítik meg azokat, amelyek felsorolják a napló állapotát.
Naplómetódus korlátozásai
A feldíszített LoggerMessageAttribute naplózási módszereknek meg kell felelniük a következő követelményeknek:
- A naplózási módszereknek meg kell lenniük
partial, és vissza kell adniukvoid. - A naplózási metódusok neve nem kezdődhet aláhúzásjellel.
- A naplózási módszerek paraméternevei nem kezdődnek aláhúzásjellel.
- A naplózási módszerek támogatják az általános típusparamétereket, de a C# 13
allows ref structkorlátozásmentesség nem támogatott. - A naplózási metódus paraméterei nem használhatják a
params,scopedvagyoutmódosítókat, és nem lehetnekref structtípusok. - Ha naplózási módszerről van szó
static, aILoggerpéldány paraméterként szükséges.
A kódgenerálási modell attól függ, hogy a kód egy modern C#-fordítóval, azaz 9-es vagy újabb verzióval van-e lefordítva. A nyelvi verzió módosításáról további információt a C# nyelvi verziószámozásával kapcsolatban talál.
Naplómetódus anatómiája
A ILogger.Log aláírás elfogadja a LogLevel és opcionálisan egy Exception, a következő kód példában látható módon.
public interface ILogger
{
void Log<TState>(
Microsoft.Extensions.Logging.LogLevel logLevel,
Microsoft.Extensions.Logging.EventId eventId,
TState state,
System.Exception? exception,
Func<TState, System.Exception?, string> formatter);
}
Általános szabályként a ILogger, LogLevel és Exception első példányát különleges kezelésben részesítik a forrásgenerátor naplózási metódusának szignatúrájában. A következő példányok az üzenetsablon normál paramétereiként lesznek kezelve:
// This is a valid attribute usage
[LoggerMessage(
EventId = 110, Level = LogLevel.Debug, Message = "M1 {Ex3} {Ex2}")]
public static partial void ValidLogMethod(
ILogger logger,
Exception ex,
Exception ex2,
Exception ex3);
// This causes a warning
[LoggerMessage(
EventId = 0, Level = LogLevel.Debug, Message = "M1 {Ex} {Ex2}")]
public static partial void WarningLogMethod(
ILogger logger,
Exception ex,
Exception ex2);
Fontos
A megjelenő figyelmeztetések részletesen ismertetik a helyes használatot LoggerMessageAttribute. Az előző példában a WarningLogMethod egy DiagnosticSeverity.WarningSYSLIB0025 értéket jelent.
Don't include a template for `ex` in the logging message since it is implicitly taken care of.
Kis- és nagybetűket nem megkülönböztető sablonnév támogatása
A generátor kis- és nagybetűk közötti összehasonlítást végez az üzenetsablon elemei és a naplóüzenet argumentumnevei között. Ez azt jelenti, hogy amikor az ILogger enumerálja az állapotot, az argumentumot az üzenetsablon használja, így a naplók könnyebben olvashatók.
public partial class LoggingExample
{
private readonly ILogger _logger;
public LoggingExample(ILogger logger)
{
_logger = logger;
}
[LoggerMessage(
EventId = 10,
Level = LogLevel.Information,
Message = "Welcome to {City} {Province}!")]
public partial void LogMethodSupportsPascalCasingOfNames(
string city, string province);
public void TestLogging()
{
LogMethodSupportsPascalCasingOfNames("Vancouver", "BC");
}
}
Fontolja meg a példa naplózási kimenetet a JsonConsole formázó használatakor:
{
"EventId": 13,
"LogLevel": "Information",
"Category": "LoggingExample",
"Message": "Welcome to Vancouver BC!",
"State": {
"Message": "Welcome to Vancouver BC!",
"City": "Vancouver",
"Province": "BC",
"{OriginalFormat}": "Welcome to {City} {Province}!"
}
}
Meghatározatlan paramétersorrend
A naplómetódus paramétereinek sorrendjére nincsenek korlátozások. A fejlesztő definiálhatja az ILogger utolsó paramétert, bár kissé kínosnak tűnhet.
[LoggerMessage(
EventId = 110,
Level = LogLevel.Debug,
Message = "M1 {Ex3} {Ex2}")]
static partial void LogMethod(
Exception ex,
Exception ex2,
Exception ex3,
ILogger logger);
Jótanács
A naplómetódus paramétereinek sorrendje nem szükséges ahhoz, hogy megfeleljen a sablon helyőrzőinek sorrendjének. A sablon helyőrző neveinek elvárás szerint meg kell felelniük a paramétereknek. Vegye figyelembe a következő JsonConsole kimenetet és a hibák sorrendjét.
{
"EventId": 110,
"LogLevel": "Debug",
"Category": "ConsoleApp.Program",
"Message": "M1 System.Exception: Third time's the charm. System.Exception: This is the second error.",
"State": {
"Message": "M1 System.Exception: Third time's the charm. System.Exception: This is the second error.",
"ex2": "System.Exception: This is the second error.",
"ex3": "System.Exception: Third time's the charm.",
"{OriginalFormat}": "M1 {Ex3} {Ex2}"
}
}
További naplózási példák
Az alábbi minták bemutatják, hogyan kérhető le az esemény neve, hogyan állíthatja be dinamikusan a naplószintet, és hogyan formázhatja a naplózási paramétereket. A naplózási módszerek a következők:
-
LogWithCustomEventName: Eseménynév lekérése attribútumon keresztülLoggerMessage. -
LogWithDynamicLogLevel: Dinamikusan állítsa be a naplószintet, hogy a naplószint a konfigurációs bemenet alapján legyen beállítva. -
UsingFormatSpecifier: A naplózási paraméterek formázásához használjon formátumjelölőket.
public partial class LoggingSample
{
private readonly ILogger _logger;
public LoggingSample(ILogger logger)
{
_logger = logger;
}
[LoggerMessage(
EventId = 20,
Level = LogLevel.Critical,
Message = "Value is {Value:E}")]
public static partial void UsingFormatSpecifier(
ILogger logger, double value);
[LoggerMessage(
EventId = 9,
Level = LogLevel.Trace,
Message = "Fixed message",
EventName = "CustomEventName")]
public partial void LogWithCustomEventName();
[LoggerMessage(
EventId = 10,
Message = "Welcome to {City} {Province}!")]
public partial void LogWithDynamicLogLevel(
string city, LogLevel level, string province);
public void TestLogging()
{
LogWithCustomEventName();
LogWithDynamicLogLevel("Vancouver", LogLevel.Warning, "BC");
LogWithDynamicLogLevel("Vancouver", LogLevel.Information, "BC");
UsingFormatSpecifier(logger, 12345.6789);
}
}
Fontolja meg a példa naplózási kimenetet a SimpleConsole formázó használatakor:
trce: LoggingExample[9]
Fixed message
warn: LoggingExample[10]
Welcome to Vancouver BC!
info: LoggingExample[10]
Welcome to Vancouver BC!
crit: LoggingExample[20]
Value is 1.234568E+004
Fontolja meg a példa naplózási kimenetet a JsonConsole formázó használatakor:
{
"EventId": 9,
"LogLevel": "Trace",
"Category": "LoggingExample",
"Message": "Fixed message",
"State": {
"Message": "Fixed message",
"{OriginalFormat}": "Fixed message"
}
}
{
"EventId": 10,
"LogLevel": "Warning",
"Category": "LoggingExample",
"Message": "Welcome to Vancouver BC!",
"State": {
"Message": "Welcome to Vancouver BC!",
"city": "Vancouver",
"province": "BC",
"{OriginalFormat}": "Welcome to {City} {Province}!"
}
}
{
"EventId": 10,
"LogLevel": "Information",
"Category": "LoggingExample",
"Message": "Welcome to Vancouver BC!",
"State": {
"Message": "Welcome to Vancouver BC!",
"city": "Vancouver",
"province": "BC",
"{OriginalFormat}": "Welcome to {City} {Province}!"
}
}
{
"EventId": 20,
"LogLevel": "Critical",
"Category": "LoggingExample",
"Message": "Value is 1.234568E+004",
"State": {
"Message": "Value is 1.234568E+004",
"value": 12345.6789,
"{OriginalFormat}": "Value is {Value:E}"
}
}
Bizalmas adatok kitakarása a naplókban
Bizalmas adatok naplózásakor fontos megelőzni a véletlen expozíciót. A nyers bizalmas értékek naplózása még fordítási időben létrehozott naplózási módszerek esetén is adatszivárgáshoz és megfelelőségi problémákhoz vezethet.
A Microsoft.Extensions.Telemetria kódtár fejlett naplózási és telemetriai bővítési képességeket biztosít .NET alkalmazásokhoz. Kibővíti a naplózási folyamatot, hogy automatikusan alkalmazza a titkosított adatokra a naplók írásakor történő újraírást. Lehetővé teszi az adatvédelmi szabályzatok alkalmazáson keresztüli kikényszerítését a naplózási munkafolyamatba való újralépés integrálásával. Kifinomult telemetriai és naplózási megállapításokat igénylő alkalmazásokhoz készült.
A redaction engedélyezéséhez használja a Microsoft.Extensions.Compliance.Redaction kódtárat . Ez a kódtár olyan összetevőket biztosít, amelyek átalakítják a bizalmas adatokat (például törléssel, maszkolással vagy kivonatolással), hogy biztonságos legyen a kimenet. A redaktorok az adatbesorolás alapján vannak kiválasztva, amely lehetővé teszi az adatok bizalmassági (például személyes, privát vagy nyilvános) szerinti címkézését.
Forrás által generált naplózási módszerek használatához a szerkesztésekhez, tegye a következőket:
- Osztályozza a bizalmas adatokat egy adatbesorolási rendszer használatával.
- Regisztrálja és konfigurálja a redaktorokat a DI-tárolóban lévő egyes besorolásokhoz.
- Engedélyezze az érzékeny adatok elrejtését a naplózási folyamatban.
- Ellenőrizze a naplókat, hogy ne tegyenek ki bizalmas adatokat.
Ha például van egy naplóüzenete, amely egy privátnak tekintett paraméterrel rendelkezik:
[LoggerMessage(0, LogLevel.Information, "User SSN: {SSN}")]
public static partial void LogPrivateInformation(
this ILogger logger,
[MyTaxonomyClassifications.Private] string SSN);
Ehhez hasonló beállításra lesz szüksége:
using Microsoft.Extensions.Telemetry;
using Microsoft.Extensions.Compliance.Redaction;
var services = new ServiceCollection();
services.AddLogging(builder =>
{
// Enable redaction.
builder.EnableRedaction();
});
services.AddRedaction(builder =>
{
// configure redactors for your data classifications
builder.SetRedactor<StarRedactor>(MyTaxonomyClassifications.Private);
});
public void TestLogging()
{
LogPrivateInformation("MySSN");
}
A kimenetnek a következőhöz hasonlónak kell lennie:
User SSN: *****
Ez a megközelítés biztosítja, hogy csak az anonimizált adatok legyenek naplózva, még fordítási idő alatt generált naplózási API-k használata esetén is. A különböző adattípusokhoz vagy besorolásokhoz különböző redaktorokat használhat, és központilag frissítheti a redaction logikát.
Az adatok besorolásáról további információt a Adatbesorolás .NET című témakörben talál. További információ a kitakarásról és a kitakaró eszközökről: Adatok kitakarása a .NET-ben.
Összefoglalás
A C#-forrásgenerátorok megjelenésével a nagy teljesítményű naplózási API-k írása egyszerűbb. A forrásgenerátor megközelítésének számos fő előnye van:
- Lehetővé teszi a naplózási struktúra megőrzését, és lehetővé teszi az üzenetsablonok által megkövetelt pontos formátumszintaxis megőrzését.
- Lehetővé teszi alternatív nevek megadását a sablon helyőrzőinek és formátumjelölők használatával.
- Lehetővé teszi az összes eredeti adat átadását, komplikációk nélkül a tárolásuk módjával kapcsolatban, mielőtt bármit tesznek velük (a
stringlétrehozását leszámítva). - Naplózásspecifikus diagnosztikát biztosít, és figyelmeztetéseket ad ki ismétlődő eseményazonosítókhoz.
Emellett a manuális használatnak LoggerMessage.Defineis vannak előnyei:
- Rövidebb és egyszerűbb szintaxis: Deklaratív attribútumhasználat a sablon kódolása helyett.
- Irányított fejlesztői élmény: A generátor figyelmeztetéseket ad, amelyek segítenek a fejlesztőknek a helyes lépésben.
- Tetszőleges számú naplózási paraméter támogatása.
LoggerMessage.Definelegfeljebb hatot támogat. - Dinamikus naplószint támogatása. Ez egyedül nem lehetséges
LoggerMessage.Define.