Formação
Módulo
Formatar dados alfanuméricos para apresentação em C# - Training
Explore métodos básicos em C# para formatar dados alfanuméricos.
Este browser já não é suportado.
Atualize para o Microsoft Edge para tirar partido das mais recentes funcionalidades, atualizações de segurança e de suporte técnico.
O .NET oferece suporte ao log estruturado de alto desempenho por meio da API para ajudar a monitorar o comportamento do ILogger aplicativo e diagnosticar problemas. Os logs podem ser gravados em destinos diferentes configurando diferentes provedores de log. Os provedores básicos de registro em log são internos e há muitos provedores de terceiros disponíveis também.
Este primeiro exemplo mostra o básico, mas só é adequado para um aplicativo de console trivial. Este aplicativo de console de exemplo depende dos seguintes pacotes NuGet:
Na próxima seção, você verá como melhorar o código considerando escala, desempenho, configuração e padrões típicos de programação.
using Microsoft.Extensions.Logging;
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger("Program");
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
O exemplo anterior:
ILoggerFactory
armazena toda a configuração que determina para onde as mensagens de log são enviadas. Nesse caso, você configura o provedor de log do console para que as mensagens de log sejam gravadas no console.string
que está associada a cada mensagem registrada pelo ILogger
objeto. Ele é usado para agrupar mensagens de log da mesma classe (ou categoria) ao pesquisar ou filtrar logs.Information
nível. O nível de log indica a gravidade do evento registrado e é usado para filtrar mensagens de log menos importantes. A entrada de log também inclui um modelo "Hello World! Logging is {Description}."
de mensagem e um par Description = fun
chave-valor. O nome da chave (ou espaço reservado) vem da palavra dentro das chaves no modelo e o valor vem do argumento de método restante.Este arquivo de projeto para este exemplo inclui dois pacotes NuGet:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
</ItemGroup>
</Project>
Gorjeta
Todo o código-fonte de exemplo de registro está disponível no Navegador de amostras para download. Para obter mais informações, consulte Procurar exemplos de código: fazendo login no .NET.
Há várias alterações que você deve considerar fazer no exemplo anterior ao fazer login em um cenário menos trivial:
Se seu aplicativo estiver usando DI (Injeção de Dependência) ou um host como o ASP. NET's WebApplication ou Host Genérico, então você deve usar ILoggerFactory
e ILogger
objetos de seus respetivos contêineres DI em vez de criá-los diretamente. Para obter mais informações, consulte Integração com DI e hosts.
Registrar a geração de código-fonte em tempo de compilação geralmente é uma alternativa melhor para métodos de ILogger
extensão como LogInformation
. A geração de origem de registro em log oferece melhor desempenho, digitação mais forte e evita espalhar string
constantes por todos os métodos. A contrapartida é que usar essa técnica requer um pouco mais de código.
using Microsoft.Extensions.Logging;
internal partial class Program
{
static void Main(string[] args)
{
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger("Program");
LogStartupMessage(logger, "fun");
}
[LoggerMessage(Level = LogLevel.Information, Message = "Hello World! Logging is {Description}.")]
static partial void LogStartupMessage(ILogger logger, string description);
}
Type
para tornar esta nomenclatura fácil de fazer.using Microsoft.Extensions.Logging;
internal class Program
{
static void Main(string[] args)
{
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger<Program>();
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
}
}
using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs;
using ILoggerFactory factory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(logging =>
{
logging.AddOtlpExporter();
});
});
ILogger logger = factory.CreateLogger("Program");
logger.LogInformation("Hello World! Logging is {Description}.", "fun");
Se seu aplicativo estiver usando DI (Injeção de Dependência) ou um host como o ASP. NET's WebApplication ou Host Genérico, então você deve usar ILoggerFactory
e ILogger
objetos do contêiner DI em vez de criá-los diretamente.
Este exemplo obtém um objeto ILogger em um aplicativo hospedado usando ASP.NET APIs mínimas:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ExampleHandler>();
var app = builder.Build();
var handler = app.Services.GetRequiredService<ExampleHandler>();
app.MapGet("/", handler.HandleRequest);
app.Run();
partial class ExampleHandler(ILogger<ExampleHandler> logger)
{
public string HandleRequest()
{
LogHandleRequest(logger);
return "Hello World";
}
[LoggerMessage(LogLevel.Information, "ExampleHandler.HandleRequest was called")]
public static partial void LogHandleRequest(ILogger logger);
}
O exemplo anterior:
ExampleHandler
e mapeou solicitações da Web de entrada para executar a ExampleHandler.HandleRequest
função.ILogger<ExampleHandler>
. ILogger<TCategoryName> deriva e ILogger indica qual categoria o ILogger
objeto tem. O contêiner DI localiza um ILogger
com a categoria correta e o fornece como o argumento do construtor. Se ainda não ILogger
existir essa categoria, o contêiner DI a criará automaticamente a ILoggerFactory
partir do no provedor de serviços.logger
parâmetro recebido no construtor foi usado para registrar na HandleRequest
função.Os construtores de hosts inicializam a configuração padrão e, em seguida, adicionam um objeto configurado ILoggerFactory
ao contêiner DI do host quando o host é construído. Antes que o host seja criado, você pode ajustar a configuração de log por meio de HostApplicationBuilder.Logging, WebApplicationBuilder.Loggingou APIs semelhantes em outros hosts. Os hosts também aplicam a configuração de log de fontes de configuração padrão como variáveis de appsettings.json e ambiente. Para obter mais informações, consulte Configuração no .NET.
Este exemplo expande o anterior para personalizar o ILoggerFactory
fornecido pelo WebApplicationBuilder
. Ele adiciona OpenTelemetry como um provedor de log transmitindo os logs por OTLP (protocolo OpenTelemetry ):
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddOpenTelemetry(logging => logging.AddOtlpExporter());
builder.Services.AddSingleton<ExampleHandler>();
var app = builder.Build();
Se você estiver usando um contêiner DI sem um host, use AddLogging para configurar e adicionar ILoggerFactory
ao contêiner.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
// Add services to the container including logging
var services = new ServiceCollection();
services.AddLogging(builder => builder.AddConsole());
services.AddSingleton<ExampleService>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
// Get the ExampleService object from the container
ExampleService service = serviceProvider.GetRequiredService<ExampleService>();
// Do some pretend work
service.DoSomeWork(10, 20);
class ExampleService(ILogger<ExampleService> logger)
{
public void DoSomeWork(int x, int y)
{
logger.LogInformation("DoSomeWork was called. x={X}, y={Y}", x, y);
}
}
O exemplo anterior:
ILoggerFactory
configurado para gravar no consoleExampleService
ao contêinerExampleService
contêiner from the DI que também criou automaticamente um ILogger<ExampleService>
para usar como o argumento do construtor.ExampleService.DoSomeWork
que usou o ILogger<ExampleService>
para registrar uma mensagem no console.A configuração de registro em log é definida em código ou por meio de fontes externas, como arquivos de configuração e variáveis de ambiente. O uso da configuração externa é benéfico quando possível, pois pode ser alterado sem reconstruir o aplicativo. No entanto, algumas tarefas, como definir provedores de log, só podem ser configuradas a partir do código.
Para aplicativos que usam um host, a "Logging"
configuração de log geralmente é fornecida pela seção de appsettings.{Environment}
.json arquivos. Para aplicativos que não usam um host, as fontes de configuração externas são configuradas explicitamente ou configuradas em código .
As seguintes configurações de aplicativo. Development.json arquivo é gerado pelos modelos de serviço do .NET Worker:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
No JSON anterior:
"Default"
categorias , "Microsoft"
, e "Microsoft.Hosting.Lifetime"
nível de log são especificadas."Default"
valor é aplicado a todas as categorias que não são especificadas de outra forma, efetivamente tornando todos os valores padrão para todas as categorias "Information"
. Você pode substituir esse comportamento especificando um valor para uma categoria."Microsoft"
categoria aplica-se a todas as categorias que começam com "Microsoft"
."Microsoft"
categoria registra em um nível de log de Warning
e superior."Microsoft.Hosting.Lifetime"
categoria é mais específica do que a "Microsoft"
categoria, portanto, a "Microsoft.Hosting.Lifetime"
categoria registra no nível "Information"
de log e superior.LogLevel
, aplica-se a todos os provedores de log habilitados, exceto para o Log de Eventos do Windows.A Logging
propriedade pode ter LogLevel e registrar propriedades do provedor. O LogLevel
especifica o nível mínimo a ser registrado para categorias selecionadas. No JSON anterior, Information
e Warning
os níveis de log são especificados. LogLevel
indica a gravidade do log e varia de 0 a 6:
Trace
= 0, Debug
= 1, Information
= 2, Warning
= 3, Error
= 4, Critical
= 5 e None
= 6.
Quando a é especificada, o LogLevel
registro em log é habilitado para mensagens no nível especificado e superior. No JSON anterior, a Default
categoria é registrada para Information
e superior. Por exemplo, Information
, Warning
, Error
, e Critical
as mensagens são registradas. Se não LogLevel
for especificado, o registro em log será padronizado para o Information
nível. Para obter mais informações, consulte Níveis de log.
Uma propriedade de provedor pode especificar uma LogLevel
propriedade. LogLevel
Em um provedor especifica os níveis a serem registrados para esse provedor e substitui as configurações de log que não são do provedor. Considere o seguinte arquivo appsettings.json :
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Warning"
},
"Debug": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting": "Trace"
}
},
"EventSource": {
"LogLevel": {
"Default": "Warning"
}
}
}
}
Configurações em Logging.{ProviderName}.LogLevel
substituir configurações em Logging.LogLevel
. No JSON anterior, o Debug
nível de log padrão do provedor é definido como Information
:
Logging:Debug:LogLevel:Default:Information
A configuração anterior especifica o nível de Information
log para cada Logging:Debug:
categoria, exceto Microsoft.Hosting
. Quando uma categoria específica é listada, a categoria específica substitui a categoria padrão. No JSON anterior, as Logging:Debug:LogLevel
categorias "Microsoft.Hosting"
e "Default"
substituem as configurações em Logging:LogLevel
O nível mínimo de log pode ser especificado para:
Logging:EventSource:LogLevel:Default:Information
Logging:LogLevel:Microsoft:Warning
Logging:LogLevel:Default:Warning
Quaisquer logs abaixo do nível mínimo não são:
Para suprimir todos os logs, especifique LogLevel.None. LogLevel.None
tem um valor de 6, que é superior a LogLevel.Critical
(5).
Se um provedor oferecer suporte a escopos de log, IncludeScopes
indica se eles estão habilitados. Para obter mais informações, consulte Escopos de log
O seguinte ficheiro appsettings.json contém definições para todos os fornecedores incorporados:
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning"
},
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft.Extensions.Hosting": "Warning",
"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"
}
}
}
}
Na amostra anterior:
Logging.{ProviderName}.LogLevel
substituir configurações em Logging.LogLevel
. Por exemplo, o nível em Debug.LogLevel.Default
substitui o nível em LogLevel.Default
.Console
Debug
EventSource
EventLog
AzureAppServicesFile
AzureAppServicesBlob
ApplicationInsights
O nível de log pode ser definido por qualquer um dos provedores de configuração. Por exemplo, você pode criar uma variável de ambiente persistente nomeada Logging:LogLevel:Microsoft
com um valor de Information
.
Crie e atribua variável de ambiente persistente, dado o valor de nível de log.
:: Assigns the env var to the value
setx "Logging__LogLevel__Microsoft" "Information" /M
Em uma nova instância do prompt de comando, leia a variável de ambiente.
:: Prints the env var value
echo %Logging__LogLevel__Microsoft%
A configuração de ambiente anterior é mantida no ambiente. Para testar as configurações ao usar um aplicativo criado com os modelos de serviço do .NET Worker, use o dotnet run
comando no diretório do projeto depois que a variável de ambiente for atribuída.
dotnet run
Gorjeta
Depois de definir uma variável de ambiente, reinicie o ambiente de desenvolvimento integrado (IDE) para garantir que as variáveis de ambiente recém-adicionadas estejam disponíveis.
No Serviço de Aplicativo do Azure, selecione Nova configuração de aplicativo na página Configuração de Definições>. As configurações do aplicativo do Serviço de Aplicativo do Azure são:
Para obter mais informações sobre como definir valores de configuração do .NET usando variáveis de ambiente, consulte variáveis de ambiente.
Para configurar o código de login, use a ILoggingBuilder API. Este pode ser acedido a partir de diferentes locais:
ILoggerFactory
diretamente, configure em LoggerFactory.Create.Este exemplo mostra a configuração do provedor de log do console e vários filtros.
using Microsoft.Extensions.Logging;
using var loggerFactory = LoggerFactory.Create(static builder =>
{
builder
.AddFilter("Microsoft", LogLevel.Warning)
.AddFilter("System", LogLevel.Warning)
.AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
.AddConsole();
});
ILogger logger = loggerFactory.CreateLogger<Program>();
logger.LogDebug("Hello {Target}", "Everyone");
No exemplo AddFilter anterior é usado para ajustar o nível de log habilitado para várias categorias. AddConsole é usado para adicionar o provedor de log do console. Por padrão, os logs com Debug
gravidade não são habilitados, mas como a configuração ajustou os filtros, a mensagem de depuração "Olá a todos" é exibida no console.
Quando um ILogger<TCategoryName> objeto é criado, o objeto seleciona ILoggerFactory uma única regra por provedor para aplicar a esse registrador. Todas as mensagens escritas por uma ILogger
instância são filtradas com base nas regras selecionadas. A regra mais específica para cada par de provedor e categoria é selecionada entre as regras disponíveis.
O algoritmo a seguir é usado para cada provedor quando um ILogger
é criado para uma determinada categoria:
Quando um ILogger
objeto é criado, uma categoria é especificada. Essa categoria é incluída em cada mensagem de log criada por essa instância do ILogger
. A cadeia de caracteres de categoria é arbitrária, mas a convenção é usar o nome de classe totalmente qualificado. Por exemplo, em um aplicativo com um serviço definido como o seguinte objeto, a categoria pode ser "Example.DefaultService"
:
namespace Example
{
public class DefaultService : IService
{
private readonly ILogger<DefaultService> _logger;
public DefaultService(ILogger<DefaultService> logger) =>
_logger = logger;
// ...
}
}
Se desejar uma categorização adicional, a convenção é usar um nome hierárquico anexando uma subcategoria ao nome de classe totalmente qualificado e especificar explicitamente a categoria usando LoggerFactory.CreateLogger:
namespace Example
{
public class DefaultService : IService
{
private readonly ILogger _logger;
public DefaultService(ILoggerFactory loggerFactory) =>
_logger = loggerFactory.CreateLogger("Example.DefaultService.CustomCategory");
// ...
}
}
Chamar CreateLogger
com um nome fixo pode ser útil quando usado em várias classes/tipos para que os eventos possam ser organizados por categoria.
ILogger<T>
é equivalente a ligar CreateLogger
com o nome de tipo totalmente qualificado de T
.
A tabela a seguir lista os LogLevel valores, o método de extensão de conveniência Log{LogLevel}
e o uso sugerido:
Nível de Registo | Value | Método | Description |
---|---|---|---|
Rastreio | 0 | LogTrace | Contêm as mensagens mais detalhadas. Essas mensagens podem conter dados confidenciais do aplicativo. Essas mensagens são desabilitadas por padrão e não devem ser habilitadas na produção. |
Debug | 1 | LogDebug | Para depuração e desenvolvimento. Use com cautela na produção devido ao alto volume. |
Informações | 2 | LogInformation | Rastreia o fluxo geral do aplicativo. Pode ter valor a longo prazo. |
Aviso | 3 | LogWarning | Para eventos anormais ou inesperados. Normalmente, inclui erros ou condições que não fazem com que o aplicativo falhe. |
Erro | 4 | LogError | Para erros e exceções que não podem ser tratados. Essas mensagens indicam uma falha na operação ou solicitação atual, não uma falha em todo o aplicativo. |
Crítico | 5 | LogCritical | Para falhas que exigem atenção imediata. Exemplos: cenários de perda de dados, sem espaço em disco. |
Nenhuma | 6 | Especifica que nenhuma mensagem deve ser gravada. |
Na tabela anterior, o LogLevel
é listado da menor para a maior gravidade.
O primeiro parâmetro do método Log , LogLevel, indica a gravidade do log. Em vez de chamar Log(LogLevel, ...)
, a maioria dos desenvolvedores chama os métodos de extensão Log{LogLevel} . Os Log{LogLevel}
métodos de extensão chamam o Log
método e especificam o LogLevel
. Por exemplo, as duas chamadas de log a seguir são funcionalmente equivalentes e produzem o mesmo log:
public void LogDetails()
{
var logMessage = "Details for log.";
_logger.Log(LogLevel.Information, AppLogEvents.Details, logMessage);
_logger.LogInformation(AppLogEvents.Details, logMessage);
}
AppLogEvents.Details
é a ID do evento e é implicitamente representada por um valor constante Int32 . AppLogEvents
é uma classe que expõe várias constantes de identificador nomeado e é exibida na seção ID do evento Log.
O código a seguir cria Information
e Warning
registra:
public async Task<T> GetAsync<T>(string id)
{
_logger.LogInformation(AppLogEvents.Read, "Reading value for {Id}", id);
var result = await _repository.GetAsync(id);
if (result is null)
{
_logger.LogWarning(AppLogEvents.ReadNotFound, "GetAsync({Id}) not found", id);
}
return result;
}
No código anterior, o primeiro Log{LogLevel}
parâmetro, AppLogEvents.Read
, é a ID do evento Log. O segundo parâmetro é um modelo de mensagem com espaços reservados para valores de argumento fornecidos pelos parâmetros de método restantes. Os parâmetros do método são explicados na seção de modelo de mensagem mais adiante neste artigo.
Configure o nível de log apropriado e chame os métodos corretos Log{LogLevel}
para controlar a quantidade de saída de log gravada em uma mídia de armazenamento específica. Por exemplo:
Trace
níveis ou Debug
produz um grande volume de mensagens de log detalhadas. Para controlar os custos e não exceder os limites de armazenamento de dados, registre Trace
e nivele as mensagens em um armazenamento de dados de alto volume e Debug
baixo custo. Considere limitar Trace
e Debug
a categorias específicas.Warning
níveis de passagem Critical
deve produzir poucas mensagens de log.
Warning
.Trace
ou Debug
mensagens durante a solução de problemas. Para limitar a produção, defina Trace
ou Debug
apenas para as categorias sob investigação.Os seguintes conjuntos Logging:Console:LogLevel:Microsoft:Information
JSON:
{
"Logging": {
"LogLevel": {
"Microsoft": "Warning"
},
"Console": {
"LogLevel": {
"Microsoft": "Information"
}
}
}
}
Cada log pode especificar um identificador de evento, o EventId é uma estrutura com uma Id
e propriedades somente leitura opcionaisName
. O código-fonte de exemplo usa a classe para definir IDs de AppLogEvents
evento:
using Microsoft.Extensions.Logging;
internal static class AppLogEvents
{
internal static EventId Create = new(1000, "Created");
internal static EventId Read = new(1001, "Read");
internal static EventId Update = new(1002, "Updated");
internal static EventId Delete = new(1003, "Deleted");
// These are also valid EventId instances, as there's
// an implicit conversion from int to an EventId
internal const int Details = 3000;
internal const int Error = 3001;
internal static EventId ReadNotFound = 4000;
internal static EventId UpdateNotFound = 4001;
// ...
}
Gorjeta
Para obter mais informações sobre como converter um int
em um EventId
, consulte EventId.Implicit(Int32 to EventId) Operator.
Um ID de evento associa um conjunto de eventos. Por exemplo, todos os logs relacionados à leitura de valores de um repositório podem ser 1001
.
O provedor de log pode registrar a ID do evento em um campo ID, na mensagem de log, ou não registrar. O provedor de depuração não mostra IDs de evento. O provedor de console mostra IDs de evento entre colchetes após a categoria:
info: Example.DefaultService.GetAsync[1001]
Reading value for a1b2c3
warn: Example.DefaultService.GetAsync[4000]
GetAsync(a1b2c3) not found
Alguns provedores de log armazenam a ID do evento em um campo, o que permite a filtragem na ID.
Cada API de log usa um modelo de mensagem. O modelo de mensagem pode conter espaços reservados para os quais os argumentos são fornecidos. Use nomes para os espaços reservados, não números. A ordem dos espaços reservados, não seus nomes, determina quais parâmetros são usados para fornecer seus valores. No código a seguir, os nomes dos parâmetros estão fora de sequência no modelo de mensagem:
string p1 = "param1";
string p2 = "param2";
_logger.LogInformation("Parameter values: {p2}, {p1}", p1, p2);
O código anterior cria uma mensagem de log com os valores de parâmetro em sequência:
Parameter values: param1, param2
Nota
Esteja atento ao usar vários espaços reservados em um único modelo de mensagem, pois eles são baseados em ordinais. Os nomes não são usados para alinhar os argumentos aos espaços reservados.
Essa abordagem permite que os provedores de log implementem log semântico ou estruturado. Os argumentos em si são passados para o sistema de registro, não apenas para o modelo de mensagem formatada. Isso permite que os provedores de log armazenem os valores de parâmetro como campos. Considere o seguinte método de logger:
_logger.LogInformation("Getting item {Id} at {RunTime}", id, DateTime.Now);
Por exemplo, ao fazer logon no Armazenamento de Tabela do Azure:
ID
e RunTime
propriedades.RunTime
sem ter que analisar o tempo limite da mensagem de texto.Os modelos de mensagens de log suportam formatação de espaço reservado. Os modelos são livres para especificar qualquer formato válido para o argumento de tipo determinado. Por exemplo, considere o seguinte Information
modelo de mensagem do registrador:
_logger.LogInformation("Logged on {PlaceHolderName:MMMM dd, yyyy}", DateTimeOffset.UtcNow);
// Logged on January 06, 2022
No exemplo anterior, a DateTimeOffset
instância é o tipo que corresponde ao PlaceHolderName
modelo de mensagem do registrador. Esse nome pode ser qualquer coisa, pois os valores são baseados em ordinais. O MMMM dd, yyyy
formato é válido para o DateTimeOffset
tipo.
Para obter mais informações sobre DateTime
formatação e DateTimeOffset
formatação, consulte Cadeias de caracteres de formato de data e hora personalizadas.
Os exemplos a seguir mostram como formatar um modelo de mensagem usando a sintaxe de {}
espaço reservado. Além disso, um exemplo de escape da sintaxe de espaço reservado {}
é mostrado com sua saída. Finalmente, a interpolação de cadeia de caracteres com espaços reservados para modelos também é mostrada:
logger.LogInformation("Number: {Number}", 1); // Number: 1
logger.LogInformation("{{Number}}: {Number}", 3); // {Number}: 3
logger.LogInformation($"{{{{Number}}}}: {{Number}}", 5); // {Number}: 5
Gorjeta
Os métodos do registrador têm sobrecargas que usam um parâmetro de exceção:
public void Test(string id)
{
try
{
if (id is "none")
{
throw new Exception("Default Id detected.");
}
}
catch (Exception ex)
{
_logger.LogWarning(
AppLogEvents.Error, ex,
"Failed to process iteration: {Id}", id);
}
}
O log de exceções é específico do provedor.
Se o nível de log padrão não estiver definido, o valor padrão do nível de log será Information
.
Por exemplo, considere o seguinte aplicativo de serviço de trabalhador:
Com a configuração anterior, navegar para a privacidade ou página inicial produz muitos Trace
, Debug
e Information
mensagens com Microsoft
o nome da categoria.
O código a seguir define o nível de log padrão quando o nível de log padrão não está definido na configuração:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Warning);
using IHost host = builder.Build();
await host.RunAsync();
Uma função de filtro é invocada para todos os provedores e categorias que não têm regras atribuídas a eles por configuração ou código:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddFilter((provider, category, logLevel) =>
{
return provider.Contains("ConsoleLoggerProvider")
&& (category.Contains("Example") || category.Contains("Microsoft"))
&& logLevel >= LogLevel.Information;
});
using IHost host = builder.Build();
await host.RunAsync();
O código anterior exibe os logs do console quando a categoria contém Example
ou Microsoft
e o nível de log é Information
ou superior.
Um escopo agrupa um conjunto de operações lógicas. Esse agrupamento pode ser usado para anexar os mesmos dados a cada log criado como parte de um conjunto. Por exemplo, cada log criado como parte do processamento de uma transação pode incluir o ID da transação.
Um âmbito:
Os seguintes provedores oferecem suporte a escopos:
Use um escopo encapsulando chamadas de logger em um using
bloco:
public async Task<T> GetAsync<T>(string id)
{
T result;
var transactionId = Guid.NewGuid().ToString();
using (_logger.BeginScope(new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("TransactionId", transactionId),
}))
{
_logger.LogInformation(
AppLogEvents.Read, "Reading value for {Id}", id);
var result = await _repository.GetAsync(id);
if (result is null)
{
_logger.LogWarning(
AppLogEvents.ReadNotFound, "GetAsync({Id}) not found", id);
}
}
return result;
}
O JSON a seguir habilita escopos para o provedor de console:
{
"Logging": {
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft": "Warning",
"Default": "Information"
}
},
"LogLevel": {
"Default": "Debug"
}
}
}
O código a seguir habilita escopos para o provedor de console:
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole(options => options.IncludeScopes = true);
using IHost host = builder.Build();
await host.RunAsync();
O código a seguir efetua login Main
obtendo uma ILogger
instância do DI depois de criar o host:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using IHost host = Host.CreateApplicationBuilder(args).Build();
var logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Host created.");
await host.RunAsync();
O código anterior depende de dois pacotes NuGet:
Seu arquivo de projeto seria semelhante ao seguinte:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
</ItemGroup>
</Project>
O registro em log deve ser tão rápido que não vale a pena o custo de desempenho do código assíncrono. Se um armazenamento de dados de registro estiver lento, não grave diretamente nele. Considere gravar as mensagens de log em um armazenamento rápido inicialmente e, em seguida, movê-las para o armazenamento lento mais tarde. Por exemplo, ao registrar em log no SQL Server, não faça isso diretamente em um Log
método, pois os Log
métodos são síncronos. Em vez disso, adicione mensagens de log de forma síncrona a uma fila na memória e peça a um operador em segundo plano que retire as mensagens da fila para fazer o trabalho assíncrono de enviar dados por push para o SQL Server.
A API de Registro em Log não inclui um cenário para alterar os níveis de log enquanto um aplicativo está em execução. No entanto, alguns provedores de configuração são capazes de recarregar a configuração, o que tem efeito imediato na configuração de log. Por exemplo, o Provedor de Configuração de Arquivo recarrega a configuração de log por padrão. Se a configuração for alterada no código enquanto um aplicativo está em execução, o aplicativo pode chamar IConfigurationRoot.Reload para atualizar a configuração de log do aplicativo.
As ILogger<TCategoryName> interfaces e implementações e ILoggerFactory implementações estão incluídas na maioria dos SDKs .NET como referência de pacote implícita. Eles também estão disponíveis explicitamente nos seguintes pacotes NuGet quando não são implicitamente referenciados:
Para obter mais informações sobre qual SDK do .NET inclui referências implícitas de pacote, consulte .NET SDK: tabela para namespace implícito.
Comentários do .NET
O .NET é um projeto código aberto. Selecione um link para fornecer comentários:
Formação
Módulo
Formatar dados alfanuméricos para apresentação em C# - Training
Explore métodos básicos em C# para formatar dados alfanuméricos.