Registrazione in .NET Core e ASP.NET Core

Di Kirk Larkin, Juergen Gutsch e Rick Anderson

Questo articolo descrive la registrazione in .NET perché si applica alle app ASP.NET Core. Per informazioni dettagliate sulla registrazione in .NET, vedere Registrazione in .NET. Per altre informazioni sulla registrazione nelle app Blazor, vedere Registrazione in ASP.NET Core Blazor.

Provider di registrazione

I provider di registrazione archiviano i log, ad eccezione del provider Console che li visualizza. Ad esempio, il provider Azure Application Insights archivia i log in Azure Application Insights. È possibile abilitare più provider.

I modelli predefiniti di app Web core ASP.NET chiamano WebApplication.CreateBuilder, che aggiunge i provider di registrazione seguenti:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Il codice precedente mostra il file Program.cs creato con i modelli di app Web ASP.NET Core. Le sezioni successive forniscono esempi basati sui modelli di app Web core di ASP.NET.

Il codice seguente sostituisce il set predefinito di provider di registrazione aggiunti da WebApplication.CreateBuilder:

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

In alternativa, il codice di registrazione precedente può essere scritto come segue:

var builder = WebApplication.CreateBuilder();
builder.Host.ConfigureLogging(logging =>
{
    logging.ClearProviders();
    logging.AddConsole();
});

Per altri provider, vedere:

Creare log

Per creare i log, usare un oggetto ILogger<TCategoryName> dall'inserimento delle dipendenze.

L'esempio seguente:

  • Crea un logger, ILogger<AboutModel>, che usa una categoria di log del nome completo del tipo AboutModel. La categoria del log è una stringa associata a ogni log.
  • Chiama LogInformation per la registrazione al livello Information. Il livello del log indica la gravità dell'evento registrato.
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("About page visited at {DT}", 
            DateTime.UtcNow.ToLongTimeString());
    }
}

Livelli e categorie vengono illustrati in modo dettagliato più avanti in questo documento.

Per informazioni su Blazor, vedere Registrazione ASP.NET CoreBlazor.

Configurare la registrazione

La configurazione della registrazione viene in genere fornita dalla sezione Logging dei file appsettings.{ENVIRONMENT}.json, in cui il segnaposto {ENVIRONMENT} è l'ambiente. Il file appsettings.Development.json seguente viene generato dai modelli di app Web ASP.NET Core:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

Nel codice JSON precedente:

  • Vengono specificate le categorie "Default" e "Microsoft.AspNetCore".
  • La categoria "Microsoft.AspNetCore" si applica a tutte le categorie che iniziano con "Microsoft.AspNetCore". Ad esempio, questa impostazione si applica alla categoria "Microsoft.AspNetCore.Routing.EndpointMiddleware".
  • La categoria "Microsoft.AspNetCore" registra al livello di log Warning e superiore.
  • Non viene specificato un provider di log specifico, quindi LogLevel si applica a tutti i provider di registrazione abilitati, ad eccezione del Registro eventi di Windows.

La proprietà Logging può avere le proprietà LogLevel e quelle del provider di log. LogLevel specifica il livello minimo per la registrazione per le categorie selezionate. Nel codice JSON precedente vengono specificati i livelli di log Information e Warning. LogLevel indica la gravità del log con valori compresi da 0 a 6:

Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5 e None = 6.

Quando si specifica un LogLevel, la registrazione viene abilitata per i messaggi al livello specificato e superiori. Nel codice JSON precedente la categoria Default viene registrata per Information e livelli superiori. Ad esempio, vengono registrati i messaggi Information, Warning, Error e Critical. Se non viene specificato un LogLevel, viene impostato il livello di log predefinito Information. Per altre informazioni, vedere Livelli di log.

Una proprietà del provider può specificare una proprietà LogLevel. LogLevel per un provider specifica i livelli da registrare per tale provider e sostituisce le impostazioni di log non specifiche del provider. Considerare il file appsettings.json seguente:

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

Le impostazioni in Logging.{PROVIDER NAME}.LogLevel sostituiscono le impostazioni in Logging.LogLevel, dove il segnaposto {PROVIDER NAME} è il nome del provider. Nel codice JSON precedente il livello di log predefinito del provider Debug è impostato su Information:

Logging:Debug:LogLevel:Default:Information

L'impostazione precedente specifica il livello di log Information per ogni categoria Logging:Debug:, ad eccezione di Microsoft.Hosting. Quando viene elencata una categoria specifica, la categoria specifica sostituisce la categoria predefinita. Nel codice JSON precedente, le categorie Logging:Debug:LogLevel"Microsoft.Hosting" e "Default" sostituiscono le impostazioni in Logging:LogLevel.

È possibile specificare il livello minimo di log per:

  • Provider specifici: ad esempio, Logging:EventSource:LogLevel:Default:Information
  • Categorie specifiche: ad esempio, Logging:LogLevel:Microsoft:Warning
  • Tutti i provider e tutte le categorie: Logging:LogLevel:Default:Warning

I log al di sotto del livello minimo non vengono:

  • Passati al provider.
  • Registrati o visualizzati.

Per eliminare tutti i log, specificare LogLevel.None. Il valore di LogLevel.None è 6, che è maggiore di LogLevel.Critical (5).

Se un provider supporta gli ambiti di log, IncludeScopes indica se tali ambiti sono abilitati. Per altre informazioni, vedere Ambiti di log.

Il file appsettings.json seguente contiene tutti i provider abilitati per impostazione predefinita:

{
  "Logging": {
    "LogLevel": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "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"
      }
    }
  }
}

Nell'esempio precedente:

  • Le categorie e i livelli non sono valori suggeriti. L'esempio viene fornito per visualizzare tutti i provider predefiniti.
  • Le impostazioni in Logging.{PROVIDER NAME}.LogLevel sostituiscono le impostazioni in Logging.LogLevel, dove il segnaposto {PROVIDER NAME} è il nome del provider. Ad esempio, il livello in Debug.LogLevel.Default sostituisce il livello in LogLevel.Default.
  • Viene usato ogni alias del provider predefinito. Ogni provider definisce un alias che può essere utilizzato nella configurazione al posto del nome completo di tipo. Gli alias dei provider predefiniti sono:
    • Console
    • Debug
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Registrare in Program.cs

L'esempio seguente chiama Builder.WebApplication.Logger in Program.cs e registra i messaggi informativi:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Logger.LogInformation("Adding Routes");
app.MapGet("/", () => "Hello World!");
app.Logger.LogInformation("Starting the app");
app.Run();

L'esempio seguente chiama AddConsole e Program.cs registra l'endpoint /Test:

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddConsole();

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

L'esempio seguente chiama AddSimpleConsole in Program.cs, disabilita l'output dei colori e registra l'endpoint /Test:

using Microsoft.Extensions.Logging.Console;

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddSimpleConsole(i => i.ColorBehavior = LoggerColorBehavior.Disabled);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

Impostare il livello di log tramite riga di comando, variabili di ambiente e altre configurazioni

Il livello di log può essere impostato da uno qualsiasi dei provider di configurazione.

Il separatore : non funziona con le chiavi gerarchiche delle variabili di ambiente in tutte le piattaforme. __, il doppio carattere di sottolineatura, è:

  • Supportato da tutte le piattaforme. Ad esempio, il separatore : non è supportato da Bash, ma __ è supportato.
  • Sostituito automaticamente da un :

I comandi seguenti:

  • Impostano la chiave di ambiente Logging:LogLevel:Microsoft su un valore Information in Windows.
  • Testare le impostazioni quando si usa un'app creata con i modelli di applicazione Web ASP.NET Core. Il comando dotnet run deve essere eseguito nella directory del progetto dopo aver usato set.
set Logging__LogLevel__Microsoft=Information
dotnet run

L'impostazione di ambiente precedente:

  • Viene impostata solo nei processi avviati dalla finestra di comando in cui è stata impostata.
  • Non verrà letta dai browser avviati con Visual Studio.

Il comando setx seguente imposta anche la chiave e il valore di ambiente in Windows. A differenza di set, le impostazioni setx vengono mantenute. L'opzione /M imposta la variabile nell'ambiente di sistema. Se non viene usata l'opzione /M, viene impostata una variabile di ambiente dell'utente.

setx Logging__LogLevel__Microsoft Information /M

Considerare il file appsettings.json seguente:

"Logging": {
  "Console": {
    "LogLevel": {
      "Microsoft.Hosting.Lifetime": "Trace"
    }
  }
}

Il comando seguente imposta la configurazione precedente nell'ambiente:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Nota

Quando si configurano variabili di ambiente con nomi contenenti . (punti) in macOS e Linux, prendere in considerazione "Esportazione di una variabile con un punto (.) in esso" domanda su Stack Exchange e la risposta accettata corrispondente.

In Servizio app di Azure selezionare Nuova impostazione applicazione nella pagina Impostazioni > Configurazione. Le impostazioni applicazione del Servizio app di Azure sono:

  • Crittografate mentre sono inattive e trasmesse su un canale crittografato.
  • Esposte come variabili di ambiente.

Per altre informazioni, vedere app Azure: Eseguire l'override della configurazione dell'app usando il portale di Azure.

Per altre informazioni sull'impostazione dei valori di configurazione di ASP.NET Core usando le variabili di ambiente, vedere Variabili di ambiente. Per informazioni sull'uso di altre origini di configurazione, tra cui la riga di comando, Azure Key Vault, Configurazione app di Azure, altri formati di file e altro ancora, vedere Configurazione in ASP.NET Core.

Applicazione delle regole di filtro

Quando viene creato un oggetto ILogger<TCategoryName>, l'oggetto ILoggerFactory seleziona una singola regola per ogni provider da applicare al logger. Tutti i messaggi scritti da un'istanza di ILogger vengono filtrati in base alle regole selezionate. Tra le regole disponibili viene selezionata la regola più specifica per ogni coppia di categoria e provider.

L'algoritmo seguente viene usato per ogni provider quando viene creato un ILogger per una determinata categoria:

  • Selezionare tutte le regole corrispondenti al provider o al relativo alias. Se non viene trovata alcuna corrispondenza, selezionare tutte le regole con un provider vuoto.
  • Dal risultato del passaggio precedente, selezionare le regole con il prefisso di categoria corrispondente più lungo. Se non viene trovata alcuna corrispondenza, selezionare tutte le regole che non specificano una categoria.
  • Se sono selezionate più regole, scegliere l'ultima.
  • Se non è selezionata alcuna regola, usare MinimumLevel.

Registrazione dell'output da dotnet run e da Visual Studio

I log creati con i provider di registrazione predefiniti vengono visualizzati:

  • In Visual Studio
    • Nella finestra di output Debug durante il debug.
    • Nella finestra Server Web ASP.NET Core.
  • Nella finestra della console quando l'app viene eseguita con dotnet run.

I log che iniziano con le categorie "Microsoft" provengono dal codice del framework ASP.NET Core. ASP.NET Core e il codice dell'applicazione usano la stessa API di registrazione e gli stessi provider.

Categoria di log

Quando viene creato un oggetto ILogger, viene specificata una categoria. La categoria è inclusa in ogni messaggio di log creato da tale istanza di ILogger. La stringa di categoria è arbitraria, ma la convenzione consiste nell'usare il nome completo della classe. Ad esempio, in un controller il nome potrebbe essere "TodoApi.Controllers.TodoController". Le app Web ASP.NET Core usano ILogger<T> per ottenere automaticamente un'istanza ILogger che usa il nome completo del tipo di T come categoria:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

Se si vuole categorizzare ulteriormente, la convenzione consiste nell'usare un nome gerarchico aggiungendo una sottocategoria al nome completo della classe e specificando in modo esplicito la categoria usando ILoggerFactory.CreateLogger:

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("TodoApi.Pages.ContactModel.MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

La chiamata CreateLogger con un nome fisso può essere utile quando viene usata in più metodi in modo che gli eventi possano essere organizzati in base alla categoria.

L'uso di ILogger<T> equivale a chiamare CreateLogger con il nome completo di tipo T.

Livello log

Nella tabella seguente sono elencati i valori LogLevel, il metodo di estensione Log{LogLevel} pratico e l'utilizzo suggerito:

LogLevel Valore metodo Descrizione
Trace 0 LogTrace Log che contengono i messaggi più dettagliati. Questi messaggi possono contenere dati sensibili dell'app. Questi messaggi sono disabilitati per impostazione predefinita e non devono essere abilitati in produzione.
Debug 1 LogDebug Per il debug e lo sviluppo. Usare con cautela in produzione a causa del volume elevato.
Information 2 LogInformation Tenere traccia del flusso generale dell'app. Può avere valore a lungo termine.
Warning 3 LogWarning Per gli eventi imprevisti o anomali. In genere include errori o condizioni che non causano l'esito negativo dell'app.
Error 4 LogError Per errori ed eccezioni che non possono essere gestiti. Questi messaggi indicano un errore nell'operazione o nella richiesta corrente, non un errore a livello di app.
Critical 5 LogCritical Per gli errori che richiedono attenzione immediata. Esempi: scenari di perdita di dati, spazio su disco insufficiente.
None 6 Specifica che una categoria di registrazione non deve scrivere messaggi.

Nella tabella precedente, LogLevel è elencato in ordine crescente di gravità.

Il primo parametro del metodo Log, LogLevel, indica la gravità del log. Anziché chiamare Log(LogLevel, ...), la maggior parte degli sviluppatori chiama i metodi di estensione Log{LOG LEVEL}, dove il segnaposto {LOG LEVEL} è il livello di log. Ad esempio, le due chiamate di registrazione seguenti sono equivalenti a livello funzionale e producono lo stesso log:

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem è l'ID dell'evento. MyLogEvents fa parte dell'app di esempio e viene visualizzato nella sezione ID evento di registrazione.

MyDisplayRouteInfo e ToCtxString vengono forniti dal pacchetto NuGet Rick.Docs.Samples.RouteInfo. I metodi visualizzano informazioni di route per Controller e Razor Page.

Il codice seguente crea i log Information e Warning:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Nel codice precedente il primo parametro Log{LOG LEVEL}, MyLogEvents.GetItem, è l'ID dell'evento di registrazione. Il secondo parametro è un modello di messaggio con segnaposto per i valori degli argomenti forniti dai parametri dei metodi rimanenti. I parametri dei metodi sono descritti nella sezione relativa al modello di messaggio più avanti in questo documento.

Chiamare il metodo Log{LOG LEVEL} appropriato per controllare la quantità di output di log scritta in un supporto di archiviazione specifico. Ad esempio:

  • In produzione:
    • La registrazione a Tracelivello di , Debugo Information produce un volume elevato di messaggi di log dettagliati. Per controllare i costi e non superare i limiti di archiviazione dei dati, registrare TraceDebug, o Information i messaggi a livello in un archivio dati a basso costo elevato. Prendere in considerazione la limitazione Tracedi , Debugo Information a categorie specifiche.
    • La registrazione ai livelli da Warning a Critical dovrebbe produrre pochi messaggi di log.
      • I costi e i limiti di archiviazione in genere non sono un problema.
      • Pochi log consentono una maggiore flessibilità nelle scelte dell'archivio dati.
  • In fase di sviluppo:
    • Impostare su Warning.
    • Aggiungere Tracemessaggi , Debugo Information durante la risoluzione dei problemi. Per limitare l'output, impostare Trace, Debugo Information solo per le categorie sottoposte a indagine.

ASP.NET Core scrive log per gli eventi del framework. Si consideri ad esempio l'output del log per:

  • Un'app Razor Pages creata con i modelli di ASP.NET Core.
  • Registrazione impostata su Logging:Console:LogLevel:Microsoft:Information.
  • Spostamento alla pagina Privacy:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

Il codice JSON seguente imposta Logging:Console:LogLevel:Microsoft:Information:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

ID evento di registrazione

Ogni log può specificare un ID evento. L'app di esempio usa la classe MyLogEvents per definire gli ID evento:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Un ID evento associa un set di eventi. Ad esempio, tutti i log correlati alla visualizzazione di un elenco di elementi in una pagina potrebbero essere indicati con 1001.

Il provider di log può archiviare l'ID evento in un campo ID o nel messaggio di registrazione oppure non archiviarlo. Il provider Debug non visualizza gli ID evento. Il provider Console visualizza gli ID evento tra parentesi quadre dopo la categoria:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

Alcuni provider di registrazione archiviano l'ID evento in un campo, che consente di filtrare le informazioni in base all'ID.

Modello di messaggio di registrazione

Ogni API di log specifica un modello di messaggio. Il modello di messaggio può contenere segnaposto per i quali vengono forniti argomenti. Usare nomi per i segnaposto, non numeri.

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

L'ordine dei parametri, non i relativi nomi segnaposto, determina quali parametri vengono usati per fornire valori segnaposto nei messaggi di log. Nel codice seguente, i nomi dei parametri non sono in sequenza nei segnaposto del modello di messaggio:

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {Pears}, {Bananas}, {Apples}", apples, pears, bananas);

Tuttavia, i parametri vengono assegnati ai segnaposto nell'ordine: apples, pears, bananas. Il messaggio di log riflette l'ordine dei parametri:

Parameters: 1, 2, 3

Questo approccio consente ai provider di registrazione di implementare la registrazione semantica o strutturata. Al sistema di registrazione vengono passati gli argomenti e non solo il modello di messaggio formattato. Ciò consente ai provider di registrazione di archiviare i valori dei parametri come campi. Si consideri ad esempio il metodo logger seguente:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

Ad esempio, quando si esegue la registrazione in Archiviazione tabelle di Azure:

  • Ogni entità Tabella di Azure può avere le proprietà ID e RequestTime.
  • Le tabelle con proprietà semplificano le query sui dati registrati. Ad esempio una query può trovare tutti i log entro un determinato intervallo RequestTime senza che sia necessario analizzare il tempo fuori dal messaggio di testo.

Registrare le eccezioni

I metodi logger hanno overload che accettano un parametro di eccezione:

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

MyDisplayRouteInfo e ToCtxString vengono forniti dal pacchetto NuGet Rick.Docs.Samples.RouteInfo. I metodi visualizzano informazioni di route per Controller e Razor Page.

La registrazione delle eccezioni è specifica del provider.

Livello di log predefinito

Se il livello di log predefinito non è impostato, il valore predefinito del livello di log è Information.

Si consideri ad esempio l'app Web seguente:

  • Creata con i modelli di app Web ASP.NET.
  • appsettings.json e appsettings.Development.json eliminati o rinominati.

Con la configurazione precedente, il passaggio alla pagina della privacy o alla home page produce molti messaggi Trace, Debug e Information con Microsoft nel nome della categoria.

Il codice seguente imposta il livello di log predefinito quando non è impostato nella configurazione:

var builder = WebApplication.CreateBuilder();
builder.Logging.SetMinimumLevel(LogLevel.Warning);

In genere, i livelli di log devono essere specificati nella configurazione e non nel codice.

Funzione di filtro

Una funzione di filtro viene richiamata per tutti i provider e le categorie a cui non sono assegnate regole tramite la configurazione o il codice:

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter((provider, category, logLevel) =>
{
    if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Controller")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Microsoft")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else
    {
        return false;
    }
});

Il codice precedente visualizza i log della console quando la categoria contiene Controller o Microsoft e il livello di log è Information o superiore.

In genere, i livelli di log devono essere specificati nella configurazione e non nel codice.

ASP.NET Core e EF Core categorie

La tabella seguente contiene alcune categorie usate da ASP.NET Core ed Entity Framework Core, con note sui log:

Categoria Note
Microsoft.AspNetCore Diagnostica generale di ASP.NET Core.
Microsoft.AspNetCore.DataProtection Chiavi considerate, trovate e usate.
Microsoft.AspNetCore.HostFiltering Host consentiti.
Microsoft.AspNetCore.Hosting Tempo impiegato per il completamento delle richieste HTTP e ora di inizio delle richieste. Assembly di avvio dell'hosting caricati.
Microsoft.AspNetCore.Mvc Diagnostica MVC e Razor. Associazione di modelli, esecuzione di filtri, compilazione di viste, selezione di azioni.
Microsoft.AspNetCore.Routing Informazioni sulla corrispondenza di route.
Microsoft.AspNetCore.Server Risposte di avvio, arresto e keep-alive per la connessione. Informazioni sui certificati HTTPS.
Microsoft.AspNetCore.StaticFiles File forniti.
Microsoft.EntityFrameworkCore Diagnostica generale di Entity Framework Core. Attività e configurazione del database, rilevamento delle modifiche, migrazioni.

Per visualizzare altre categorie nella finestra della console, impostare appsettings.Development.json come segue:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Ambiti dei log

Un ambito può raggruppare un set di operazioni logiche. Questo raggruppamento può essere usato per collegare gli stessi dati a ogni log creato come parte di un set. Ad esempio, ogni log creato come parte dell'elaborazione di una transazione può includere l'ID transazione.

Un ambito:

I provider seguenti supportano gli ambiti:

Un ambito si usa mediante il wrapping delle chiamate del logger in un blocco using:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

Provider di registrazione predefiniti

ASP.NET Core include i provider di registrazione seguenti come parte del framework condiviso:

I provider di registrazione seguenti vengono forniti da Microsoft, ma non come parte del framework condiviso. Devono essere installati come nuget aggiuntivi.

ASP.NET Core non include un provider di registrazione per la scrittura dei log nei file. Per scrivere log nei file da un'app ASP.NET Core, prendere in considerazione l'uso di un provider di registrazione di terze parti.

Per informazioni su stdout e sulla registrazione di debug con il modulo di ASP.NET Core, vedere Risolvere i problemi di ASP.NET Core in Servizio app di Azure e IIS e Modulo ASP.NET Core (ANCM) per IIS.

Console

Il provider Console registra l'output nella console. Per altre informazioni sulla visualizzazione dei log Console in fase di sviluppo, vedere Registrazione dell'output da dotnet run e Visual Studio.

Debug

Il provider Debug scrive l'output del log usando la classe System.Diagnostics.Debug. Le chiamate di System.Diagnostics.Debug.WriteLine scrivono nel provider Debug.

In Linux la posizione del log del provider Debug dipende dalla distribuzione e può essere una delle seguenti:

  • /var/log/message
  • /var/log/syslog

Origine evento

Il provider EventSource scrive in un'origine evento multipiattaforma con il nome Microsoft-Extensions-Logging. In Windows il provider usa ETW.

Strumenti dotnet-trace

Lo strumento dotnet-trace è uno strumento globale dell'interfaccia della riga di comando multipiattaforma che consente la raccolta di tracce di .NET Core di un processo in esecuzione. Lo strumento raccoglie i dati del provider Microsoft.Extensions.Logging.EventSource usando un LoggingEventSource.

Per istruzioni di installazione, vedere dotnet-trace.

Usare lo strumento dotnet-trace per raccogliere una traccia da un'app:

  1. Eseguire l'app con il comando dotnet run.

  2. Determinare l'identificatore di processo (PID) dell'app .NET Core:

    dotnet-trace ps
    

    Trovare il PID per il processo con lo stesso nome dell'assembly dell'app.

  3. Eseguire il comando dotnet-trace.

    Sintassi generale del comando:

    dotnet-trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    Quando si usa una shell dei comandi di PowerShell, racchiudere il valore --providers tra virgolette singole ('):

    dotnet-trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    Nelle piattaforme non Windows aggiungere l'opzione -f speedscope per modificare il formato del file di traccia di output in speedscope.

    La tabella seguente definisce il parametro Keyword:

    Parola chiave Descrizione
    1 Registra meta eventi per LoggingEventSource. Non registra eventi da ILogger.
    2 Attiva l'evento Message in seguito alla chiamata di ILogger.Log(). Fornisce le informazioni in modo programmatico (senza formattazione).
    4 Attiva l'evento FormatMessage in seguito alla chiamata di ILogger.Log(). Fornisce la versione in formato stringa formattata delle informazioni.
    8 Attiva l'evento MessageJson in seguito alla chiamata di ILogger.Log(). Fornisce una rappresentazione JSON degli argomenti.

    Nella tabella seguente vengono elencati i livelli di provider:

    Livello provider Descrizione
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    L'analisi per un livello di categoria può essere una stringa o un numero:

    Valore denominato categoria Valore numerico
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    Livello di provider e livello di categoria:

    • Sono in ordine inverso.
    • Le costanti stringa non sono tutte identiche.

    Se non viene specificato alcun valore FilterSpecs, l'implementazione EventSourceLogger tenta di convertire il livello del provider in un livello di categoria e lo applica a tutte le categorie.

    Livello provider Livello categoria
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Se si specifica FilterSpecs, tutte le altre categorie incluse nell'elenco usano il livello di categoria codificato e tutte le altre categorie vengono escluse.

    Negli esempi seguenti si presuppone che:

    • Sia in esecuzione un'app che chiama logger.LogDebug("12345").
    • L'ID processo (PID) sia stato impostato tramite set PID=12345, dove 12345 è il PID effettivo.

    Si consideri il comando seguente:

    dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    Il comando precedente:

    • Acquisisce i messaggi di debug.
    • Non applica FilterSpecs.
    • Specifica il livello 5 che corrisponde alla categoria Debug.

    Si consideri il comando seguente:

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    Il comando precedente:

    • Non acquisisce i messaggi di debug perché il livello di categoria 5 è Critical.
    • Specifica FilterSpecs.

    Il comando seguente acquisisce i messaggi di debug perché il livello di categoria 1 specifica Debug.

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    Il comando seguente acquisisce i messaggi di debug perché la categoria specifica Debug.

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    Le voci FilterSpecs per {Logger Category} e {Category Level} rappresentano condizioni di filtro dei log aggiuntive. Separare le voci FilterSpecs con il carattere punto e virgola ;.

    Esempio di uso di una shell dei comandi di Windows:

    dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    Il comando precedente attiva:

    • Il logger origine evento per produrre stringhe formattate (4) per gli errori (2).
    • La registrazione Microsoft.AspNetCore.Hosting al livello di registrazione Informational (4).
  4. Arrestare gli dotnet-trace strumenti premendo INVIO o CTRL+C.

    La traccia viene salvata con il nome trace.nettrace nella cartella in cui viene eseguito il comando dotnet-trace.

  5. Aprire la traccia con Perfview. Aprire il file trace.nettrace ed esplorare gli eventi di traccia.

Se l'app non compila l'host con WebApplication.CreateBuilder, aggiungere il provider origine evento alla configurazione di registrazione dell'app.

Per altre informazioni, vedi:

Perfview

Usare l'utilità PerfView per raccogliere e visualizzare i log. Sono disponibili altri strumenti per la visualizzazione dei log ETW, ma PerfView fornisce un'esperienza ottimale per l'uso con gli eventi ETW generati da ASP.NET Core.

Per configurare PerfView per la raccolta degli eventi registrati da questo provider, aggiungere la stringa *Microsoft-Extensions-Logging nell'elenco Provider aggiuntivi Non dimenticare * all'inizio della stringa.

Registro eventi di Windows

Il provider EventLog invia l'output di log al Registro eventi di Windows. A differenza degli altri provider, il provider EventLognon eredita le impostazioni predefinite non specifiche del provider. Se non si specificano le impostazioni di log EventLog, l'impostazione predefinita è LogLevel.Warning.

Per registrare eventi di livello inferiore a LogLevel.Warning, impostare in modo esplicito il livello di log. L'esempio seguente imposta il livello di log predefinito del registro eventi su LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

Gli overload AddEventLog possono passare EventLogSettings. Se null o non specificato, vengono usate le impostazioni predefinite seguenti:

  • LogName: "Application"
  • SourceName: ".NET Runtime"
  • MachineName: viene usato il nome del computer locale.

Il codice seguente modifica SourceName dal valore predefinito ".NET Runtime" a MyLogs:


var builder = WebApplication.CreateBuilder();
builder.Logging.AddEventLog(eventLogSettings =>
{
    eventLogSettings.SourceName = "MyLogs";
});

Servizio app di Azure

Il pacchetto di provider Microsoft.Extensions.Logging.AzureAppServices scrive i log in file di testo nel file system di un'app del Servizio app di Azure e nell'archivio BLOB in un account di archiviazione di Azure.

Il pacchetto del provider non è incluso nel framework condiviso. Per usare il provider, aggiungere il relativo pacchetto al progetto.

Per configurare le impostazioni del provider, usare AzureFileLoggerOptions e AzureBlobLoggerOptions, come illustrato nell'esempio seguente:

using Microsoft.Extensions.Logging.AzureAppServices;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddAzureWebAppDiagnostics();
builder.Services.Configure<AzureFileLoggerOptions>(options =>
{
    options.FileName = "azure-diagnostics-";
    options.FileSizeLimit = 50 * 1024;
    options.RetainedFileCountLimit = 5;
});
builder.Services.Configure<AzureBlobLoggerOptions>(options =>
{
    options.BlobName = "log.txt";
});

Se distribuita in Servizio app di Azure, l'app usa le impostazioni nella sezione Log del servizio app della pagina Servizio app del portale di Azure. Quando le impostazioni seguenti vengono aggiornate, le modifiche hanno effetto immediatamente senza richiedere un riavvio o la ridistribuzione dell'app.

  • Registrazione applicazioni (file system)
  • Registrazione applicazione (BLOB)

Il percorso predefinito per i file di log è la cartella D:\\home\\LogFiles\\Application e il nome del file predefinito è diagnostics-yyyymmdd.txt. Il limite predefinito per le dimensioni del file è 10 MB e il numero massimo predefinito di file conservati è 2. Il nome predefinito del BLOB è {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt.

Questo provider registra solo quando viene eseguito il progetto nell'ambiente di Azure.

Flusso di registrazione di Azure

Il flusso di registrazione di Azure supporta la visualizzazione dell'attività di registrazione in tempo reale da:

  • Server applicazioni
  • Server Web
  • Traccia delle richieste non riuscite

Per configurare il flusso di registrazione di Azure:

  • Passare alla pagina Log del servizio app dalla pagina del portale dell'app.
  • Impostare Registrazione applicazioni (file system) su Attiva.
  • Scegliere il livello di registrazione in Livello. Questa impostazione si applica solo al flusso di registrazione di Azure.

Passare alla pagina Flusso di registrazione per visualizzare i log. I messaggi registrati vengono registrati con l'interfaccia ILogger.

Azure Application Insights

Il pacchetto di provider Microsoft.Extensions.Logging.ApplicationInsights scrive i log in Azure Application Insights. Application Insights è un servizio che monitora un'app Web e fornisce gli strumenti per l'esecuzione di query sui dati di telemetria e la loro analisi. Se si usa questo provider, è possibile eseguire query sui log e analizzarli usando gli strumenti di Application Insights.

Il provider di registrazione è incluso come dipendenza di Microsoft.ApplicationInsights.AspNetCore, ovvero il pacchetto che fornisce tutti i dati di telemetria disponibili per ASP.NET Core. Se si usa questo pacchetto, non è necessario installare il pacchetto di provider.

Il pacchetto Microsoft.ApplicationInsights.Web è per ASP.NET 4.x, non ASP.NET Core.

Per ulteriori informazioni, vedi le seguenti risorse:

Provider di registrazione di terze parti

Framework di registrazione di terze parti che usano ASP.NET Core:

Alcuni framework di terze parti possono eseguire la registrazione semantica, nota anche come registrazione strutturata.

L'uso di un framework di terze parti è simile a quello di uno dei provider predefiniti:

  1. Aggiungere un pacchetto NuGet al progetto.
  2. Chiamare un metodo di estensione ILoggerFactory fornito dal framework di registrazione.

Per altre informazioni, vedere la documentazione di ogni provider. I provider di registrazione di terze parti non sono supportati da Microsoft.

Evitare l'uso di metodi logger asincroni

La registrazione deve essere così rapida da non giustificare l'impatto sulle prestazioni del codice asincrono. Se un archivio dati di registrazione è lento, non scrivere direttamente al suo interno. Valutare invece la possibilità di scrivere i messaggi di log prima in un archivio veloce e quindi spostarli nell'archivio lento in un secondo momento. Ad esempio, quando la registrazione viene eseguita in SQL Server, non farlo direttamente in un metodo Log, poiché i metodi Log sono sincroni. Al contrario, aggiungere i messaggi di log in modo sincrono a una coda in memoria e usare un ruolo di lavoro in background per eseguire il pull dei messaggi dalla coda per eseguire le operazioni asincrone di push dei dati in SQL Server. Per altre informazioni, vedere Guidance on how to log to a message queue for slow data stores (dotnet/AspNetCore.Docs #11801) (Linee guida su come eseguire la registrazione in una coda di messaggi per archivi dati lenti).

Modificare i livelli di log in un'app in esecuzione

L'API di registrazione non include uno scenario per modificare i livelli di log mentre un'app è in esecuzione. Tuttavia, alcuni provider di configurazione sono in grado di ricaricare la configurazione, che diventa effettiva immediatamente per la configurazione della registrazione. Ad esempio, il provider di configurazione file ricarica la configurazione della registrazione per impostazione predefinita. Se la configurazione viene modificata nel codice mentre un'app è in esecuzione, l'app può chiamare IConfigurationRoot.Reload per aggiornare la configurazione di registrazione dell'app.

ILogger e ILoggerFactory

Le interfacce e le implementazioni ILogger<TCategoryName> e ILoggerFactory sono incluse in .NET Core SDK. Sono disponibili anche nei pacchetti NuGet seguenti:

Applicare le regole di filtro dei log nel codice

L'approccio preferito per l'impostazione delle regole di filtro dei log prevede l'uso della configurazione.

L'esempio seguente illustra come registrare le regole di filtro nel codice:

using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Logging.Debug;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter("System", LogLevel.Debug);
builder.Logging.AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information);
builder.Logging.AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace);

logging.AddFilter("System", LogLevel.Debug) specifica la categoria System e il livello di log Debug. Il filtro viene applicato a tutti i provider perché non è stato configurato un provider specifico.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) specifica:

  • Il provider di registrazione Debug.
  • Livello di log Information e superiore.
  • Tutte le categorie a partire da "Microsoft".

Ambito di log automatico con SpanId, TraceId, ParentId, Baggage e Tags.

Le librerie di registrazione creano in modo implicito un oggetto ambito con SpanId, TraceId, ParentId,Baggage e Tags. Questo comportamento viene configurato tramite ActivityTrackingOptions.

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddSimpleConsole(options =>
{
    options.IncludeScopes = true;
});

builder.Logging.Configure(options =>
{
    options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                       | ActivityTrackingOptions.TraceId
                                       | ActivityTrackingOptions.ParentId
                                       | ActivityTrackingOptions.Baggage
                                       | ActivityTrackingOptions.Tags;
});
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Se l'intestazione della richiesta HTTP traceparent è impostata, ParentId nell'ambito del log mostra il valore parent-id W3C dall'intestazione traceparent in ingresso e SpanId nell'ambito del log mostra il valore parent-id aggiornato per il passaggio/intervallo in uscita successivo. Per altre informazioni, vedere Mutating the traceparent Field (Modifica del campo traceparent).

Creare un logger personalizzato

Per creare un logger personalizzato, vedere Implementare un provider di registrazione personalizzato in .NET.

Risorse aggiuntive

Di Kirk Larkin, Juergen Gutsch e Rick Anderson

Questo argomento descrive la registrazione in .NET in riferimento alle app ASP.NET Core. Per informazioni dettagliate sulla registrazione in .NET, vedere Registrazione in .NET. Per altre informazioni sulla registrazione nelle app Blazor, vedere Registrazione in ASP.NET Core Blazor.

Visualizzare o scaricare il codice di esempio (procedura per il download).

Provider di registrazione

I provider di registrazione archiviano i log, ad eccezione del provider Console che li visualizza. Ad esempio, il provider Azure Application Insights archivia i log in Azure Application Insights. È possibile abilitare più provider.

I modelli di app Web ASP.NET Core predefiniti:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Il codice precedente mostra la classe Program creata con i modelli di app Web ASP.NET Core. Le sezioni successive forniscono esempi basati sui modelli di app Web ASP.NET Core, che usano l'host generico. Le app console non host vengono illustrate più avanti in questo documento.

Pe sostituire il set predefinito di provider di registrazione aggiunti da Host.CreateDefaultBuilder, chiamare ClearProviders e aggiungere i provider di registrazione necessari. Ad esempio, il seguente codice:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Per altri provider, vedere:

Creare log

Per creare i log, usare un oggetto ILogger<TCategoryName> dall'inserimento delle dipendenze.

L'esempio seguente:

  • Crea un logger, ILogger<AboutModel>, che usa una categoria di log del nome completo del tipo AboutModel. La categoria del log è una stringa associata a ogni log.
  • Chiama LogInformation per la registrazione al livello Information. Il livello del log indica la gravità dell'evento registrato.
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }
    public string Message { get; set; }

    public void OnGet()
    {
        Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
        _logger.LogInformation(Message);
    }
}

Livelli e categorie vengono illustrati in modo dettagliato più avanti in questo documento.

Per informazioni su Blazor, vedere Registrazione ASP.NET CoreBlazor.

Creare log in Main and Startup illustra come creare i log in Main e Startup.

Configurare la registrazione

La configurazione di registrazione viene comunemente fornita dalla sezione Logging dei file appsettings.{Environment}.json. Il file appsettings.Development.json seguente viene generato dai modelli di app Web ASP.NET Core:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Nel codice JSON precedente:

  • Vengono specificate le categorie "Default", "Microsoft" e "Microsoft.Hosting.Lifetime".
  • La categoria "Microsoft" si applica a tutte le categorie che iniziano con "Microsoft". Ad esempio, questa impostazione si applica alla categoria "Microsoft.AspNetCore.Routing.EndpointMiddleware".
  • La categoria "Microsoft" registra al livello di log Warning e superiore.
  • La categoria "Microsoft.Hosting.Lifetime" è più specifica della categoria "Microsoft", quindi la categoria "Microsoft.Hosting.Lifetime" esegue la registrazione al livello di log "Information" e superiori.
  • Non viene specificato un provider di log specifico, quindi LogLevel si applica a tutti i provider di registrazione abilitati, ad eccezione del Registro eventi di Windows.

La proprietà Logging può avere le proprietà LogLevel e quelle del provider di log. LogLevel specifica il livello minimo per la registrazione per le categorie selezionate. Nel codice JSON precedente vengono specificati i livelli di log Information e Warning. LogLevel indica la gravità del log con valori compresi da 0 a 6:

Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5 e None = 6.

Quando si specifica un LogLevel, la registrazione viene abilitata per i messaggi al livello specificato e superiori. Nel codice JSON precedente la categoria Default viene registrata per Information e livelli superiori. Ad esempio, vengono registrati i messaggi Information, Warning, Error e Critical. Se non viene specificato un LogLevel, viene impostato il livello di log predefinito Information. Per altre informazioni, vedere Livelli di log.

Una proprietà del provider può specificare una proprietà LogLevel. LogLevel per un provider specifica i livelli da registrare per tale provider e sostituisce le impostazioni di log non specifiche del provider. Considerare il file appsettings.json seguente:

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

Le impostazioni in Logging.{providername}.LogLevel sostituiscono le impostazioni in Logging.LogLevel. Nel codice JSON precedente il livello di log predefinito del provider Debug è impostato su Information:

Logging:Debug:LogLevel:Default:Information

L'impostazione precedente specifica il livello di log Information per ogni categoria Logging:Debug:, ad eccezione di Microsoft.Hosting. Quando viene elencata una categoria specifica, la categoria specifica sostituisce la categoria predefinita. Nel codice JSON precedente, le categorie Logging:Debug:LogLevel, "Microsoft.Hosting" e "Default" sostituiscono le impostazioni in Logging:LogLevel.

È possibile specificare il livello minimo di log per:

  • Provider specifici: ad esempio, Logging:EventSource:LogLevel:Default:Information
  • Categorie specifiche: ad esempio, Logging:LogLevel:Microsoft:Warning
  • Tutti i provider e tutte le categorie: Logging:LogLevel:Default:Warning

I log al di sotto del livello minimo non vengono:

  • Passati al provider.
  • Registrati o visualizzati.

Per eliminare tutti i log, specificare LogLevel.None. Il valore di LogLevel.None è 6, che è maggiore di LogLevel.Critical (5).

Se un provider supporta gli ambiti di log, IncludeScopes indica se tali ambiti sono abilitati. Per altre informazioni, vedere Ambiti di log

Il file appsettings.json seguente contiene tutti i provider abilitati per impostazione predefinita:

{
  "Logging": {
    "LogLevel": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "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"
      }
    }
  }
}

Nell'esempio precedente:

  • Le categorie e i livelli non sono valori suggeriti. L'esempio viene fornito per visualizzare tutti i provider predefiniti.
  • Le impostazioni in Logging.{providername}.LogLevel sostituiscono le impostazioni in Logging.LogLevel. Ad esempio, il livello in Debug.LogLevel.Default sostituisce il livello in LogLevel.Default.
  • Viene usato ogni alias del provider predefinito. Ogni provider definisce un alias che può essere utilizzato nella configurazione al posto del nome completo di tipo. Gli alias dei provider predefiniti sono:
    • Console
    • Debug
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Impostare il livello di log tramite riga di comando, variabili di ambiente e altre configurazioni

Il livello di log può essere impostato da uno qualsiasi dei provider di configurazione.

Il separatore : non funziona con le chiavi gerarchiche delle variabili di ambiente in tutte le piattaforme. __, il doppio carattere di sottolineatura, è:

  • Supportato da tutte le piattaforme. Ad esempio, il separatore : non è supportato da Bash, ma __ è supportato.
  • Sostituito automaticamente da un :

I comandi seguenti:

  • Impostano la chiave di ambiente Logging:LogLevel:Microsoft su un valore Information in Windows.
  • Testare le impostazioni quando si usa un'app creata con i modelli di applicazione Web ASP.NET Core. Il comando dotnet run deve essere eseguito nella directory del progetto dopo aver usato set.
set Logging__LogLevel__Microsoft=Information
dotnet run

L'impostazione di ambiente precedente:

  • Viene impostata solo nei processi avviati dalla finestra di comando in cui è stata impostata.
  • Non verrà letta dai browser avviati con Visual Studio.

Il comando setx seguente imposta anche la chiave e il valore di ambiente in Windows. A differenza di set, le impostazioni setx vengono mantenute. L'opzione /M imposta la variabile nell'ambiente di sistema. Se non viene usata l'opzione /M, viene impostata una variabile di ambiente dell'utente.

setx Logging__LogLevel__Microsoft Information /M

Considerare il file appsettings.json seguente:

"Logging": {
    "Console": {
      "LogLevel": {
        "Microsoft.Hosting.Lifetime": "Trace"
      }
    }
}

Il comando seguente imposta la configurazione precedente nell'ambiente:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

In Servizio app di Azure selezionare Nuova impostazione applicazione nella pagina Impostazioni > Configurazione. Le impostazioni applicazione del Servizio app di Azure sono:

  • Crittografate mentre sono inattive e trasmesse su un canale crittografato.
  • Esposte come variabili di ambiente.

Per altre informazioni, vedere App di Azure: Eseguire l'override della configurazione delle app usando il portale di Azure.

Per altre informazioni sull'impostazione dei valori di configurazione di ASP.NET Core usando le variabili di ambiente, vedere Variabili di ambiente. Per informazioni sull'uso di altre origini di configurazione, tra cui la riga di comando, Azure Key Vault, Configurazione app di Azure, altri formati di file e altro ancora, vedere Configurazione in ASP.NET Core.

Applicazione delle regole di filtro

Quando viene creato un oggetto ILogger<TCategoryName>, l'oggetto ILoggerFactory seleziona una singola regola per ogni provider da applicare al logger. Tutti i messaggi scritti da un'istanza di ILogger vengono filtrati in base alle regole selezionate. Tra le regole disponibili viene selezionata la regola più specifica per ogni coppia di categoria e provider.

L'algoritmo seguente viene usato per ogni provider quando viene creato un ILogger per una determinata categoria:

  • Selezionare tutte le regole corrispondenti al provider o al relativo alias. Se non viene trovata alcuna corrispondenza, selezionare tutte le regole con un provider vuoto.
  • Dal risultato del passaggio precedente, selezionare le regole con il prefisso di categoria corrispondente più lungo. Se non viene trovata alcuna corrispondenza, selezionare tutte le regole che non specificano una categoria.
  • Se sono selezionate più regole, scegliere l'ultima.
  • Se non è selezionata alcuna regola, usare MinimumLevel.

Registrazione dell'output da dotnet run e da Visual Studio

I log creati con i provider di registrazione predefiniti vengono visualizzati:

  • In Visual Studio
    • Nella finestra di output Debug durante il debug.
    • Nella finestra Server Web ASP.NET Core.
  • Nella finestra della console quando l'app viene eseguita con dotnet run.

I log che iniziano con le categorie "Microsoft" provengono dal codice del framework ASP.NET Core. ASP.NET Core e il codice dell'applicazione usano la stessa API di registrazione e gli stessi provider.

Categoria di log

Quando viene creato un oggetto ILogger, viene specificata una categoria. La categoria è inclusa in ogni messaggio di log creato da tale istanza di ILogger. La stringa di categoria è arbitraria, ma per convenzione viene usato il nome della classe. Ad esempio, in un controller il nome potrebbe essere "TodoApi.Controllers.TodoController". Le app Web ASP.NET Core usano ILogger<T> per ottenere automaticamente un'istanza ILogger che usa il nome completo del tipo di T come categoria:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

Per specificare in modo esplicito la categoria, chiamare ILoggerFactory.CreateLogger:

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("TodoApi.Pages.ContactModel.MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

La chiamata CreateLogger con un nome fisso può essere utile quando viene usata in più metodi in modo che gli eventi possano essere organizzati in base alla categoria.

L'uso di ILogger<T> equivale a chiamare CreateLogger con il nome completo di tipo T.

Livello log

Nella tabella seguente sono elencati i valori LogLevel, il metodo di estensione Log{LogLevel} pratico e l'utilizzo suggerito:

LogLevel Valore metodo Descrizione
Traccia 0 LogTrace Log che contengono i messaggi più dettagliati. Questi messaggi possono contenere dati sensibili dell'app. Questi messaggi sono disabilitati per impostazione predefinita e non devono essere abilitati in produzione.
Debug 1 LogDebug Per il debug e lo sviluppo. Usare con cautela in produzione a causa del volume elevato.
Informazioni 2 LogInformation Tenere traccia del flusso generale dell'app. Può avere valore a lungo termine.
Avvertenza 3 LogWarning Per gli eventi imprevisti o anomali. In genere include errori o condizioni che non causano l'esito negativo dell'app.
Errore 4 LogError Per errori ed eccezioni che non possono essere gestiti. Questi messaggi indicano un errore nell'operazione o nella richiesta corrente, non un errore a livello di app.
Critico 5 LogCritical Per gli errori che richiedono attenzione immediata. Esempi: scenari di perdita di dati, spazio su disco insufficiente.
Nessuno 6 Specifica che una categoria di registrazione non deve scrivere alcun messaggio.

Nella tabella precedente, LogLevel è elencato in ordine crescente di gravità.

Il primo parametro del metodo Log, LogLevel, indica la gravità del log. Anziché chiamare Log(LogLevel, ...), la maggior parte degli sviluppatori chiama i metodi di estensione Log{LogLevel}. I metodi di estensione Log{LogLevel} chiamano il metodo Log e specificano il LogLevel. Ad esempio, le due chiamate di registrazione seguenti sono equivalenti a livello funzionale e producono lo stesso log:

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem è l'ID dell'evento. MyLogEvents fa parte dell'app di esempio e viene visualizzato nella sezione ID evento di registrazione.

MyDisplayRouteInfo e ToCtxString vengono forniti dal pacchetto NuGet Rick.Docs.Samples.RouteInfo. I metodi visualizzano informazioni di route per Controller e Razor Page.

Il codice seguente crea i log Information e Warning:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Nel codice precedente il primo parametro Log{LogLevel}, MyLogEvents.GetItem, è l'ID dell'evento di registrazione. Il secondo parametro è un modello di messaggio con segnaposto per i valori degli argomenti forniti dai parametri dei metodi rimanenti. I parametri dei metodi sono descritti nella sezione relativa al modello di messaggio più avanti in questo documento.

Chiamare il metodo Log{LogLevel} appropriato per controllare la quantità di output di log scritta in un supporto di archiviazione specifico. Ad esempio:

  • In produzione:
    • La registrazione ai livelli Trace o Information produce un volume elevato di messaggi di log dettagliati. Per controllare i costi e non superare i limiti di archiviazione dei dati, registrare i messaggi di livello Trace e Information in un archivio dati a basso costo per volumi elevati. Prendere in considerazione la limitazione di Trace e Information a categorie specifiche.
    • La registrazione ai livelli da Warning a Critical dovrebbe produrre pochi messaggi di log.
      • I costi e i limiti di archiviazione in genere non sono un problema.
      • Pochi log consentono una maggiore flessibilità nelle scelte dell'archivio dati.
  • In fase di sviluppo:
    • Impostare su Warning.
    • Aggiungere messaggi Trace o Information durante la risoluzione dei problemi. Per limitare l'output, impostare Trace o Information solo per le categorie in fase di indagine.

ASP.NET Core scrive log per gli eventi del framework. Si consideri ad esempio l'output del log per:

  • Un'app Razor Pages creata con i modelli di ASP.NET Core.
  • Registrazione impostata su Logging:Console:LogLevel:Microsoft:Information
  • Spostamento alla pagina Privacy:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

Il codice JSON seguente imposta Logging:Console:LogLevel:Microsoft:Information:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

ID evento di registrazione

Ogni log può specificare un ID evento. L'app di esempio usa la classe MyLogEvents per definire gli ID evento:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Un ID evento associa un set di eventi. Ad esempio, tutti i log correlati alla visualizzazione di un elenco di elementi in una pagina potrebbero essere indicati con 1001.

Il provider di log può archiviare l'ID evento in un campo ID o nel messaggio di registrazione oppure non archiviarlo. Il provider Debug non visualizza gli ID evento. Il provider Console visualizza gli ID evento tra parentesi quadre dopo la categoria:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

Alcuni provider di registrazione archiviano l'ID evento in un campo, che consente di filtrare le informazioni in base all'ID.

Modello di messaggio di registrazione

Ogni API di log specifica un modello di messaggio. Il modello di messaggio può contenere segnaposto per i quali vengono forniti argomenti. Usare nomi per i segnaposto, non numeri.

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

L'ordine dei parametri, non i relativi nomi segnaposto, determina quali parametri vengono usati per fornire valori segnaposto nei messaggi di log. Nel codice seguente, i nomi dei parametri non sono in sequenza nei segnaposto del modello di messaggio:

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {pears}, {bananas}, {apples}", apples, pears, bananas);

Tuttavia, i parametri vengono assegnati ai segnaposto nell'ordine: apples, pears, bananas. Il messaggio di log riflette l'ordine dei parametri:

Parameters: 1, 2, 3

Questo approccio consente ai provider di registrazione di implementare la registrazione semantica o strutturata. Al sistema di registrazione vengono passati gli argomenti e non solo il modello di messaggio formattato. Ciò consente ai provider di registrazione di archiviare i valori dei parametri come campi. Si consideri ad esempio il metodo logger seguente:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

Ad esempio, quando si esegue la registrazione in Archiviazione tabelle di Azure:

  • Ogni entità Tabella di Azure può avere le proprietà ID e RequestTime.
  • Le tabelle con proprietà semplificano le query sui dati registrati. Ad esempio una query può trovare tutti i log entro un determinato intervallo RequestTime senza che sia necessario analizzare il tempo fuori dal messaggio di testo.

Registrare le eccezioni

I metodi logger hanno overload che accettano un parametro di eccezione:

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

MyDisplayRouteInfo e ToCtxString vengono forniti dal pacchetto NuGet Rick.Docs.Samples.RouteInfo. I metodi visualizzano informazioni di route per Controller e Razor Page.

La registrazione delle eccezioni è specifica del provider.

Livello di log predefinito

Se il livello di log predefinito non è impostato, il valore predefinito del livello di log è Information.

Si consideri ad esempio l'app Web seguente:

  • Creata con i modelli di app Web ASP.NET.
  • appsettings.json e appsettings.Development.json eliminati o rinominati.

Con la configurazione precedente, il passaggio alla pagina della privacy o alla home page produce molti messaggi Trace, Debug e Information con Microsoft nel nome della categoria.

Il codice seguente imposta il livello di log predefinito quando non è impostato nella configurazione:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

In genere, i livelli di log devono essere specificati nella configurazione e non nel codice.

Funzione di filtro

Una funzione di filtro viene richiamata per tutti i provider e le categorie a cui non sono assegnate regole tramite la configurazione o il codice:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddFilter((provider, category, logLevel) =>
                {
                    if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Controller")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Microsoft")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Il codice precedente visualizza i log della console quando la categoria contiene Controller o Microsoft e il livello di log è Information o superiore.

In genere, i livelli di log devono essere specificati nella configurazione e non nel codice.

ASP.NET Core e EF Core categorie

La tabella seguente contiene alcune categorie usate da ASP.NET Core ed Entity Framework Core, con note sui log:

Categoria Note
Microsoft.AspNetCore Diagnostica generale di ASP.NET Core.
Microsoft.AspNetCore.DataProtection Chiavi considerate, trovate e usate.
Microsoft.AspNetCore.HostFiltering Host consentiti.
Microsoft.AspNetCore.Hosting Tempo impiegato per il completamento delle richieste HTTP e ora di inizio delle richieste. Assembly di avvio dell'hosting caricati.
Microsoft.AspNetCore.Mvc Diagnostica MVC e Razor. Associazione di modelli, esecuzione di filtri, compilazione di viste, selezione di azioni.
Microsoft.AspNetCore.Routing Informazioni sulla corrispondenza di route.
Microsoft.AspNetCore.Server Risposte di avvio, arresto e keep-alive per la connessione. Informazioni sui certificati HTTPS.
Microsoft.AspNetCore.StaticFiles File forniti.
Microsoft.EntityFrameworkCore Diagnostica generale di Entity Framework Core. Attività e configurazione del database, rilevamento delle modifiche, migrazioni.

Per visualizzare altre categorie nella finestra della console, impostare appsettings.Development.json come segue:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Ambiti dei log

Un ambito può raggruppare un set di operazioni logiche. Questo raggruppamento può essere usato per collegare gli stessi dati a ogni log creato come parte di un set. Ad esempio, ogni log creato come parte dell'elaborazione di una transazione può includere l'ID transazione.

Un ambito:

I provider seguenti supportano gli ambiti:

Un ambito si usa mediante il wrapping delle chiamate del logger in un blocco using:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

Provider di registrazione predefiniti

ASP.NET Core include i provider di registrazione seguenti come parte del framework condiviso:

I provider di registrazione seguenti vengono forniti da Microsoft, ma non come parte del framework condiviso. Devono essere installati come nuget aggiuntivi.

ASP.NET Core non include un provider di registrazione per la scrittura dei log nei file. Per scrivere log nei file da un'app ASP.NET Core, prendere in considerazione l'uso di un provider di registrazione di terze parti.

Per informazioni su stdout e sulla registrazione di debug con il modulo di ASP.NET Core, vedere Risolvere i problemi di ASP.NET Core in Servizio app di Azure e IIS e Modulo ASP.NET Core (ANCM) per IIS.

Console

Il provider Console registra l'output nella console. Per altre informazioni sulla visualizzazione dei log Console in fase di sviluppo, vedere Registrazione dell'output da dotnet run e Visual Studio.

Debug

Il provider Debug scrive l'output del log usando la classe System.Diagnostics.Debug. Le chiamate di System.Diagnostics.Debug.WriteLine scrivono nel provider Debug.

In Linux la posizione del log del provider Debug dipende dalla distribuzione e può essere una delle seguenti:

  • /var/log/message
  • /var/log/syslog

Origine evento

Il provider EventSource scrive in un'origine evento multipiattaforma con il nome Microsoft-Extensions-Logging. In Windows il provider usa ETW.

Strumento dotnet trace

Lo strumento dotnet-trace è uno strumento globale dell'interfaccia della riga di comando multipiattaforma che consente la raccolta di tracce di .NET Core di un processo in esecuzione. Lo strumento raccoglie i dati del provider Microsoft.Extensions.Logging.EventSource usando un LoggingEventSource.

Per istruzioni di installazione, vedere dotnet-trace.

Usare lo strumento dotnet trace per raccogliere una traccia da un'app:

  1. Eseguire l'app con il comando dotnet run.

  2. Determinare l'identificatore di processo (PID) dell'app .NET Core:

    dotnet trace ps
    

    Trovare il PID per il processo con lo stesso nome dell'assembly dell'app.

  3. Eseguire il comando dotnet trace.

    Sintassi generale del comando:

    dotnet trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    Quando si usa una shell dei comandi di PowerShell, racchiudere il valore --providers tra virgolette singole ('):

    dotnet trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    Nelle piattaforme non Windows aggiungere l'opzione -f speedscope per modificare il formato del file di traccia di output in speedscope.

    La tabella seguente definisce il parametro Keyword:

    Parola chiave Descrizione
    1 Registra meta eventi per LoggingEventSource. Non registra eventi da ILogger.
    2 Attiva l'evento Message in seguito alla chiamata di ILogger.Log(). Fornisce le informazioni in modo programmatico (senza formattazione).
    4 Attiva l'evento FormatMessage in seguito alla chiamata di ILogger.Log(). Fornisce la versione in formato stringa formattata delle informazioni.
    8 Attiva l'evento MessageJson in seguito alla chiamata di ILogger.Log(). Fornisce una rappresentazione JSON degli argomenti.

    Nella tabella seguente vengono elencati i livelli di provider:

    Livello provider Descrizione
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    L'analisi per un livello di categoria può essere una stringa o un numero:

    Valore denominato categoria Valore numerico
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    Livello di provider e livello di categoria:

    • Sono in ordine inverso.
    • Le costanti stringa non sono tutte identiche.

    Se non viene specificato alcun valore FilterSpecs, l'implementazione EventSourceLogger tenta di convertire il livello del provider in un livello di categoria e lo applica a tutte le categorie.

    Livello provider Livello categoria
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Se si specifica FilterSpecs, tutte le altre categorie incluse nell'elenco usano il livello di categoria codificato e tutte le altre categorie vengono escluse.

    Negli esempi seguenti si presuppone che:

    • Sia in esecuzione un'app che chiama logger.LogDebug("12345").
    • L'ID processo (PID) sia stato impostato tramite set PID=12345, dove 12345 è il PID effettivo.

    Si consideri il comando seguente:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    Il comando precedente:

    • Acquisisce i messaggi di debug.
    • Non applica FilterSpecs.
    • Specifica il livello 5 che corrisponde alla categoria Debug.

    Si consideri il comando seguente:

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    Il comando precedente:

    • Non acquisisce i messaggi di debug perché il livello di categoria 5 è Critical.
    • Specifica FilterSpecs.

    Il comando seguente acquisisce i messaggi di debug perché il livello di categoria 1 specifica Debug.

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    Il comando seguente acquisisce i messaggi di debug perché la categoria specifica Debug.

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    Le voci FilterSpecs per {Logger Category} e {Category Level} rappresentano condizioni di filtro dei log aggiuntive. Separare le voci FilterSpecs con il carattere punto e virgola ;.

    Esempio di uso di una shell dei comandi di Windows:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    Il comando precedente attiva:

    • Il logger origine evento per produrre stringhe formattate (4) per gli errori (2).
    • La registrazione Microsoft.AspNetCore.Hosting al livello di registrazione Informational (4).
  4. Arrestare lo strumento dotnet trace premendo INVIO o CTRL+C.

    La traccia viene salvata con il nome trace.nettrace nella cartella in cui viene eseguito il comando dotnet trace.

  5. Aprire la traccia con Perfview. Aprire il file trace.nettrace ed esplorare gli eventi di traccia.

Se l'app non compila l'host con CreateDefaultBuilder, aggiungere il provider origine evento alla configurazione di registrazione dell'app.

Per altre informazioni, vedi:

Perfview

Usare l'utilità PerfView per raccogliere e visualizzare i log. Sono disponibili altri strumenti per la visualizzazione dei log ETW, ma PerfView fornisce un'esperienza ottimale per l'uso con gli eventi ETW generati da ASP.NET Core.

Per configurare PerfView per la raccolta degli eventi registrati da questo provider, aggiungere la stringa *Microsoft-Extensions-Logging nell'elenco Provider aggiuntivi Non dimenticare * all'inizio della stringa.

Registro eventi di Windows

Il provider EventLog invia l'output di log al Registro eventi di Windows. A differenza degli altri provider, il provider EventLognon eredita le impostazioni predefinite non specifiche del provider. Se non si specificano le impostazioni di log EventLog, l'impostazione predefinita è LogLevel.Warning.

Per registrare eventi di livello inferiore a LogLevel.Warning, impostare in modo esplicito il livello di log. L'esempio seguente imposta il livello di log predefinito del registro eventi su LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

Gli overload AddEventLog possono passare EventLogSettings. Se null o non specificato, vengono usate le impostazioni predefinite seguenti:

  • LogName: "Application"
  • SourceName: ".NET Runtime"
  • MachineName: viene usato il nome del computer locale.

Il codice seguente modifica SourceName dal valore predefinito ".NET Runtime" a MyLogs:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddEventLog(eventLogSettings =>
                {
                    eventLogSettings.SourceName = "MyLogs"; 
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Servizio app di Azure

Il pacchetto di provider Microsoft.Extensions.Logging.AzureAppServices scrive i log in file di testo nel file system di un'app del Servizio app di Azure e nell'archivio di BLOB in un account di archiviazione di Azure.

Il pacchetto del provider non è incluso nel framework condiviso. Per usare il provider, aggiungere il relativo pacchetto al progetto.

Per configurare le impostazioni del provider, usare AzureFileLoggerOptions e AzureBlobLoggerOptions, come illustrato nell'esempio seguente:

public class Scopes
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging => logging.AddAzureWebAppDiagnostics())
                .ConfigureServices(serviceCollection => serviceCollection
                    .Configure<AzureFileLoggerOptions>(options =>
                    {
                        options.FileName = "azure-diagnostics-";
                        options.FileSizeLimit = 50 * 1024;
                        options.RetainedFileCountLimit = 5;
                    })
                    .Configure<AzureBlobLoggerOptions>(options =>
                    {
                        options.BlobName = "log.txt";
                    }))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Se distribuita in Servizio app di Azure, l'app usa le impostazioni nella sezione Log del servizio app della pagina Servizio app del portale di Azure. Quando le impostazioni seguenti vengono aggiornate, le modifiche hanno effetto immediatamente senza richiedere un riavvio o la ridistribuzione dell'app.

  • Registrazione applicazioni (file system)
  • Registrazione applicazione (BLOB)

Il percorso predefinito per i file di log è nella cartella D:\home\LogFiles\Application e il nome di file predefinito è diagnostics-aaaammgg.txt. Il limite predefinito per le dimensioni del file è 10 MB e il numero massimo predefinito di file conservati è 2. Il nome BLOB predefinito è {nome-app}{timestamp}/aaaa/mm/gg/hh/{guid}-applicationLog.txt.

Questo provider registra solo quando viene eseguito il progetto nell'ambiente di Azure.

Flusso di registrazione di Azure

Il flusso di registrazione di Azure supporta la visualizzazione dell'attività di registrazione in tempo reale da:

  • Server applicazioni
  • Server Web
  • Traccia delle richieste non riuscite

Per configurare il flusso di registrazione di Azure:

  • Passare alla pagina Log del servizio app dalla pagina del portale dell'app.
  • Impostare Registrazione applicazioni (file system) su Attiva.
  • Scegliere il livello di registrazione in Livello. Questa impostazione si applica solo al flusso di registrazione di Azure.

Passare alla pagina Flusso di registrazione per visualizzare i log. I messaggi registrati vengono registrati con l'interfaccia ILogger.

Azure Application Insights

Il pacchetto di provider Microsoft.Extensions.Logging.ApplicationInsights scrive log in Azure Application Insights. Application Insights è un servizio che monitora un'app Web e fornisce gli strumenti per l'esecuzione di query sui dati di telemetria e la loro analisi. Se si usa questo provider, è possibile eseguire query sui log e analizzarli usando gli strumenti di Application Insights.

Il provider di registrazione è incluso come dipendenza di Microsoft.ApplicationInsights.AspNetCore, ovvero il pacchetto che fornisce tutti i dati di telemetria disponibili per ASP.NET Core. Se si usa questo pacchetto, non è necessario installare il pacchetto di provider.

Il pacchetto Microsoft.ApplicationInsights.Web è per ASP.NET 4.x e non per ASP.NET Core.

Per ulteriori informazioni, vedi le seguenti risorse:

Provider di registrazione di terze parti

Framework di registrazione di terze parti che usano ASP.NET Core:

Alcuni framework di terze parti possono eseguire la registrazione semantica, nota anche come registrazione strutturata.

L'uso di un framework di terze parti è simile a quello di uno dei provider predefiniti:

  1. Aggiungere un pacchetto NuGet al progetto.
  2. Chiamare un metodo di estensione ILoggerFactory fornito dal framework di registrazione.

Per altre informazioni, vedere la documentazione di ogni provider. I provider di registrazione di terze parti non sono supportati da Microsoft.

App console non host

Per un esempio di come usare l'host generico in un'app console non Web, vedere il file Program.cs dell'app di esempio Background Tasks (Attività in background con servizi ospitati in ASP.NET Core).

Il codice di registrazione per le app senza Host generico è diverso dal modo in cui vengono aggiunti i provider e vengono creati logger.

Provider di registrazione

In un'app console non host chiamare il metodo di estensione Add{provider name} del provider durante la creazione di un oggetto LoggerFactory:

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

Creare log

Per creare i log, usare un oggetto ILogger<TCategoryName>. Usare per LoggerFactory creare un ILogger.

L'esempio seguente crea un logger con LoggingConsoleApp.Program come categoria.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

Nell'esempio seguente il logger viene usato per creare log con il livello Information. Il livello del log indica la gravità dell'evento registrato.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

I livelli e le categorie vengono illustrati in modo dettagliato più avanti in questo articolo.

Log durante la costruzione dell'host

La registrazione durante la costruzione dell'host non è supportata direttamente. Tuttavia, è possibile usare un logger separato. Nell'esempio seguente viene usato un logger Serilog per la registrazione in CreateHostBuilder. AddSerilog usa la configurazione statica specificata in Log.Logger:

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var builtConfig = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddCommandLine(args)
            .Build();

        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .WriteTo.File(builtConfig["Logging:FilePath"])
            .CreateLogger();

        try
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureServices((context, services) =>
                {
                    services.AddRazorPages();
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddConfiguration(builtConfig);
                })
                .ConfigureLogging(logging =>
                {   
                    logging.AddSerilog();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host builder error");

            throw;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

Configurare un servizio che dipende da ILogger

L'inserimento di un logger nel costruttore Startup è possibile nelle versioni precedenti di ASP.NET Core perché viene creato un contenitore di inserimento delle dipendenze separato per l'host Web. Per informazioni sul motivo per cui viene creato un solo contenitore per l'host generico, vedere l'annuncio relativo alle modifiche di rilievo.

Per configurare un servizio che dipende da ILogger<T>, usare l'inserimento del costruttore o fornire un metodo factory. L'approccio con il metodo factory è consigliato solo se non sono disponibili altre opzioni. Si consideri ad esempio un servizio che necessita di un'istanza ILogger<T> fornita dall'inserimento delle dipendenze:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddRazorPages();

    services.AddSingleton<IMyService>((container) =>
    {
        var logger = container.GetRequiredService<ILogger<MyService>>();
        return new MyService() { Logger = logger };
    });
}

Il precedente codice evidenziato è un oggetto Func<T,TResult> che viene eseguito la prima volta che il contenitore di inserimento delle dipendenze deve creare un'istanza di MyService. È possibile accedere a uno dei servizi registrati in questo modo.

Creare log in Main

Il codice seguente esegue la registrazione in Main ottenendo un'istanza ILogger dall'inserimento delle dipendenze dopo la costruzione dell'host:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    var logger = host.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Host created.");

    host.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Creare log nella classe Startup

Il codice seguente scrive i log in Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
                      ILogger<Startup> logger)
{
    if (env.IsDevelopment())
    {
        logger.LogInformation("In Development.");
        app.UseDeveloperExceptionPage();
    }
    else
    {
        logger.LogInformation("Not Development.");
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapRazorPages();
    });
}

La scrittura di log prima del completamento della configurazione del contenitore di inserimento delle dipendenze nel metodo Startup.ConfigureServices non è supportata:

  • L'inserimento del logger nel costruttore Startup non è supportato.
  • L'inserimento del logger nella firma del metodo Startup.ConfigureServices non è supportato

Questa restrizione è dovuta al fatto che la registrazione dipende dall'inserimento delle dipendenze e dalla configurazione, che a sua volta dipende dall'inserimento delle dipendenze. Il contenitore di inserimento delle dipendenze non viene configurato finché il metodo ConfigureServices non è completato.

Per informazioni sulla configurazione di un servizio che dipende da ILogger<T> o sui motivi per cui l'inserimento di un logger dal costruttore in Startup funziona nelle versioni precedenti, vedere Configurare un servizio che dipende da ILogger

Evitare l'uso di metodi logger asincroni

La registrazione deve essere così rapida da non giustificare l'impatto sulle prestazioni del codice asincrono. Se un archivio dati di registrazione è lento, non scrivere direttamente al suo interno. Valutare invece la possibilità di scrivere i messaggi di log prima in un archivio veloce e quindi spostarli nell'archivio lento in un secondo momento. Ad esempio, quando la registrazione viene eseguita in SQL Server, non farlo direttamente in un metodo Log, poiché i metodi Log sono sincroni. Al contrario, aggiungere i messaggi di log in modo sincrono a una coda in memoria e usare un ruolo di lavoro in background per eseguire il pull dei messaggi dalla coda per eseguire le operazioni asincrone di push dei dati in SQL Server. Per altre informazioni, vedere questo problema in GitHub.

Modificare i livelli di log in un'app in esecuzione

L'API di registrazione non include uno scenario per modificare i livelli di log mentre un'app è in esecuzione. Tuttavia, alcuni provider di configurazione sono in grado di ricaricare la configurazione, che diventa effettiva immediatamente per la configurazione della registrazione. Ad esempio, il provider di configurazione file ricarica la configurazione della registrazione per impostazione predefinita. Se la configurazione viene modificata nel codice mentre un'app è in esecuzione, l'app può chiamare IConfigurationRoot.Reload per aggiornare la configurazione di registrazione dell'app.

ILogger e ILoggerFactory

Le interfacce e le implementazioni ILogger<TCategoryName> e ILoggerFactory sono incluse in .NET Core SDK. Sono disponibili anche nei pacchetti NuGet seguenti:

Applicare le regole di filtro dei log nel codice

L'approccio preferito per l'impostazione delle regole di filtro dei log prevede l'uso della configurazione.

L'esempio seguente illustra come registrare le regole di filtro nel codice:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
               logging.AddFilter("System", LogLevel.Debug)
                  .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information)
                  .AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

logging.AddFilter("System", LogLevel.Debug) specifica la categoria System e il livello di log Debug. Il filtro viene applicato a tutti i provider perché non è stato configurato un provider specifico.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) specifica:

  • Il provider di registrazione Debug.
  • Livello di log Information e superiore.
  • Tutte le categorie a partire da "Microsoft".

Registrare automaticamente l'ambito con SpanId, TraceId e ParentId

Le librerie di registrazione creano in modo implicito un oggetto ambito con SpanId, TraceId e ParentId. Questo comportamento viene configurato tramite ActivityTrackingOptions.

  var loggerFactory = LoggerFactory.Create(logging =>
  {
      logging.Configure(options =>
      {
          options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                              | ActivityTrackingOptions.TraceId
                                              | ActivityTrackingOptions.ParentId;
      }).AddSimpleConsole(options =>
      {
          options.IncludeScopes = true;
      });
  });

Se l'intestazione della richiesta HTTP traceparent è impostata, ParentId nell'ambito del log mostra il valore parent-id W3C dall'intestazione traceparent in ingresso e SpanId nell'ambito del log mostra il valore parent-id aggiornato per il passaggio/intervallo in uscita successivo. Per altre informazioni, vedere Mutating the traceparent Field (Modifica del campo traceparent).

Creare un logger personalizzato

Per creare un logger personalizzato, vedere Implementare un provider di registrazione personalizzato in .NET.

Risorse aggiuntive