Rejestrowanie HTTP w usłudze ASP.NET Core

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Rejestrowanie HTTP to oprogramowanie pośredniczące, które rejestruje informacje o przychodzących żądaniach HTTP i odpowiedziach HTTP. Rejestrowanie HTTP udostępnia dzienniki zawierające:

  • Informacje o żądaniach HTTP
  • Wspólne właściwości
  • Nagłówki
  • Treść
  • Informacje o odpowiedziach HTTP

Rejestrowanie HTTP może:

  • Rejestruj wszystkie żądania i odpowiedzi lub tylko żądania i odpowiedzi spełniające określone kryteria.
  • Wybierz, które części żądania i odpowiedzi są rejestrowane.
  • Umożliwia redagowania poufnych informacji z dzienników.

Rejestrowanie HTTP może zmniejszyć wydajność aplikacji, szczególnie podczas rejestrowania treści żądania i odpowiedzi. Podczas wybierania pól do rejestrowania należy wziąć pod uwagę wpływ na wydajność. Przetestuj wpływ na wydajność wybranych właściwości rejestrowania.

Ostrzeżenie

Rejestrowanie HTTP może potencjalnie rejestrować dane osobowe . Weź to ryzyko pod uwagę i unikaj rejestrowania poufnych informacji.

Włączanie rejestrowania HTTP

Rejestrowanie HTTP jest włączone przez wywołanie AddHttpLogging metod i UseHttpLogging, jak pokazano w poniższym przykładzie:

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

Pusta lambda w poprzednim przykładzie wywołania AddHttpLogging dodaje oprogramowanie pośredniczące z konfiguracją domyślną. Domyślnie rejestrowanie HTTP rejestruje typowe właściwości, takie jak ścieżka, kod stanu i nagłówki dla żądań i odpowiedzi.

Dodaj następujący wiersz do pliku appsettings.Development.json na poziomie "LogLevel": {, aby wyświetlić dzienniki HTTP:

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

W przypadku konfiguracji domyślnej żądanie i odpowiedź są rejestrowane jako para komunikatów podobnych do następującego przykładu:

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

Opcje rejestrowania HTTP

Aby skonfigurować globalne opcje oprogramowania pośredniczącego rejestrowania HTTP, wywołaj metodę AddHttpLogging w Program.csprogramie przy użyciu metody lambda w celu skonfigurowania HttpLoggingOptionspolecenia .

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

Uwaga

W poprzednim przykładzie i poniższych przykładach UseHttpLogging jest wywoływana po UseStaticFiles, więc rejestrowanie HTTP nie jest włączone dla plików statycznych. Aby włączyć rejestrowanie HTTP pliku statycznego, wywołaj metodę UseHttpLogging przed UseStaticFiles.

LoggingFields

Właściwość HttpLoggingOptions.LoggingFields to flaga wyliczenia, która konfiguruje konkretne części żądania i odpowiedzi, które mają zostać zarejestrowane. Właściwość HttpLoggingOptions.LoggingFields domyślnie przyjmuje wartość RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.

RequestHeaders i ResponseHeaders

RequestHeaders i ResponseHeaders to zestawy zarejestrowanych nagłówków HTTP. Wartości nagłówka są rejestrowane tylko dla nazw nagłówków, które znajdują się w tych kolekcjach. Poniższy kod dodaje sec-ch-ua element do RequestHeaderselementu , więc wartość nagłówka sec-ch-ua jest rejestrowana. Dodaje element MyResponseHeader do ResponseHeaderselementu , więc wartość nagłówka MyResponseHeader jest rejestrowana. Jeśli te wiersze zostaną usunięte, wartości tych nagłówków to [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

Właściwość MediaTypeOptions zapewnia konfigurację w celu wybrania, którego kodowania użyć w przypadku konkretnego typu nośnika.

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

Takie podejście może również służyć do włączania rejestrowania danych, które nie są rejestrowane domyślnie (na przykład dane formularza, które mogą mieć typ nośnika, taki jak application/x-www-form-urlencoded lub multipart/form-data).

Metody MediaTypeOptions

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

Ustawienie CombineLogs umożliwiające true skonfigurowanie oprogramowania pośredniczącego w celu skonsolidowania wszystkich dzienników z włączonymi dziennikami dla żądania i odpowiedzi na jeden dziennik na końcu. Obejmuje to żądanie, treść żądania, odpowiedź, treść odpowiedzi i czas trwania.

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

Konfiguracja specyficzna dla punktu końcowego

W przypadku konfiguracji specyficznej dla punktu końcowego w minimalnych aplikacjach WithHttpLogging interfejsu API dostępna jest metoda rozszerzenia. W poniższym przykładzie pokazano, jak skonfigurować rejestrowanie HTTP dla jednego punktu końcowego:

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

W przypadku konfiguracji specyficznej dla punktu końcowego w aplikacjach korzystających z kontrolerów [HttpLogging] atrybut jest dostępny. Atrybut może być również używany w minimalnych aplikacjach interfejsu API, jak pokazano w poniższym przykładzie:

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

IHttpLoggingInterceptor

IHttpLoggingInterceptor to interfejs usługi, który można zaimplementować w celu obsługi wywołań zwrotnych dla poszczególnych żądań i odpowiedzi w celu dostosowania szczegółów, które są rejestrowane. Wszystkie ustawienia dziennika specyficzne dla punktu końcowego są stosowane najpierw, a następnie można je przesłonić w tych wywołaniach zwrotnych. Implementacja może:

  • Sprawdź żądanie lub odpowiedź.
  • Włącz lub wyłącz dowolny HttpLoggingFields.
  • Dostosuj liczbę rejestrowanych treści żądania lub odpowiedzi.
  • Dodaj pola niestandardowe do dzienników.

Zarejestruj implementację IHttpLoggingInterceptor , wywołując polecenie AddHttpLoggingInterceptor<T> w pliku Program.cs. Jeśli zarejestrowano wiele IHttpLoggingInterceptor wystąpień, są one uruchamiane w kolejności zarejestrowanej.

W poniższym przykładzie pokazano, jak zarejestrować implementację IHttpLoggingInterceptor :

var builder = WebApplication.CreateBuilder(args);

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

Poniższy przykład to implementacja IHttpLoggingInterceptor , która:

  • Sprawdza metodę żądania i wyłącza rejestrowanie żądań POST.
  • W przypadku żądań innych niż POST:
    • Redacts ścieżka żądania, nagłówki żądań i nagłówki odpowiedzi.
    • Dodaje niestandardowe pola i wartości pól do dzienników żądań i odpowiedzi.
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");
    }
}

W przypadku tego przechwytywania żądanie POST nie generuje żadnych dzienników, nawet jeśli rejestrowanie HTTP jest skonfigurowane do rejestrowania HttpLoggingFields.All. Żądanie GET generuje dzienniki podobne do następującego przykładu:

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

Rejestrowanie kolejności konfiguracji pierwszeństwa

Poniższa lista przedstawia kolejność pierwszeństwa konfiguracji rejestrowania:

  1. Konfiguracja globalna z HttpLoggingOptionsklasy , ustawiona przez wywołanie metody AddHttpLogging.
  2. Konfiguracja specyficzna dla punktu końcowego z atrybutu [HttpLogging] lub WithHttpLogging metody rozszerzenia zastępuje konfigurację globalną.
  3. IHttpLoggingInterceptor element jest wywoływany z wynikami i może dodatkowo modyfikować konfigurację na żądanie.

Rejestrowanie HTTP to oprogramowanie pośredniczące, które rejestruje informacje na temat przychodzących żądań i odpowiedzi HTTP. Rejestrowanie HTTP udostępnia dzienniki zawierające:

  • Informacje o żądaniach HTTP
  • Wspólne właściwości
  • Nagłówki
  • Treść
  • Informacje o odpowiedziach HTTP

Rejestrowanie HTTP przydaje się w kilku scenariuszach i umożliwia:

  • Rejestrowanie informacji o przychodzących żądaniach i odpowiedziach.
  • Filtrowanie części żądania i odpowiedzi, które są rejestrowane.
  • Filtrowanie nagłówków, które należy zarejestrować.

Rejestrowanie HTTP może obniżyć wydajność aplikacji, szczególnie w przypadku rejestrowania treści żądania i odpowiedzi. Podczas wybierania pól do rejestrowania należy wziąć pod uwagę wpływ na wydajność. Przetestuj wpływ na wydajność wybranych właściwości rejestrowania.

Ostrzeżenie

Rejestrowanie HTTP może potencjalnie rejestrować dane osobowe. Weź to ryzyko pod uwagę i unikaj rejestrowania poufnych informacji.

Włączanie rejestrowania HTTP

Rejestrowanie HTTP jest włączane za pomocą metody UseHttpLogging, która dodaje oprogramowanie pośredniczące rejestrowania 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();

Domyślnie rejestrowanie HTTP rejestruje typowe właściwości, takie jak ścieżka, kod stanu i nagłówki żądań i odpowiedzi. Dodaj następujący wiersz do pliku appsettings.Development.json na poziomie "LogLevel": {, aby wyświetlić dzienniki HTTP:

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

Dane wyjściowe są rejestrowane jako pojedynczy komunikat na poziomie LogLevel.Information.

Dane wyjściowe przykładowego żądania

Opcje rejestrowania HTTP

Aby skonfigurować oprogramowanie pośredniczące rejestrowania HTTP, wywołaj metodę AddHttpLogging w pliku 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();

Uwaga

W poprzednim przykładzie i poniższych przykładach UseHttpLogging jest wywoływana po UseStaticFiles, więc rejestrowanie HTTP nie jest włączone dla pliku statycznego. Aby włączyć rejestrowanie HTTP pliku statycznego, wywołaj metodę UseHttpLogging przed UseStaticFiles.

LoggingFields

Właściwość HttpLoggingOptions.LoggingFields to flaga wyliczenia, która konfiguruje konkretne części żądania i odpowiedzi, które mają zostać zarejestrowane. Właściwość HttpLoggingOptions.LoggingFields domyślnie przyjmuje wartość RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.

RequestHeaders

Właściwość Headers to zestaw nagłówków żądania HTTP, które można rejestrować. Wartości nagłówków są rejestrowane tylko w przypadku nazw nagłówków umieszczonych w tej kolekcji. Poniższy kod rejestruje nagłówek żądania "sec-ch-ua". Jeśli element logging.RequestHeaders.Add("sec-ch-ua"); zostanie usunięty, wartość nagłówka żądania "sec-ch-ua" zostanie zredagowana. Następujący wyróżniony kod wywołuje właściwości HttpLoggingOptions.RequestHeaders i 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

Właściwość MediaTypeOptions zapewnia konfigurację w celu wybrania, którego kodowania użyć w przypadku konkretnego typu nośnika.

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

Takie podejście może również służyć do włączania rejestrowania danych, które nie są rejestrowane domyślnie (np. dane formularza, które mogą mieć typ nośnika, taki jak application/x-www-form-urlencoded lub multipart/form-data).

Metody MediaTypeOptions

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