Protokolování s vysokým výkonem pomocí LoggerMessage v ASP.NET Core

LoggerMessage funkce vytvářejí delegáty, které umožňují ukládání do mezipaměti, které vyžadují méně přidělení objektů a snižují výpočetní režii v porovnání s metodami rozšíření protokolovacíhonástroje, jako jsou LogInformation a LogDebug . Pro scénáře protokolování s vysokým výkonem použijte LoggerMessage vzor.

LoggerMessage poskytuje následující výhody výkonu v rámci rozšiřujících metod protokolovacího nástroje:

  • Metody rozšíření protokolovacího nástroje vyžadují "zabalení" (převod) typů hodnot, například int do object . LoggerMessageVzor zabraňuje zabalení pomocí statických Action polí a metod rozšíření s parametry silného typu.
  • Metody rozšíření protokolovacího nástroje musí při každém zápisu zprávy protokolu analyzovat šablonu zprávy (pojmenovaný řetězec formátu). LoggerMessage pouze při definování zprávy vyžaduje pouze analýzu šablony.

Zobrazit nebo stáhnout ukázkový kód (Jak stáhnout)

Ukázková aplikace ukazuje LoggerMessage funkce se základním systémem pro sledování nabídek. Aplikace přidá a odstraní uvozovky pomocí databáze v paměti. Při výskytu těchto operací se zprávy protokolu generují pomocí LoggerMessage vzoru.

LoggerMessage. define

Define (LogLevel, ID události, String) vytvoří Action delegáta pro protokolování zprávy. Define přetížení povolují předání až šesti parametrů typu pojmenovanému formátovacímu řetězci (Template).

Řetězec poskytnutý Define metodě je šablona, nikoli interpolovaná řetězec. Zástupné symboly jsou vyplněny v pořadí, v jakém jsou typy zadány. Zástupné názvy v šabloně by měly být popisné a konzistentní v rámci šablon. Slouží jako názvy vlastností v rámci strukturovaných dat protokolu. Pro názvy zástupných symbolů doporučujeme použít velká písmena Pascal . Například {Count} , {FirstName} .

Každá zpráva protokolu je Action držená ve statickém poli vytvořeném pomocí LoggerMessage. define. Ukázková aplikace například vytvoří pole pro popis zprávy protokolu pro požadavek GET na stránku indexu (interní/LoggerExtensions. cs):

private static readonly Action<ILogger, Exception> _indexPageRequested;

Pro Action zadejte:

  • Úroveň protokolování
  • Jedinečný identifikátor události ( EventId ) s názvem statické metody rozšíření.
  • Šablona zprávy (pojmenovaný řetězec formátu).

Požadavek na stránku index ukázkové aplikace nastaví:

  • Úroveň protokolu do Information .
  • ID události na 1 název IndexPageRequested metody
  • Šablona zprávy (pojmenovaný řetězec formátu) k řetězci.
_indexPageRequested = LoggerMessage.Define(
    LogLevel.Information, 
    new EventId(1, nameof(IndexPageRequested)), 
    "GET request for Index page");

Úložiště strukturovaného protokolování můžou použít název události, když se poskytne s ID události pro rozšíření protokolování. Serilog například používá název události.

ActionJe vyvolána prostřednictvím rozšiřující metody silného typu. IndexPageRequestedMetoda zaznamená zprávu pro požadavek na stránku indexu v ukázkové aplikaci:

public static void IndexPageRequested(this ILogger logger)
{
    _indexPageRequested(logger, null);
}

IndexPageRequested se volá v protokolovacím nástroji v OnGetAsync metodě na stránkách pages/index. cshtml. cs:

public async Task OnGetAsync()
{
    _logger.IndexPageRequested();

    Quotes = await _db.Quotes.AsNoTracking().ToListAsync();
}

Zkontrolujte výstup konzoly aplikace:

info: LoggerMessageSample.Pages.IndexModel[1]
      => RequestId:0HL90M6E7PHK4:00000001 RequestPath:/ => /Index
      GET request for Index page

Chcete-li předat parametry do zprávy protokolu, definujte při vytváření statického pole až šest typů. Ukázková aplikace při přidávání nabídky zaznamená řetězec tak, že definuje string typ Action pole:

private static readonly Action<ILogger, string, Exception> _quoteAdded;

Šablona zprávy protokolu delegáta přijímá své zástupné hodnoty z poskytnutých typů. Ukázková aplikace definuje delegáta pro přidání nabídky, kde je parametrem nabídky string :

_quoteAdded = LoggerMessage.Define<string>(
    LogLevel.Information, 
    new EventId(2, nameof(QuoteAdded)), 
    "Quote added (Quote = '{Quote}')");

Statická rozšiřující metoda pro přidání nabídky, QuoteAdded přijímá hodnotu argumentu citace a předá ji Action delegátovi:

public static void QuoteAdded(this ILogger logger, string quote)
{
    _quoteAdded(logger, quote, null);
}

V modelu stránky indexu stránky (pages/index. cshtml. cs) QuoteAdded se volá, aby se zaprotokoloval zpráva:

public async Task<IActionResult> OnPostAddQuoteAsync()
{
    _db.Quotes.Add(Quote);
    await _db.SaveChangesAsync();

    _logger.QuoteAdded(Quote.Text);

    return RedirectToPage();
}

Zkontrolujte výstup konzoly aplikace:

info: LoggerMessageSample.Pages.IndexModel[2]
      => RequestId:0HL90M6E7PHK5:0000000A RequestPath:/ => /Index
      Quote added (Quote = 'You can avoid reality, but you cannot avoid the 
          consequences of avoiding reality. - Ayn Rand')

Ukázková aplikace implementuje vzor try-catch pro odstranění nabídky. Informační zpráva se zaznamená do protokolu pro úspěšnou operaci odstranění. Pokud je vyvolána výjimka, je zaznamenána chybová zpráva pro operaci odstranění. Zpráva protokolu pro neúspěšnou operaci odstranění zahrnuje trasování zásobníku výjimky (interní/LoggerExtensions. cs):

private static readonly Action<ILogger, string, int, Exception> _quoteDeleted;
private static readonly Action<ILogger, int, Exception> _quoteDeleteFailed;
_quoteDeleted = LoggerMessage.Define<string, int>(
    LogLevel.Information, 
    new EventId(4, nameof(QuoteDeleted)), 
    "Quote deleted (Quote = '{Quote}' Id = {Id})");

_quoteDeleteFailed = LoggerMessage.Define<int>(
    LogLevel.Error, 
    new EventId(5, nameof(QuoteDeleteFailed)), 
    "Quote delete failed (Id = {Id})");

Všimněte si, jak je výjimka předána delegátovi v QuoteDeleteFailed :

public static void QuoteDeleted(this ILogger logger, string quote, int id)
{
    _quoteDeleted(logger, quote, id, null);
}

public static void QuoteDeleteFailed(this ILogger logger, int id, Exception ex)
{
    _quoteDeleteFailed(logger, id, ex);
}

V modelu stránky pro stránku index je úspěšné odstranění citace voláním QuoteDeleted metody protokolovacího nástroje. Pokud se nabídka nenajde pro odstranění, ArgumentNullException vyvolá se. Výjimka je zachycena příkazem try-catch a protokolována voláním metody v QuoteDeleteFailed protokolovacím nástroji v bloku catch (pages/index. cshtml. cs):

public async Task<IActionResult> OnPostDeleteQuoteAsync(int id)
{
    try
    {
        var quote = await _db.Quotes.FindAsync(id);
        _db.Quotes.Remove(quote);
        await _db.SaveChangesAsync();

        _logger.QuoteDeleted(quote.Text, id);
    }
    catch (NullReferenceException ex)
    {
        _logger.QuoteDeleteFailed(id, ex);
    }

    return RedirectToPage();
}

Po úspěšném odstranění nabídky zkontrolujte výstup konzoly aplikace:

info: LoggerMessageSample.Pages.IndexModel[4]
      => RequestId:0HL90M6E7PHK5:00000016 RequestPath:/ => /Index
      Quote deleted (Quote = 'You can avoid reality, but you cannot avoid the 
          consequences of avoiding reality. - Ayn Rand' Id = 1)

Pokud se odstranění citace nepovede, zkontrolujte výstup konzoly aplikace. Všimněte si, že je tato výjimka součástí zprávy protokolu:

LoggerMessageSample.Pages.IndexModel: Error: Quote delete failed (Id = 999)

System.NullReferenceException: Object reference not set to an instance of an object.
   at lambda_method(Closure , ValueBuffer )
   at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at LoggerMessageSample.Pages.IndexModel.OnPostDeleteQuoteAsync(Int32 id) in c:\Users\guard\Documents\GitHub\Docs\aspnetcore\fundamentals\logging\loggermessage\samples\3.x\LoggerMessageSample\Pages\Index.cshtml.cs:line 77

LoggerMessage. Definescope –

Definescope – (String) vytvoří Func<TResult> delegáta pro definování oboru protokolu. DefineScope přetížení povolují předání až tří parametrů typu pojmenovanému formátovacímu řetězci (Template).

Stejně jako v případě Define metody, řetězec poskytnutý DefineScope metodě je šablona, nikoli interpolovaná řetězec. Zástupné symboly jsou vyplněny v pořadí, v jakém jsou typy zadány. Zástupné názvy v šabloně by měly být popisné a konzistentní v rámci šablon. Slouží jako názvy vlastností v rámci strukturovaných dat protokolu. Pro názvy zástupných symbolů doporučujeme použít velká písmena Pascal . Například {Count} , {FirstName} .

Definujte Rozsah protokolu , který se má použít pro řadu zpráv protokolu pomocí DefineScope metody.

Ukázková aplikace má tlačítko Zrušit vše pro odstranění všech nabídek v databázi. Tyto nabídky jsou odstraněny po jednom jejich odebráním. Pokaždé, když se odstraní citace, QuoteDeleted metoda se zavolá do protokolovacího nástroje. Do těchto zpráv protokolu se přidá rozsah protokolu.

Povolit IncludeScopes v části protokolovacího nástroje konzoly appsettings.json :

{
  "Logging": {
    "Console": {
      "IncludeScopes": true
    },
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Chcete-li vytvořit rozsah protokolu, přidejte pole pro blokování Func<TResult> delegáta oboru. Ukázková aplikace vytvoří pole s názvem _allQuotesDeletedScope (interní/LoggerExtensions. cs):

private static Func<ILogger, int, IDisposable> _allQuotesDeletedScope;

Použijte DefineScope k vytvoření delegáta. Až tři typy lze zadat pro použití jako argumenty šablony při volání delegáta. Ukázková aplikace používá šablonu zprávy, která obsahuje počet odstraněných uvozovek ( int typ):

_allQuotesDeletedScope = 
    LoggerMessage.DefineScope<int>("All quotes deleted (Count = {Count})");

Zadejte statickou metodu rozšíření pro zprávu protokolu. Zahrňte všechny parametry typu pro pojmenované vlastnosti, které se zobrazí v šabloně zprávy. Ukázková aplikace se převezme v count uvozovkách, které se mají odstranit a vrátí _allQuotesDeletedScope :

public static IDisposable AllQuotesDeletedScope(
    this ILogger logger, int count)
{
    return _allQuotesDeletedScope(logger, count);
}

Obor zabalí volání rozšíření protokolování v bloku using :

public async Task<IActionResult> OnPostDeleteAllQuotesAsync()
{
    var quoteCount = await _db.Quotes.CountAsync();

    using (_logger.AllQuotesDeletedScope(quoteCount))
    {
        foreach (Quote quote in _db.Quotes)
        {
            _db.Quotes.Remove(quote);

            _logger.QuoteDeleted(quote.Text, quote.Id);
        }
        await _db.SaveChangesAsync();
    }

    return RedirectToPage();
}

Zkontrolujte zprávy protokolu ve výstupu konzoly aplikace. Následující výsledek obsahuje tři nabídky odstraněné se zprávou rozsah protokolu, která je součástí:

info: LoggerMessageSample.Pages.IndexModel[4]
      => RequestId:0HL90M6E7PHK5:0000002E RequestPath:/ => /Index => 
          All quotes deleted (Count = 3)
      Quote deleted (Quote = 'Quote 1' Id = 2)
info: LoggerMessageSample.Pages.IndexModel[4]
      => RequestId:0HL90M6E7PHK5:0000002E RequestPath:/ => /Index => 
          All quotes deleted (Count = 3)
      Quote deleted (Quote = 'Quote 2' Id = 3)
info: LoggerMessageSample.Pages.IndexModel[4]
      => RequestId:0HL90M6E7PHK5:0000002E RequestPath:/ => /Index => 
          All quotes deleted (Count = 3)
      Quote deleted (Quote = 'Quote 3' Id = 4)

LoggerMessage funkce vytvářejí delegáty, které umožňují ukládání do mezipaměti, které vyžadují méně přidělení objektů a snižují výpočetní režii v porovnání s metodami rozšíření protokolovacíhonástroje, jako jsou LogInformation a LogDebug . Pro scénáře protokolování s vysokým výkonem použijte LoggerMessage vzor.

LoggerMessage poskytuje následující výhody výkonu v rámci rozšiřujících metod protokolovacího nástroje:

  • Metody rozšíření protokolovacího nástroje vyžadují "zabalení" (převod) typů hodnot, například int do object . LoggerMessageVzor zabraňuje zabalení pomocí statických Action polí a metod rozšíření s parametry silného typu.
  • Metody rozšíření protokolovacího nástroje musí při každém zápisu zprávy protokolu analyzovat šablonu zprávy (pojmenovaný řetězec formátu). LoggerMessage pouze při definování zprávy vyžaduje pouze analýzu šablony.

Zobrazit nebo stáhnout ukázkový kód (Jak stáhnout)

Ukázková aplikace ukazuje LoggerMessage funkce se základním systémem pro sledování nabídek. Aplikace přidá a odstraní uvozovky pomocí databáze v paměti. Při výskytu těchto operací se zprávy protokolu generují pomocí LoggerMessage vzoru.

LoggerMessage. define

Define (LogLevel, ID události, String) vytvoří Action delegáta pro protokolování zprávy. Define přetížení povolují předání až šesti parametrů typu pojmenovanému formátovacímu řetězci (Template).

Řetězec poskytnutý Define metodě je šablona, nikoli interpolovaná řetězec. Zástupné symboly jsou vyplněny v pořadí, v jakém jsou typy zadány. Zástupné názvy v šabloně by měly být popisné a konzistentní v rámci šablon. Slouží jako názvy vlastností v rámci strukturovaných dat protokolu. Jako zástupné názvy doporučujeme používat jazyk Pascal Casing. Například , {Count} {FirstName} .

Každá zpráva protokolu je ve Action statickém poli vytvořeném protokolovací zprávou LoggerMessage.Define. Ukázková aplikace například vytvoří pole pro popis zprávy protokolu pro požadavek GET pro stránku indexu (Internal/LoggerExtensions.cs):

private static readonly Action<ILogger, Exception> _indexPageRequested;

Pro Action zadejte:

  • Úroveň protokolování
  • Jedinečný identifikátor události ( EventId ) s názvem metody statického rozšíření.
  • Šablona zprávy (pojmenovaný formátovací řetězec).

Požadavek na stránku Index ukázkové aplikace nastaví:

  • Přihlaste se na Information úroveň .
  • ID události 1 na s názvem IndexPageRequested metody.
  • Šablona zprávy (pojmenovaný formátovací řetězec) na řetězec.
_indexPageRequested = LoggerMessage.Define(
    LogLevel.Information, 
    new EventId(1, nameof(IndexPageRequested)), 
    "GET request for Index page");

Strukturovaná úložiště protokolování mohou k rozšíření protokolování použít název události, pokud je součástí ID události. Například Serilog používá název události.

Je Action vyvolána prostřednictvím metody rozšíření silného typu. Metoda IndexPageRequested zaznamená zprávu pro požadavek GET indexové stránky v ukázkové aplikaci:

public static void IndexPageRequested(this ILogger logger)
{
    _indexPageRequested(logger, null);
}

IndexPageRequested se volá v protokolovači v OnGetAsync metodě v Pages/Index.cshtml.cs:

public async Task OnGetAsync()
{
    _logger.IndexPageRequested();

    Quotes = await _db.Quotes.AsNoTracking().ToListAsync();
}

Zkontrolujte výstup konzoly aplikace:

info: LoggerMessageSample.Pages.IndexModel[1]
      => RequestId:0HL90M6E7PHK4:00000001 RequestPath:/ => /Index
      GET request for Index page

Pokud chcete do zprávy protokolu předat parametry, definujte při vytváření statického pole až šest typů. Ukázková aplikace protokoluje řetězec při přidávání uvozovek string definováním typu Action pro pole:

private static readonly Action<ILogger, string, Exception> _quoteAdded;

Šablona zprávy protokolu delegáta přijímá zástupné hodnoty z poskytnutých typů. Ukázková aplikace definuje delegáta pro přidání uvozovek, kde parametr nabídky je string :

_quoteAdded = LoggerMessage.Define<string>(
    LogLevel.Information, 
    new EventId(2, nameof(QuoteAdded)), 
    "Quote added (Quote = '{Quote}')");

Metoda statického rozšíření pro přidání uvozovek přijme hodnotu argumentu uvozovek a QuoteAdded předá ji Action delegátovi:

public static void QuoteAdded(this ILogger logger, string quote)
{
    _quoteAdded(logger, quote, null);
}

V modelu stránky indexové stránky (Pages/Index.cshtml.cs) se volá pro QuoteAdded protokolování zprávy:

public async Task<IActionResult> OnPostAddQuoteAsync()
{
    _db.Quotes.Add(Quote);
    await _db.SaveChangesAsync();

    _logger.QuoteAdded(Quote.Text);

    return RedirectToPage();
}

Zkontrolujte výstup konzoly aplikace:

info: LoggerMessageSample.Pages.IndexModel[2]
      => RequestId:0HL90M6E7PHK5:0000000A RequestPath:/ => /Index
      Quote added (Quote = 'You can avoid reality, but you cannot avoid the 
          consequences of avoiding reality. - Ayn Rand')

Ukázková aplikace implementuje vzor try-catch pro odstranění nabídky. Pro úspěšnou operaci odstranění se zaprotokoluje informační zpráva. Při vyvolání výjimky se pro operaci odstranění zaprotokoluje chybová zpráva. Zpráva protokolu pro neúspěšnou operaci odstranění zahrnuje trasování zásobníku výjimek (Internal/LoggerExtensions.cs):

private static readonly Action<ILogger, string, int, Exception> _quoteDeleted;
private static readonly Action<ILogger, int, Exception> _quoteDeleteFailed;
_quoteDeleted = LoggerMessage.Define<string, int>(
    LogLevel.Information, 
    new EventId(4, nameof(QuoteDeleted)), 
    "Quote deleted (Quote = '{Quote}' Id = {Id})");

_quoteDeleteFailed = LoggerMessage.Define<int>(
    LogLevel.Error, 
    new EventId(5, nameof(QuoteDeleteFailed)), 
    "Quote delete failed (Id = {Id})");

Všimněte si, jak je výjimka předána delegátu v QuoteDeleteFailed :

public static void QuoteDeleted(this ILogger logger, string quote, int id)
{
    _quoteDeleted(logger, quote, id, null);
}

public static void QuoteDeleteFailed(this ILogger logger, int id, Exception ex)
{
    _quoteDeleteFailed(logger, id, ex);
}

V modelu stránky pro stránku Index volá úspěšné odstranění nabídky QuoteDeleted metodu na protokolovací nástroj. Pokud se pro odstranění nenašla nabídka, vyvolá ArgumentNullException se . Výjimka je zachycena příkazem try-catch a zaprotokolována voláním metody na protokolovači v QuoteDeleteFailed bloku catch (Pages/Index.cshtml.cs):

public async Task<IActionResult> OnPostDeleteQuoteAsync(int id)
{
    var quote = await _db.Quotes.FindAsync(id);

    // DO NOT use this approach in production code!
    // You should check quote to see if it's null before removing 
    // it and saving changes to the database. A try-catch is used 
    // here for demonstration purposes of LoggerMessage features.
    try
    {
        _db.Quotes.Remove(quote);
        await _db.SaveChangesAsync();

        _logger.QuoteDeleted(quote.Text, id);
    }
    catch (ArgumentNullException ex)
    {
        _logger.QuoteDeleteFailed(id, ex);
    }

    return RedirectToPage();
}

Po úspěšném odstranění nabídky zkontrolujte výstup konzoly aplikace:

info: LoggerMessageSample.Pages.IndexModel[4]
      => RequestId:0HL90M6E7PHK5:00000016 RequestPath:/ => /Index
      Quote deleted (Quote = 'You can avoid reality, but you cannot avoid the 
          consequences of avoiding reality. - Ayn Rand' Id = 1)

Pokud odstranění nabídky selže, zkontrolujte výstup konzoly aplikace. Všimněte si, že výjimka je součástí zprávy protokolu:

fail: LoggerMessageSample.Pages.IndexModel[5]
      => RequestId:0HL90M6E7PHK5:00000010 RequestPath:/ => /Index
      Quote delete failed (Id = 999)
System.ArgumentNullException: Value cannot be null.
Parameter name: entity
   at Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T]
       (T value, String parameterName)
   at Microsoft.EntityFrameworkCore.DbContext.Remove[TEntity](TEntity entity)
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Remove(TEntity entity)
   at LoggerMessageSample.Pages.IndexModel.<OnPostDeleteQuoteAsync>d__14.MoveNext() 
      in <PATH>\sample\Pages\Index.cshtml.cs:line 87

LoggerMessage.DefineScope

DefineScope(String) vytvoří Func<TResult> delegáta pro definování oboru protokolu. DefineScope přetížení umožňují předání až tří parametrů typu pojmenovanému formátovacímu řetězci (šabloně).

Stejně jako u metody je řetězec poskytnutý metodě Define DefineScope šablonou, nikoli interpolovaným řetězcem. Zástupné symboly jsou vyplněné v pořadí, ve které jsou typy zadány. Zástupné názvy v šabloně by měly být popisné a konzistentní napříč šablonami. Slouží jako názvy vlastností v rámci strukturovaných dat protokolu. Jako zástupné názvy doporučujeme používat jazyk Pascal Casing. Například , {Count} {FirstName} .

Definujte obor protokolu, který se použije na řadu zpráv protokolu pomocí DefineScope metody .

Ukázková aplikace má tlačítko Vymazat vše pro odstranění všech uvozovek v databázi. Uvozovky se odstraní tak, že je odeberete po jedné. Při každém odstranění nabídky se v protokolovači QuoteDeleted volá metoda . Do těchto zpráv protokolu se přidá obor protokolu.

Povolte IncludeScopes v oddílu protokolovacího nástroje konzoly v appsettings.json nástroji :

{
  "Logging": {
    "Console": {
      "IncludeScopes": true
    },
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Chcete-li vytvořit obor protokolu, přidejte pole pro blokování Func<TResult> delegáta pro obor. Ukázková aplikace vytvoří pole s názvem _allQuotesDeletedScope (Internal/LoggerExtensions.cs):

private static Func<ILogger, int, IDisposable> _allQuotesDeletedScope;

Slouží DefineScope k vytvoření delegáta. Až tři typy lze zadat pro použití jako argumenty šablony při vyvolání delegátu. Ukázková aplikace používá šablonu zprávy, která obsahuje počet odstraněných uvozovek int (typ):

_allQuotesDeletedScope = 
    LoggerMessage.DefineScope<int>("All quotes deleted (Count = {Count})");

Zadejte metodu statického rozšíření pro zprávu protokolu. Zahrnte všechny parametry typu pro pojmenované vlastnosti, které se zobrazí v šabloně zprávy. Ukázková aplikace používá k odstranění a count vrácení uvozovek _allQuotesDeletedScope :

public static IDisposable AllQuotesDeletedScope(
    this ILogger logger, int count)
{
    return _allQuotesDeletedScope(logger, count);
}

Obor zabalí volání rozšíření protokolování do bloku using:

public async Task<IActionResult> OnPostDeleteAllQuotesAsync()
{
    var quoteCount = await _db.Quotes.CountAsync();

    using (_logger.AllQuotesDeletedScope(quoteCount))
    {
        foreach (Quote quote in _db.Quotes)
        {
            _db.Quotes.Remove(quote);

            _logger.QuoteDeleted(quote.Text, quote.Id);
        }
        await _db.SaveChangesAsync();
    }

    return RedirectToPage();
}

Zkontrolujte zprávy protokolu ve výstupu konzoly aplikace. Následující výsledek ukazuje tři uvozovky odstraněné se zprávou oboru protokolu:

info: LoggerMessageSample.Pages.IndexModel[4]
      => RequestId:0HL90M6E7PHK5:0000002E RequestPath:/ => /Index => 
          All quotes deleted (Count = 3)
      Quote deleted (Quote = 'Quote 1' Id = 2)
info: LoggerMessageSample.Pages.IndexModel[4]
      => RequestId:0HL90M6E7PHK5:0000002E RequestPath:/ => /Index => 
          All quotes deleted (Count = 3)
      Quote deleted (Quote = 'Quote 2' Id = 3)
info: LoggerMessageSample.Pages.IndexModel[4]
      => RequestId:0HL90M6E7PHK5:0000002E RequestPath:/ => /Index => 
          All quotes deleted (Count = 3)
      Quote deleted (Quote = 'Quote 3' Id = 4)

Další zdroje informací