Delen via


HTTP-logboekregistratie in ASP.NET Core

Note

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Warning

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Important

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikelvoor de huidige release.

HTTP-logboekregistratie is een middleware die informatie over binnenkomende HTTP-aanvragen en HTTP-antwoorden registreert. HTTP-logboekregistratie biedt logboeken van:

  • HTTP-aanvraaggegevens
  • Common properties
  • Headers
  • Body
  • HTTP-antwoordinformatie

HTTP-logboekregistratie kan:

  • Registreer alle aanvragen en antwoorden of alleen aanvragen en antwoorden die voldoen aan bepaalde criteria.
  • Selecteer welke onderdelen van de aanvraag en het antwoord worden geregistreerd.
  • Hiermee kunt u gevoelige informatie uit de logboeken redacteren.

HTTP-logboekregistratie kan de prestaties van een app verminderen, met name bij het vastleggen van de aanvraag- en antwoordteksten. Houd rekening met de invloed van de prestaties bij het selecteren van velden die moeten worden vastgelegd. Test de invloed van de geselecteerde logeigenschappen op de prestaties.

Warning

HTTP-logboekregistratie kan mogelijk persoonlijk identificeerbare informatie (PII) registreren. Houd rekening met het risico en vermijd gevoelige informatie in logboekregistratie. Raadpleeg het redacteren van gevoelige gegevens voor meer informatie over redaction

HTTP-logboekregistratie inschakelen

HTTP-logboekregistratie is ingeschakeld door aanroepen AddHttpLogging en UseHttpLogging, zoals wordt weergegeven in het volgende voorbeeld:

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();

De lege lambda in het voorgaande voorbeeld van het aanroepen AddHttpLogging voegt de middleware toe met de standaardconfiguratie. Http-logboekregistratie registreert standaard algemene eigenschappen, zoals pad, statuscode en headers voor aanvragen en antwoorden.

Voeg de volgende regel toe aan het appsettings.Development.json bestand op niveau "LogLevel": { , zodat de HTTP-logboeken worden weergegeven:

"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"

Met de standaardconfiguratie wordt een aanvraag en antwoord geregistreerd als een paar berichten die vergelijkbaar zijn met het volgende voorbeeld:

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

Opties voor HTTP-logboekregistratie

Als u globale opties voor de middleware voor HTTP-logboekregistratie wilt configureren, roep AddHttpLogging aan in Program.cs om HttpLoggingOptions te configureren met de lambda.

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

In het voorgaande voorbeeld en de volgende voorbeelden wordt UseHttpLogging na UseStaticFiles aangeroepen, zodat HTTP-logging niet is ingeschakeld voor statische bestanden. Roep UseHttpLogging aan voordat UseStaticFiles om HTTP-logboekregistratie voor statische bestanden in te schakelen.

LoggingFields

HttpLoggingOptions.LoggingFields is een enum-vlag waarmee specifieke onderdelen van de aanvraag en reactie worden geconfigureerd voor loggen. LoggingFields is standaard ingesteld op RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.

RequestHeaders en ResponseHeaders

RequestHeaders en ResponseHeaders zijn sets HTTP-headers die worden geregistreerd. Headerwaarden worden alleen geregistreerd voor headernamen die zich in deze verzamelingen bevinden. De volgende code voegt sec-ch-ua toe aan de RequestHeaders, waardoor de waarde van de sec-ch-ua header wordt vastgelegd. En dat voegt MyResponseHeader toe aan de ResponseHeaders, zodat de waarde van de header MyResponseHeader wordt vastgelegd. Als deze regels worden verwijderd, zijn de waarden van deze headers [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 biedt configuratie voor het selecteren van welke codering moet worden gebruikt voor een specifiek mediatype.

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();

Deze methode kan ook worden gebruikt om logboekregistratie in te schakelen voor gegevens die niet standaard worden geregistreerd (bijvoorbeeld formuliergegevens, die mogelijk een mediatype hebben zoals application/x-www-form-urlencoded of multipart/form-data).

MediaTypeOptions Methoden

RequestBodyLogLimit en 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

Instellen van CombineLogs op true configureert de middleware om aan het einde al zijn ingeschakelde logboeken voor een verzoek en antwoord in één logboek samen te voegen. Dit omvat de aanvraag, de inhoud van de aanvraag, het antwoord, de inhoud van het antwoord en de duur.

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();

Endpoint-specific configuration

Voor eindpuntspecifieke configuratie in minimale API-apps is er een WithHttpLogging extensiemethode beschikbaar. In het volgende voorbeeld ziet u hoe u HTTP-logboekregistratie voor één eindpunt configureert:

app.MapGet("/response", () => "Hello World! (logging response)")
    .WithHttpLogging(HttpLoggingFields.ResponsePropertiesAndHeaders);

Voor eindpuntspecifieke configuratie in apps die gebruikmaken van controllers, is het [HttpLogging] kenmerk beschikbaar. Het kenmerk kan ook worden gebruikt in minimale API-apps, zoals wordt weergegeven in het volgende voorbeeld:

app.MapGet("/duration", [HttpLogging(loggingFields: HttpLoggingFields.Duration)]
    () => "Hello World! (logging duration)");

IHttpLoggingInterceptor

IHttpLoggingInterceptor is de interface voor een service die kan worden geïmplementeerd om callbacks per aanvraag en per antwoord te verwerken voor het aanpassen van de details die worden geregistreerd. Alle eindpuntspecifieke logboekinstellingen worden eerst toegepast en kunnen vervolgens worden overschreven in deze callbacks. Een implementatie kan:

  • Inspecteer een aanvraag of antwoord.
  • Schakel alle HttpLoggingFieldsin of uit.
  • Pas aan hoeveel van de aanvraag- of antwoordtekst wordt geregistreerd.
  • Voeg aangepaste velden toe aan de logboeken.

Registreer een IHttpLoggingInterceptor-implementatie door AddHttpLoggingInterceptor aan te roepen in Program.cs. Als er meerdere IHttpLoggingInterceptor exemplaren zijn geregistreerd, worden ze uitgevoerd in de geregistreerde order.

In het volgende voorbeeld ziet u hoe u een IHttpLoggingInterceptor implementatie registreert:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.Duration;
});
builder.Services.AddHttpLoggingInterceptor<SampleHttpLoggingInterceptor>();

Het volgende voorbeeld is een IHttpLoggingInterceptor implementatie die:

  • Inspecteert de aanvraagmethode en schakelt logboekregistratie voor POST-aanvragen uit.
  • Voor niet-POST-aanvragen:
    • Aanvraagpad, aanvraagheaders en antwoordheaders opnieuw uitvoeren.
    • Voegt aangepaste velden en veldwaarden toe aan de aanvraag- en antwoordlogboeken.
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");
    }
}

Met deze interceptor genereert een POST-aanvraag geen logs, zelfs niet als de HTTP-logconfiguratie is ingesteld om HttpLoggingFields.All te loggen. Een GET-aanvraag genereert logboeken die vergelijkbaar zijn met het volgende voorbeeld:

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

Volgorde van voorrang van logboekconfiguratie

In de volgende lijst ziet u de volgorde van prioriteit voor de configuratie van logboekregistratie:

  1. Globale configuratie van HttpLoggingOptions, ingesteld door aan te roepen AddHttpLogging.
  2. Eindpuntspecifieke configuratie van het [HttpLogging] kenmerk of de WithHttpLogging extensiemethode overschrijft globale configuratie.
  3. IHttpLoggingInterceptor wordt aangeroepen met de resultaten en kan de configuratie per aanvraag verder wijzigen.

HTTP-logboekregistratie is een middleware die informatie registreert over binnenkomende HTTP-aanvragen en HTTP-antwoorden. HTTP-logboekregistratie biedt logboeken van:

  • HTTP-aanvraaggegevens
  • Common properties
  • Headers
  • Body
  • HTTP-antwoordinformatie

HTTP-logboekregistratie is in verschillende scenario's waardevol voor:

  • Noteer informatie over binnenkomende aanvragen en antwoorden.
  • Filter welke onderdelen van de aanvraag en het antwoord worden geregistreerd.
  • Filteren welke headers moeten worden vastgelegd.

HTTP-logboekregistratie kan de prestaties van een app verminderen, met name bij het vastleggen van de aanvraag- en antwoordteksten. Houd rekening met de invloed van de prestaties bij het selecteren van velden die moeten worden vastgelegd. Test de invloed van de geselecteerde logeigenschappen op de prestaties.

Warning

HTTP-logboekregistratie kan mogelijk persoonlijk identificeerbare informatie (PII) registreren. Houd rekening met het risico en vermijd gevoelige informatie in logboekregistratie.

HTTP-logboekregistratie inschakelen

HTTP-logboekregistratie is ingeschakeld met UseHttpLogging, waarmee middleware voor HTTP-logboekregistratie wordt toegevoegd.

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();

Http-logboekregistratie registreert standaard algemene eigenschappen, zoals pad, statuscode en headers voor aanvragen en antwoorden. Voeg de volgende regel toe aan het appsettings.Development.json bestand op niveau "LogLevel": { , zodat de HTTP-logboeken worden weergegeven:

 "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"

De uitvoer wordt geregistreerd als één bericht op LogLevel.Information.

Voorbeeld van aanvraaguitvoer

Opties voor HTTP-logboekregistratie

Om de middleware voor HTTP-logboekregistratie te configureren, roep AddHttpLogging aan in 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

In het voorgaande voorbeeld en de volgende voorbeelden wordt UseHttpLogging aangeroepen na UseStaticFiles, zodat HTTP-logboekregistratie niet is ingeschakeld voor statische bestanden. Roep UseHttpLogging aan voordat UseStaticFiles om HTTP-logboekregistratie voor statische bestanden in te schakelen.

LoggingFields

HttpLoggingOptions.LoggingFields is een enum-vlag waarmee specifieke onderdelen van de aanvraag en reactie worden geconfigureerd voor loggen. HttpLoggingOptions.LoggingFields is standaard ingesteld op RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.

RequestHeaders

Headers zijn een set HTTP-aanvraagheaders die mogen worden geregistreerd. Headerwaarden worden alleen geregistreerd voor headernamen die zich in deze verzameling bevinden. Met de volgende code wordt de aanvraagheader "sec-ch-ua"vastgelegd. Als logging.RequestHeaders.Add("sec-ch-ua"); is verwijderd, wordt de waarde van de aanvraagheader "sec-ch-ua" verwijderd. De volgende gemarkeerde code-aanroepen HttpLoggingOptions.RequestHeaders en 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 biedt configuratie voor het selecteren van welke codering moet worden gebruikt voor een specifiek mediatype.

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();

Deze methode kan ook worden gebruikt om logboekregistratie in te schakelen voor gegevens die niet standaard worden geregistreerd. Formuliergegevens, die bijvoorbeeld een mediatype kunnen hebben, zoals application/x-www-form-urlencoded of multipart/form-data.

MediaTypeOptions Methoden

RequestBodyLogLimit en 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();

Gevoelige gegevens redacteren

HTTP-logboekregistratie met redacties kan worden ingeschakeld door te roepen AddHttpLoggingRedaction:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.Duration;
});

builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op => { });

Voor meer informatie over de gegevensreductiebibliotheek van .NET, zie Gegevensredactie in .NET.

Opties voor het vastleggen van redactions

Om opties voor logboekregistratie met redaction te configureren, roept u AddHttpLoggingRedaction in Program.cs aan met de lambda om LoggingRedactionOptions te configureren.

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();

Met de vorige redaction-configuratie ziet de uitvoer er ongeveer als volgt uit:

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

Het aanvraagpad /home wordt niet geregistreerd omdat het is opgenomen in de ExcludePathStartsWith eigenschap. http.request.header.accept en http.response.header.content-type werden geredigeerd door Microsoft.Extensions.Compliance.Redaction.ErasingRedactor.

RequestPathLoggingMode

RequestPathLoggingMode bepaalt hoe het aanvraagpad wordt geregistreerd, of dit Formatted of Structured is, ingesteld door IncomingPathLoggingMode:

  • Formatted: registreert het aanvraagpad zonder parameters.
  • Structured: registreert het aanvraagpad met parameters die zijn opgenomen.
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 specificeert hoe routeparameters in het aanvraagpad moeten worden bewerkt, hetzij Strict, Loose of None, ingesteld door HttpRouteParameterRedactionMode:

  • Strict: Routeparameters van verzoeken worden beschouwd als gevoelig, vereisen expliciete annotatie met een gegevensclassificatie en worden standaard geanonimiseerd.
  • Loose: Alle parameters worden als niet-gevoelig beschouwd en standaard opgenomen as-is.
  • None: Routeparameters worden niet geredigeerd, ongeacht de aanwezigheid van gegevensclassificatieaantekeningen.
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 wijst aanvraagheaders toe aan hun gegevensclassificatie, waarmee wordt bepaald hoe ze worden bewerkt:

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, vergelijkbaar met RequestHeadersDataClasses', maar voor antwoordheaders:

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 wijst routeparameters toe aan hun gegevensclassificatie:

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 hiermee geeft u paden op die volledig moeten worden uitgesloten van logboekregistratie:

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 maakt het mogelijk om niet-overeenkomende routes te rapporteren. Als dit is ingesteld op true, wordt het hele pad van routes die niet worden geïdentificeerd door Routering geregistreerd in plaats van de Unknown-waarde voor het padattribuut te loggen.

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();