Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Note
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.
Warning
Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
O log HTTP é um middleware que registra informações sobre solicitações HTTP de entrada e respostas HTTP. O registo HTTP fornece os registos de:
- Informações de solicitação HTTP
- Propriedades comuns
- Headers
- Body
- Informações de resposta HTTP
O registo HTTP pode:
- Registre todas as solicitações e respostas ou somente solicitações e respostas que atendam a determinados critérios.
- Selecione quais partes da solicitação e da resposta serão registradas.
- Permitir que você retire informações confidenciais dos logs.
O log HTTP pode reduzir o desempenho de um aplicativo, especialmente ao registrar os corpos de solicitação e resposta. Considere o impacto no desempenho ao selecionar campos para registro. Teste o impacto das propriedades de logging selecionadas no desempenho.
Warning
O log HTTP pode potencialmente registrar informações de identificação pessoal (PII). Considere o risco e evite registrar informações confidenciais. Para obter mais informações sobre redação, verifique a redação de dados confidenciais
Habilitar o log HTTP
O log HTTP é habilitado chamando AddHttpLogging e UseHttpLogging, conforme mostrado no exemplo a seguir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Hello World!");
app.Run();
O lambda vazio no exemplo anterior de invocação AddHttpLogging adiciona o middleware com a configuração padrão. Por padrão, o log HTTP registra propriedades comuns, como caminho, código de status e cabeçalhos para solicitações e respostas.
Adicione a seguinte linha ao arquivo appsettings.Development.json no nível "LogLevel": { para que os logs HTTP sejam exibidos.
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
Com a configuração padrão, uma solicitação e resposta é registrada como um par de mensagens semelhantes ao exemplo a seguir:
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
Request:
Protocol: HTTP/2
Method: GET
Scheme: https
PathBase:
Path: /
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Host: localhost:52941
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.61
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: [Redacted]
sec-ch-ua: [Redacted]
sec-ch-ua-mobile: [Redacted]
sec-ch-ua-platform: [Redacted]
sec-fetch-site: [Redacted]
sec-fetch-mode: [Redacted]
sec-fetch-user: [Redacted]
sec-fetch-dest: [Redacted]
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
Response:
StatusCode: 200
Content-Type: text/plain; charset=utf-8
Date: Tue, 24 Oct 2023 02:03:53 GMT
Server: Kestrel
Opções de registo HTTP
Para configurar opções globais para o middleware de log HTTP, chame AddHttpLogging em Program.cs, usando o lambda para configurar HttpLoggingOptions.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Note
No exemplo anterior e nos exemplos seguintes, UseHttpLogging é chamado após UseStaticFiles, portanto, o registo HTTP não está habilitado para ficheiros estáticos. Para habilitar o registro HTTP de arquivo estático, ligue UseHttpLogging antes de UseStaticFiles.
LoggingFields
HttpLoggingOptions.LoggingFields é um sinalizador de enum que configura partes específicas da solicitação e da resposta ao log.
LoggingFields define-se por padrão como RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.
RequestHeaders e ResponseHeaders
RequestHeaders e ResponseHeaders são conjuntos de cabeçalhos HTTP que são registrados. Os valores de cabeçalho são registrados apenas para nomes de cabeçalho que estão nessas coleções. O código a seguir adiciona sec-ch-ua ao RequestHeaders, para que o valor do cabeçalho sec-ch-ua seja registado. E adiciona MyResponseHeader ao ResponseHeaders, para que o valor do cabeçalho MyResponseHeader seja registrado. Se essas linhas forem removidas, os valores desses cabeçalhos serão [Redacted].
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
MediaTypeOptions
MediaTypeOptions Fornece configuração para selecionar qual codificação usar para um tipo de mídia específico.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Essa abordagem também pode ser usada para habilitar o registro em log de dados que não são registrados por padrão (por exemplo, dados de formulário, que podem ter um tipo de mídia como application/x-www-form-urlencoded ou multipart/form-data).
MediaTypeOptions Metodologia
RequestBodyLogLimit e ResponseBodyLogLimit
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
CombineLogs
Definir CombineLogs como true configura o middleware para consolidar todos os seus logs ativados para as solicitações e respostas num único log no final. Isso inclui a solicitação, o corpo da solicitação, a resposta, o corpo da resposta e a duração.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
logging.CombineLogs = true;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Configuração específica do endpoint
Para configuração específica de endpoint em aplicativos de API mínimos, um método de WithHttpLogging extensão está disponível. O exemplo a seguir mostra como configurar o registo HTTP para um endpoint.
app.MapGet("/response", () => "Hello World! (logging response)")
.WithHttpLogging(HttpLoggingFields.ResponsePropertiesAndHeaders);
Para configuração específica de ponto de extremidade em aplicativos que usam controladores, o [HttpLogging] atributo está disponível. O atributo também pode ser usado em aplicativos de API mínimos, conforme mostrado no exemplo a seguir:
app.MapGet("/duration", [HttpLogging(loggingFields: HttpLoggingFields.Duration)]
() => "Hello World! (logging duration)");
IHttpLoggingInterceptor
IHttpLoggingInterceptor é a interface para um serviço que pode ser implementado para lidar com callbacks por solicitação e por resposta, a fim de personalizar quais detalhes são registrados. Todas as configurações de log específicas do ponto de extremidade são aplicadas primeiro e, em seguida, podem ser alteradas nestes callbacks. Uma implementação pode:
- Inspecione uma solicitação ou resposta.
- É possível ativar ou desativar qualquer HttpLoggingFields.
- Ajuste a parte do corpo da solicitação ou resposta que é registada.
- Adicione campos personalizados aos logs.
Registe uma implementação de IHttpLoggingInterceptor chamando AddHttpLoggingInterceptor em Program.cs. Se várias IHttpLoggingInterceptor instâncias forem registradas, elas serão executadas na ordem registrada.
O exemplo a seguir mostra como registrar uma IHttpLoggingInterceptor implementação:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.Duration;
});
builder.Services.AddHttpLoggingInterceptor<SampleHttpLoggingInterceptor>();
O exemplo a seguir é uma IHttpLoggingInterceptor implementação que:
- Inspeciona o método de solicitação e desabilita o registro em log de solicitações POST.
- Para pedidos não POST:
- Redacts caminho de solicitação, cabeçalhos de solicitação e cabeçalhos de resposta.
- Adiciona campos personalizados e valores de campo aos logs de solicitação e resposta.
using Microsoft.AspNetCore.HttpLogging;
namespace HttpLoggingSample;
internal sealed class SampleHttpLoggingInterceptor : IHttpLoggingInterceptor
{
public ValueTask OnRequestAsync(HttpLoggingInterceptorContext logContext)
{
if (logContext.HttpContext.Request.Method == "POST")
{
// Don't log anything if the request is a POST.
logContext.LoggingFields = HttpLoggingFields.None;
}
// Don't enrich if we're not going to log any part of the request.
if (!logContext.IsAnyEnabled(HttpLoggingFields.Request))
{
return default;
}
if (logContext.TryDisable(HttpLoggingFields.RequestPath))
{
RedactPath(logContext);
}
if (logContext.TryDisable(HttpLoggingFields.RequestHeaders))
{
RedactRequestHeaders(logContext);
}
EnrichRequest(logContext);
return default;
}
public ValueTask OnResponseAsync(HttpLoggingInterceptorContext logContext)
{
// Don't enrich if we're not going to log any part of the response
if (!logContext.IsAnyEnabled(HttpLoggingFields.Response))
{
return default;
}
if (logContext.TryDisable(HttpLoggingFields.ResponseHeaders))
{
RedactResponseHeaders(logContext);
}
EnrichResponse(logContext);
return default;
}
private void RedactPath(HttpLoggingInterceptorContext logContext)
{
logContext.AddParameter(nameof(logContext.HttpContext.Request.Path), "RedactedPath");
}
private void RedactRequestHeaders(HttpLoggingInterceptorContext logContext)
{
foreach (var header in logContext.HttpContext.Request.Headers)
{
logContext.AddParameter(header.Key, "RedactedHeader");
}
}
private void EnrichRequest(HttpLoggingInterceptorContext logContext)
{
logContext.AddParameter("RequestEnrichment", "Stuff");
}
private void RedactResponseHeaders(HttpLoggingInterceptorContext logContext)
{
foreach (var header in logContext.HttpContext.Response.Headers)
{
logContext.AddParameter(header.Key, "RedactedHeader");
}
}
private void EnrichResponse(HttpLoggingInterceptorContext logContext)
{
logContext.AddParameter("ResponseEnrichment", "Stuff");
}
}
Com esse intercetador, uma solicitação POST não gera nenhum log, mesmo que o log HTTP esteja configurado para registrar HttpLoggingFields.All. Uma solicitação GET gera logs semelhantes ao exemplo a seguir:
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
Request:
Path: RedactedPath
Accept: RedactedHeader
Host: RedactedHeader
User-Agent: RedactedHeader
Accept-Encoding: RedactedHeader
Accept-Language: RedactedHeader
Upgrade-Insecure-Requests: RedactedHeader
sec-ch-ua: RedactedHeader
sec-ch-ua-mobile: RedactedHeader
sec-ch-ua-platform: RedactedHeader
sec-fetch-site: RedactedHeader
sec-fetch-mode: RedactedHeader
sec-fetch-user: RedactedHeader
sec-fetch-dest: RedactedHeader
RequestEnrichment: Stuff
Protocol: HTTP/2
Method: GET
Scheme: https
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
Response:
Content-Type: RedactedHeader
MyResponseHeader: RedactedHeader
ResponseEnrichment: Stuff
StatusCode: 200
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[4]
ResponseBody: Hello World!
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[8]
Duration: 2.2778ms
Ordem de precedência da configuração de log
A lista a seguir mostra a ordem de precedência para a configuração do log:
- Configuração global de HttpLoggingOptions, definida por chamada AddHttpLogging.
- A configuração específica do ponto de extremidade do atributo
[HttpLogging]ou do método de extensão WithHttpLogging substitui a configuração global. -
IHttpLoggingInterceptoré chamado com os resultados e pode modificar ainda mais a configuração por solicitação.
O Log HTTP é um middleware que registra informações sobre solicitações HTTP de entrada e respostas HTTP. O registo HTTP fornece os registos de:
- Informações de solicitação HTTP
- Propriedades comuns
- Headers
- Body
- Informações de resposta HTTP
O log HTTP é valioso em vários cenários para:
- Registre informações sobre solicitações e respostas recebidas.
- Filtre quais partes da solicitação e da resposta são registradas.
- Filtragem dos cabeçalhos a registar.
O Log HTTP pode reduzir o desempenho de um aplicativo, especialmente ao registrar os corpos de solicitação e resposta. Considere o impacto no desempenho ao selecionar campos para registro. Teste o impacto das propriedades de logging selecionadas no desempenho.
Warning
O Registo HTTP pode potencialmente registar informações de identificação pessoal (PII). Considere o risco e evite registrar informações confidenciais.
Habilitando o log HTTP
O Registo HTTP está ativado com UseHttpLoggingo , que adiciona middleware de registo HTTP.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Hello World!");
app.Run();
Por padrão, o Log HTTP registra propriedades comuns, como caminho, código de status e cabeçalhos para solicitações e respostas. Adicione a seguinte linha ao arquivo appsettings.Development.json no nível "LogLevel": { para que os logs HTTP sejam exibidos.
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
A saída é registrada como uma única mensagem em LogLevel.Information.
Opções de registo HTTP
Para configurar o middleware de log HTTP, chame AddHttpLoggingProgram.cs.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Note
No exemplo anterior e nos exemplos seguintes, UseHttpLogging é chamado após UseStaticFiles, portanto, o registo de HTTP não está ativado para ficheiros estáticos. Para habilitar o registro HTTP de arquivo estático, ligue UseHttpLogging antes de UseStaticFiles.
LoggingFields
HttpLoggingOptions.LoggingFields é um sinalizador de enum que configura partes específicas da solicitação e da resposta ao log.
HttpLoggingOptions.LoggingFields define-se por padrão como RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.
RequestHeaders
Headers são um conjunto de cabeçalhos de solicitação HTTP que podem ser registrados. Os valores de cabeçalho são registrados apenas para nomes de cabeçalho que estão nesta coleção. O código a seguir registra o cabeçalho "sec-ch-ua"da solicitação. Se logging.RequestHeaders.Add("sec-ch-ua"); for removido, o valor do cabeçalho "sec-ch-ua" da solicitação será editado. As seguintes linhas de código destacadas chamam HttpLoggingOptions.RequestHeaders e HttpLoggingOptions.ResponseHeaders :
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
MediaTypeOptions
MediaTypeOptions Fornece configuração para selecionar qual codificação usar para um tipo de mídia específico.
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Essa abordagem também pode ser usada para habilitar o registro em log de dados que não são registrados por padrão. Por exemplo, dados de formulário, que podem ter um tipo de mídia como application/x-www-form-urlencoded ou multipart/form-data.
MediaTypeOptions Metodologia
RequestBodyLogLimit e ResponseBodyLogLimit
using Microsoft.AspNetCore.HttpLogging;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.All;
logging.RequestHeaders.Add("sec-ch-ua");
logging.ResponseHeaders.Add("MyResponseHeader");
logging.MediaTypeOptions.AddText("application/javascript");
logging.RequestBodyLogLimit = 4096;
logging.ResponseBodyLogLimit = 4096;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
context.Response.Headers["MyResponseHeader"] =
new string[] { "My Response Header Value" };
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
Redação ou ocultação de dados confidenciais
O registo de log HTTP com redação de informações pode ser ativado chamando AddHttpLoggingRedaction.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.Duration;
});
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op => { });
Para obter mais informações sobre a biblioteca de redação de dados do .NET, consulte Redação de dados no .NET.
Opções de edição de logs
Para configurar opções para registro com redação, chame AddHttpLoggingRedaction em Program.cs usando o lambda para configurar LoggingRedactionOptions.
using Microsoft.Extensions.Compliance.Classification;
namespace HttpLoggingSample
{
public static class MyTaxonomyClassifications
{
public static string Name => "MyTaxonomy";
public static DataClassification Private => new(Name, nameof(Private));
public static DataClassification Public => new(Name, nameof(Public));
public static DataClassification Personal => new(Name, nameof(Personal));
}
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op =>
{
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
{
{ "one", MyTaxonomyClassifications.Personal },
};
// Add the paths that should be filtered, with a leading '/'.
op.ExcludePathStartsWith.Add("/home");
op.IncludeUnmatchedRoutes = true;
});
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Logged!");
app.MapGet("/home", () => "Not logged!");
app.Run();
Com a configuração de edição anterior, a saída é semelhante à seguinte:
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[9]
Request and Response:
server.address: localhost:61361
Path: /
http.request.header.accept:
Protocol: HTTP/2
Method: GET
Scheme: https
http.response.header.content-type:
StatusCode: 200
Duration: 8.4684
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/2 GET https://localhost:61361/ - 200 - text/plain;+charset=utf-8 105.5334ms
Note
O caminho /home da solicitação não é registrado porque está incluído na ExcludePathStartsWith propriedade.
http.request.header.accept e http.response.header.content-type foram editados por Microsoft.Extensions.Compliance.Redaction.ErasingRedactor.
RequestPathLoggingMode
RequestPathLoggingMode Determina como o caminho da solicitação é registrado, se Formatted ou Structured, definido por IncomingPathLoggingMode:
-
Formatted: Registra o caminho da solicitação sem parâmetros. -
Structured: Registra o caminho da solicitação com parâmetros incluídos.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op =>
{
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
{
{ "one", MyTaxonomyClassifications.Personal },
};
// Add the paths that should be filtered, with a leading '/'.
op.ExcludePathStartsWith.Add("/home");
op.IncludeUnmatchedRoutes = true;
});
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Logged!");
app.MapGet("/home", () => "Not logged!");
app.Run();
RequestPathParameterRedactionMode
RequestPathParameterRedactionMode especifica como os parâmetros de rota no caminho da solicitação devem ser editados, se Strict, Loose ou None, definidos por HttpRouteParameterRedactionMode
-
Strict: Os parâmetros de rota de solicitação são considerados confidenciais, exigem anotação explícita com uma classificação de dados e são editados por padrão. -
Loose: Todos os parâmetros são considerados não confidenciais e incluídos as-is por padrão. -
None: Os parâmetros de rota não são editados independentemente da presença de anotações de classificação de dados.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op =>
{
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
{
{ "one", MyTaxonomyClassifications.Personal },
};
// Add the paths that should be filtered, with a leading '/'.
op.ExcludePathStartsWith.Add("/home");
op.IncludeUnmatchedRoutes = true;
});
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Logged!");
app.MapGet("/home", () => "Not logged!");
app.Run();
RequestHeadersDataClasses
RequestHeadersDataClasses Mapeia cabeçalhos de solicitação para sua classificação de dados, o que determina como eles são editados:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op =>
{
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
{
{ "one", MyTaxonomyClassifications.Personal },
};
// Add the paths that should be filtered, with a leading '/'.
op.ExcludePathStartsWith.Add("/home");
op.IncludeUnmatchedRoutes = true;
});
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Logged!");
app.MapGet("/home", () => "Not logged!");
app.Run();
ResponseHeadersDataClasses
ResponseHeadersDataClasses, semelhante a RequestHeadersDataClasses', mas para cabeçalhos de resposta:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op =>
{
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
{
{ "one", MyTaxonomyClassifications.Personal },
};
// Add the paths that should be filtered, with a leading '/'.
op.ExcludePathStartsWith.Add("/home");
op.IncludeUnmatchedRoutes = true;
});
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Logged!");
app.MapGet("/home", () => "Not logged!");
app.Run();
RouteParameterDataClasses
RouteParameterDataClasses Mapeia os parâmetros de rota para sua classificação de dados:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op =>
{
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
{
{ "one", MyTaxonomyClassifications.Personal },
};
// Add the paths that should be filtered, with a leading '/'.
op.ExcludePathStartsWith.Add("/home");
op.IncludeUnmatchedRoutes = true;
});
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Logged!");
app.MapGet("/home", () => "Not logged!");
app.Run();
ExcludePathStartsWith
ExcludePathStartsWith Especifica os caminhos que devem ser totalmente excluídos do registro:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op =>
{
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
{
{ "one", MyTaxonomyClassifications.Personal },
};
// Add the paths that should be filtered, with a leading '/'.
op.ExcludePathStartsWith.Add("/home");
op.IncludeUnmatchedRoutes = true;
});
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Logged!");
app.MapGet("/home", () => "Not logged!");
app.Run();
IncludeUnmatchedRoutes
IncludeUnmatchedRoutes permite relatar rotas incomparáveis. Se definido como true, regista todo o caminho de rotas não identificadas pelo Routing em vez do valor de Unknown para o atributo de caminho:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op =>
{
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
{
{ "one", MyTaxonomyClassifications.Personal },
};
// Add the paths that should be filtered, with a leading '/'.
op.ExcludePathStartsWith.Add("/home");
op.IncludeUnmatchedRoutes = true;
});
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Logged!");
app.MapGet("/home", () => "Not logged!");
app.Run();