Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Note
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 10 tohoto článku.
Warning
Tato verze ASP.NET Core již není podporována. Pro více informací se podívejte na Zásady podpory .NET a .NET Core. Aktuální vydání tohoto článku najdete v verzi .NET 9.
Protokolování protokolu HTTP je prostřední vrstva aplikace, která zaznamenává informace o příchozích požadavcích a odpovědích protokolu HTTP. Protokolování HTTP poskytuje záznamy obsahující:
- Informace o požadavku HTTP
- Obecné vlastnosti
- Headers
- Body
- Informace o odpovědi HTTP
Protokolování HTTP může:
- Protokolujte všechny požadavky a odpovědi nebo pouze žádosti a odpovědi, které splňují určitá kritéria.
- Vyberte, které části požadavku a odpovědi se protokolují.
- Umožňuje redigovat citlivé informace z protokolů.
Protokolování HTTP může snížit výkon aplikace, zejména při protokolování těla požadavků a odpovědí. Při výběru polí, která se mají protokolovat, zvažte dopad na výkon. Otestujte dopad na výkon vybraných vlastností protokolování.
Warning
Protokolování HTTP může potenciálně protokolovat identifikovatelné osobní údaje (PII). Zvažte riziko a vyhněte se protokolování citlivých informací. Další informace o redigování najdete v redigování citlivých dat.
Povolte protokolování HTTP
Protokolování HTTP je povoleno voláním AddHttpLogging a UseHttpLogging, jak je znázorněno v následujícím příkladu:
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();
Prázdná lambda v předchozím příkladu volání funkce AddHttpLogging přidá middleware s výchozí konfigurací. Protokolování HTTP ve výchozím nastavení protokoluje běžné vlastnosti, jako je cesta, stavový kód a hlavičky pro požadavky a odpovědi.
Přidejte do appsettings.Development.json souboru následující řádek na "LogLevel": { úrovni, aby se zobrazily protokoly HTTP:
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
Ve výchozí konfiguraci se požadavek a odpověď zaprotokolují jako dvojice zpráv podobných následujícímu příkladu:
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
Možnosti protokolování HTTP
Pokud chcete nakonfigurovat globální možnosti pro Middleware protokolování HTTP, zavolejte AddHttpLogging v Program.cs, pomocí lambda ke konfiguraci 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
V předchozí ukázce a následujících ukázkách se UseHttpLogging volá po UseStaticFiles, takže protokolování HTTP není zapnuté pro statické soubory. Chcete-li povolit protokolování statických souborů HTTP, zavolejte UseHttpLogging před UseStaticFiles.
LoggingFields
HttpLoggingOptions.LoggingFields je příznak výčtu, který konfiguruje konkrétní části požadavku a odpovědi na protokol.
LoggingFields výchozí hodnota RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.
RequestHeaders a ResponseHeaders
RequestHeaders a ResponseHeaders jsou sady hlaviček HTTP, které jsou protokolovány. Hodnoty hlaviček se protokolují jenom pro názvy hlaviček, které jsou v těchto kolekcích. Následující kód přidá sec-ch-ua do RequestHeaders, takže hodnota záhlaví sec-ch-ua je zaznamenána. Přidá MyResponseHeader k ResponseHeaders, takže hodnota hlavičky MyResponseHeader je zaznamenána. Pokud jsou tyto řádky odebrány, hodnoty těchto záhlaví jsou [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 poskytuje konfiguraci pro výběr kódování, které se má použít pro určitý typ média.
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();
Tento přístup lze použít také k povolení protokolování dat, která nejsou ve výchozím nastavení protokolována (například data formuláře, která můžou mít typ média, například application/x-www-form-urlencoded ).multipart/form-data
Metody MediaTypeOptions
RequestBodyLogLimit a 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
Nastavení CombineLogs na true konfiguruje middleware ke konsolidaci všech jeho povolených záznamů pro požadavek a odpověď do jednoho záznamu na konci. To zahrnuje požadavek, text požadavku, odpověď, text odpovědi a dobu trvání.
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();
Konfigurace specifická pro koncový bod
Pro konfiguraci specifickou pro koncový bod v minimálních aplikacích WithHttpLogging API je k dispozici metoda rozšíření. Následující příklad ukazuje, jak nakonfigurovat protokolování HTTP pro jeden koncový bod:
app.MapGet("/response", () => "Hello World! (logging response)")
.WithHttpLogging(HttpLoggingFields.ResponsePropertiesAndHeaders);
Pro konfiguraci specifickou pro koncový bod v aplikacích, které používají kontrolery, [HttpLogging] je atribut k dispozici. Atribut lze použít také v minimálních aplikacích API, jak je znázorněno v následujícím příkladu:
app.MapGet("/duration", [HttpLogging(loggingFields: HttpLoggingFields.Duration)]
() => "Hello World! (logging duration)");
IHttpLoggingInterceptor
IHttpLoggingInterceptor je rozhraní pro službu, která se dá implementovat za účelem zpracování zpětného volání na požadavek a odpověď pro přizpůsobení podrobností, které se zaprotokolují. Nejprve se použijí všechna nastavení protokolu specifická pro koncový bod a pak je možné je v těchto zpětných voláních přepsat. Implementace může:
- Zkontrolujte požadavek nebo odpověď.
- Povolte nebo zakažte libovolný HttpLoggingFields.
- Upravte, kolik textu požadavku nebo odpovědi se protokoluje.
- Přidejte do protokolů vlastní pole.
Zaregistrujte implementaci IHttpLoggingInterceptor voláním AddHttpLoggingInterceptor v Program.cs. Pokud je zaregistrovaných více IHttpLoggingInterceptor instancí, spustí se v pořadí, v jakém byly zaregistrovány.
Následující příklad ukazuje, jak zaregistrovat implementaci IHttpLoggingInterceptor :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.Duration;
});
builder.Services.AddHttpLoggingInterceptor<SampleHttpLoggingInterceptor>();
Následující příklad je IHttpLoggingInterceptor implementace, která:
- Zkontroluje metodu požadavku a zakáže protokolování požadavků POST.
- Pro požadavky kromě POST:
- Rediguje cestu žádosti, hlavičky žádosti a hlavičky odpovědi.
- Přidá do protokolů požadavků a odpovědí vlastní pole a hodnoty polí.
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");
}
}
Při použití tohoto zachytávače požadavek POST nevytváří žádné záznamy, ani když je protokolování HTTP nakonfigurováno k záznamu HttpLoggingFields.All. Požadavek GET generuje protokoly podobné následujícímu příkladu:
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
Pořadí priority konfigurace protokolování
Následující seznam ukazuje pořadí priorit konfigurace protokolování:
- Globální konfigurace z HttpLoggingOptions, nastavená voláním AddHttpLogging.
- Konfigurace specifická pro koncový bod, vycházející z atributu
[HttpLogging]nebo rozšiřující metody WithHttpLogging, přepisují globální konfiguraci. -
IHttpLoggingInterceptorse volá s výsledky a může dále upravit konfiguraci na požadavek.
Protokolování HTTP je middleware, který protokoluje informace o příchozích požadavcích HTTP a odpovědích HTTP. Protokolování HTTP poskytuje záznamy obsahující:
- Informace o požadavku HTTP
- Obecné vlastnosti
- Headers
- Body
- Informace o odpovědi HTTP
Protokolování HTTP je užitečné v několika scénářích:
- Zaznamenává informace o příchozích požadavcích a odpovědích.
- Vyfiltrujte, které části požadavku a odpovědi se protokolují.
- Filtrování hlaviček, které se mají protokolovat.
Protokolování HTTP může snížit výkon aplikace, zejména při protokolování těla požadavků a odpovědí. Při výběru polí, která se mají protokolovat, zvažte dopad na výkon. Otestujte dopad na výkon vybraných vlastností protokolování.
Warning
Protokolování HTTP může zaznamenávat potenciálně osobně identifikovatelné údaje (PII). Zvažte riziko a vyhněte se protokolování citlivých informací.
Povolení protokolování HTTP
Protokolování HTTP je povoleno pomocí UseHttpLogging, které přidává middleware pro protokolování 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();
Protokolování HTTP ve výchozím nastavení protokoluje běžné vlastnosti, jako je cesta, stavový kód a hlavičky pro požadavky a odpovědi. Přidejte do appsettings.Development.json souboru následující řádek na "LogLevel": { úrovni, aby se zobrazily protokoly HTTP:
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
Výstup je protokolován jako jedna zpráva na LogLevel.Informationadrese .
Možnosti protokolování HTTP
Chcete-li nakonfigurovat middleware protokolování HTTP, zavolejte AddHttpLogging v Program.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
V předchozí i následujících ukázkách se UseHttpLogging volá po UseStaticFiles, takže protokolování HTTP není povoleno pro statické soubory. Chcete-li povolit protokolování statických souborů HTTP, zavolejte UseHttpLogging před UseStaticFiles.
LoggingFields
HttpLoggingOptions.LoggingFields je příznak výčtu, který konfiguruje konkrétní části požadavku a odpovědi na protokol.
HttpLoggingOptions.LoggingFields výchozí hodnota RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.
RequestHeaders
Headers jsou sadou hlaviček požadavků HTTP, které mohou být protokolovány. Hodnoty hlaviček jsou protokolovány pouze pro názvy hlaviček, které jsou v této kolekci. Následující kód zaznamená hlavičku "sec-ch-ua"požadavku . Pokud je logging.RequestHeaders.Add("sec-ch-ua"); odebrán, hodnota hlavičky požadavku "sec-ch-ua" je upravena. Zvýrazněný kód volá HttpLoggingOptions.RequestHeaders a 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 poskytuje konfiguraci pro výběr kódování, které se má použít pro určitý typ média.
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();
Tento přístup lze použít také k povolení protokolování dat, která nejsou ve výchozím nastavení protokolována. Například data formuláře, která mohou mít typ média, například application/x-www-form-urlencoded nebo multipart/form-data.
Metody MediaTypeOptions
RequestBodyLogLimit a 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();
Redigování citlivých údajů
Protokolování HTTP s redukcí je možné povolit voláním AddHttpLoggingRedaction:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.Duration;
});
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op => { });
Další informace o knihovně pro redakci dat v .NET najdete v Redakce dat v .NET.
Možnosti úpravy protokolování
Pokud chcete nakonfigurovat možnosti protokolování s využitím redakce, zavolejte AddHttpLoggingRedaction v Program.cs s využitím lambda pro konfiguraci 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();
S předchozí konfigurací redakce je výstup podobný následujícímu:
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
Cesta /home požadavku není zaprotokolována, protože je součástí ExcludePathStartsWith vlastnosti.
http.request.header.accept a http.response.header.content-type byly redigovány Microsoft.Extensions.Compliance.Redaction.ErasingRedactor.
RequestPathLoggingMode
RequestPathLoggingMode určuje, jak je cesta požadavku protokolována, zda Formatted nebo Structured, nastavena pomocí IncomingPathLoggingMode:
-
Formatted: Zaznamená cestu požadavku bez parametrů. -
Structured: Zaznamená cestu požadavku s zahrnutými parametry.
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 určuje, jak mají být parametry trasy v cestě požadavku redigovány, zda Strict, Loose nebo None, nastaveny pomocí HttpRouteParameterRedactionMode:
-
Strict: Parametry trasy požadavku jsou považovány za citlivé, vyžadují explicitní anotace s klasifikací dat a jsou ve výchozím nastavení upraveny. -
Loose: Všechny parametry jsou ve výchozím nastavení považovány za nerozlišivé a zahrnuté as-is. -
None: Parametry trasy nejsou skryty bez ohledu na to, zda jsou přítomny poznámky ke klasifikaci dat.
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 mapuje hlavičky požadavků na jejich klasifikaci dat, která určuje, jak jsou upraveny:
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, podobně jako RequestHeadersDataClasses', ale pro hlavičky odpovědi:
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 mapuje parametry trasování na jejich klasifikaci dat:
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 určuje cesty, které by měly být vyloučeny z protokolování zcela:
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 umožňuje hlásit chybějící trasy. Pokud je nastaveno true, zapisuje celou cestu tras, které nejsou identifikovány užitím Směrování, místo zapisování Unknown hodnoty atributu cesty.
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();