Megosztás a következőn keresztül:


HTTP-naplózás a ASP.NET Core-ban

Note

Ez nem a cikk legújabb verziója. Az aktuális kiadásról a cikk .NET 10-es verziójában olvashat.

Warning

A ASP.NET Core ezen verziója már nem támogatott. További információ: .NET és .NET Core támogatási szabályzat. A jelen cikk .NET 9-es verzióját lásd az aktuális kiadásért .

A HTTP-naplózás egy köztes szoftver, amely naplózza a bejövő HTTP-kérelmek és HTTP-válaszok adatait. A HTTP-naplózás a következő naplókat tartalmazza:

  • HTTP-kérelem adatai
  • Általános tulajdonságok
  • Headers
  • Body
  • HTTP-válasz információi

A HTTP-naplózás a következő lehet:

  • Naplózza az összes kérést és választ, vagy csak azokat a kéréseket és válaszokat, amelyek megfelelnek bizonyos feltételeknek.
  • Válassza ki a kérés és a válasz mely részeit naplózza.
  • Lehetővé teszi a naplók bizalmas információinak eltávolítását.

A HTTP-naplózás csökkentheti az alkalmazások teljesítményét, különösen a kérés- és választörzsek naplózása során. A naplózni kívánt mezők kiválasztásakor vegye figyelembe a teljesítményre gyakorolt hatást. Tesztelje a kiválasztott naplózási tulajdonságok teljesítményre gyakorolt hatását.

Warning

A HTTP-naplózás személyazonosításra alkalmas adatokat (PII) is naplózhat. Vegye figyelembe a kockázatot, és kerülje a bizalmas adatok naplózását. Az adatok kitakarásával kapcsolatos további információkért tekintse meg a bizalmas adatok kitakarását

HTTP-naplózás engedélyezése

A HTTP-naplózás a AddHttpLogging és UseHttpLogging hívásával engedélyezhető, az alábbi példa szerint:

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

Az előző hívási AddHttpLogging példában szereplő üres lambda hozzáadja a köztes szoftvert az alapértelmezett konfigurációhoz. A HTTP-naplózás alapértelmezés szerint naplózza a kérések és válaszok gyakori tulajdonságait, például az elérési utat, az állapotkódot és a fejléceket.

Adja hozzá a következő sort a appsettings.Development.json fájlhoz a "LogLevel": { http-naplók megjelenítéséhez:

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

Az alapértelmezett konfigurációval a rendszer a következő példához hasonló üzenetpárként naplózza a kéréseket és a válaszokat:

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

HTTP-naplózási beállítások

A HTTP-naplózási köztes szoftver globális beállításainak konfigurálásához hívja meg a AddHttpLogging a Program.cs-ban, és használja a lambdát a HttpLoggingOptions konfigurálásához.

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

Az előző mintában és a következő mintákban a rendszer a UseHttpLogging elemet a UseStaticFiles után hívja meg, így a HTTP-naplózás statikus fájlok esetében nincs engedélyezve. A statikus fájl HTTP-naplózásának engedélyezéséhez hívja meg a UseHttpLogging-ot a UseStaticFiles előtt.

LoggingFields

HttpLoggingOptions.LoggingFields egy számjelölő, amely a kérés adott részeit és a naplóra adott választ konfigurálja. alapértelmezett érték: .>

RequestHeaders és ResponseHeaders

RequestHeaders és ResponseHeaders a naplózott HTTP-fejlécek készletei. A fejlécértékek csak az ezekben a gyűjteményekben található fejlécnevekhez vannak naplózva. A következő kód hozzáadja sec-ch-ua-t a RequestHeaders-hez, így a sec-ch-ua fejléc értékét naplózza. És hozzáadja MyResponseHeader-t a ResponseHeaders-hez, így a MyResponseHeader fejléc értéke naplózva lesz. Ha ezek a sorok el lettek távolítva, a fejlécek értékei a következők [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 konfigurációt biztosít az adott médiatípushoz használandó kódolás kiválasztásához.

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

Ezzel a módszerrel engedélyezhető az alapértelmezés szerint nem naplózott adatok naplózása (például űrlapadatok, amelyek médiatípussal rendelkezhetnek, például application/x-www-form-urlencoded vagy multipart/form-data).

MediaTypeOptions Módszerek

RequestBodyLogLimit és 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

A köztes szoftver konfigurálásának CombineLogs beállítása true a kérelem és a válasz összes engedélyezett naplójának összesítésére egy naplóba a végén. Ez magában foglalja a kérést, a kérelem törzsét, a választ, a válasz törzsét és az időtartamot.

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

Végpontspecifikus konfiguráció

A minimális API-alkalmazások WithHttpLogging végpontspecifikus konfigurációja esetén egy bővítménymetódus érhető el. Az alábbi példa bemutatja, hogyan konfigurálható a HTTP-naplózás egy végponthoz:

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

A vezérlőket használó alkalmazások végpontspecifikus konfigurációja esetén az [HttpLogging] attribútum elérhető. Az attribútum minimális API-alkalmazásokban is használható, ahogy az alábbi példában is látható:

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

IHttpLoggingInterceptor

IHttpLoggingInterceptor Egy olyan szolgáltatás felülete, amely a kérésenkénti és a válaszonkénti visszahívások kezelésére implementálható a naplózott adatok testreszabásához. A végpontspecifikus naplóbeállításokat először alkalmazzuk, és ezeket a visszahívások során felül lehet bírálni. A megvalósítás a következő lehet:

  • Vizsgálja meg a kérést vagy a választ.
  • Az HttpLoggingFieldsengedélyezése vagy letiltása.
  • A kérelem vagy válasz törzséből naplózott rész mennyiségének beállítása.
  • Egyéni mezők hozzáadása a naplókhoz.

Regisztráljon egy IHttpLoggingInterceptor implementációt a AddHttpLoggingInterceptor-ban a Program.cs hívásával. Ha több IHttpLoggingInterceptor példány van regisztrálva, akkor a rendszer a regisztrált sorrendben futtatja őket.

Az alábbi példa bemutatja, hogyan regisztrálhat implementációt IHttpLoggingInterceptor :

var builder = WebApplication.CreateBuilder(args);

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

Az alábbi példa egy IHttpLoggingInterceptor implementáció, amely:

  • Vizsgálja meg a kérelem metódusát, és tiltsa le a POST-kérelmek naplózását.
  • Nem POST kérések esetén:
    • Cenzúrázza a kérelem útvonalát, a kérelemfejléceket és a válaszfejléceket.
    • Egyéni mezőket és mezőértékeket ad hozzá a kérelem- és válasznaplókhoz.
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");
    }
}

Ezzel az elfogóval a POST-kérések nem hoznak létre naplókat akkor sem, ha a HTTP-naplózás HttpLoggingFields.All konfigurálva van. A GET-kérések az alábbi példához hasonló naplókat hoznak létre:

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

A naplózás konfigurációs sorrendje elsőbbséget élvez

Az alábbi lista a naplózás konfigurációjának sorrendjét mutatja be:

  1. Globális konfiguráció a hívással HttpLoggingOptionsbeállított helyrőlAddHttpLogging.
  2. Az attribútum vagy a [HttpLogging] bővítménymetódus végpontspecifikus konfigurációja felülírja a WithHttpLogging globális konfigurációt.
  3. IHttpLoggingInterceptor az eredményekkel együtt van meghívva, és kérésenként tovább módosíthatja a konfigurációt.

A HTTP-naplózás egy köztes szoftver, amely naplózza a bejövő HTTP-kérelmekre és HTTP-válaszokra vonatkozó információkat. A HTTP-naplózás a következő naplókat tartalmazza:

  • HTTP-kérelem adatai
  • Általános tulajdonságok
  • Headers
  • Body
  • HTTP-válasz információi

A HTTP-naplózás több forgatókönyvben is hasznos:

  • A bejövő kérésekkel és válaszokkal kapcsolatos információk rögzítése.
  • Szűrje a kérés és a válasz mely részeit naplózza.
  • A naplózni kívánt fejlécek szűrése.

A HTTP-naplózás csökkentheti az alkalmazások teljesítményét, különösen a kérés- és választestek naplózása során. A naplózni kívánt mezők kiválasztásakor vegye figyelembe a teljesítményre gyakorolt hatást. Tesztelje a kiválasztott naplózási tulajdonságok teljesítményre gyakorolt hatását.

Warning

A HTTP-naplózás személyazonosításra alkalmas adatokat (PII) is naplózhat. Vegye figyelembe a kockázatot, és kerülje a bizalmas adatok naplózását.

HTTP-naplózás engedélyezése

A HTTP-naplózás be van kapcsolva a UseHttpLogging által hozzáadott köztes szoftverrel.

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

A HTTP-naplózás alapértelmezés szerint naplózza a kérések és válaszok gyakori tulajdonságait, például az elérési utat, az állapotkódot és a fejléceket. Adja hozzá a következő sort a appsettings.Development.json fájlhoz a "LogLevel": { http-naplók megjelenítéséhez:

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

A kimenetet a rendszer egyetlen üzenetként naplózza a következő helyen LogLevel.Information: .

Mintakérés kimenete

HTTP-naplózási beállítások

A HTTP-naplózási middleware konfigurálásához hívja meg 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

Az előző mintában és a következő mintákban a UseHttpLogging a UseStaticFiles után van hívva, így a HTTP-naplózás nincs engedélyezve a statikus fájlhoz. A statikus fájl HTTP-naplózásának engedélyezéséhez hívja meg a UseHttpLogging-ot a UseStaticFiles előtt.

LoggingFields

HttpLoggingOptions.LoggingFields egy számjelölő, amely a kérés adott részeit és a naplóra adott választ konfigurálja. alapértelmezett érték: .>

RequestHeaders

Headers egy olyan HTTP-kérelemfejlécek készlete, amelyek naplózhatók. A fejlécértékek csak az ebben a gyűjteményben található fejlécnevekhez vannak naplózva. Az alábbi kód naplózza a kérelem fejlécét "sec-ch-ua". Ha logging.RequestHeaders.Add("sec-ch-ua"); el van távolítva, a kérelem fejlécének "sec-ch-ua" értéke el lesz távolítva. A következő kiemelt kódhívások HttpLoggingOptions.RequestHeaders és 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 konfigurációt biztosít az adott médiatípushoz használandó kódolás kiválasztásához.

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

Ez a módszer az alapértelmezetten nem naplózott adatok naplózásának engedélyezésére is használható. Például űrlapadatok, amelyek médiatípussal rendelkezhetnek, például application/x-www-form-urlencoded vagy multipart/form-data.

MediaTypeOptions Módszerek

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

Bizalmas adatok kitakarása

A http-naplózás kitakarással engedélyezhető a következő hívással: AddHttpLoggingRedaction

var builder = WebApplication.CreateBuilder(args);

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

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

További információért a .NET adatmaszkolási könyvtáráról lásd: Adatmaszkolás a .NET-ben.

Naplózási szerkesztési beállítások

A naplózási beállítások redaction használatával történő konfigurálásához hívja meg AddHttpLoggingRedaction a Program.cs-ban, és a lambdával konfigurálja a LoggingRedactionOptions-t.

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

Az előző szerkesztési konfigurációval a kimenet a következőhöz hasonló:

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

A kérelem elérési útja /home nincs naplózva, mert szerepel a ExcludePathStartsWith tulajdonságban. http.request.header.accept és http.response.header.content-type ki lettek cenzúrázva Microsoft.Extensions.Compliance.Redaction.ErasingRedactor által.

RequestPathLoggingMode

RequestPathLoggingMode meghatározza, hogy a kérelem elérési útja hogyan van naplózva, attól függően, hogy Formatted vagy Structured, IncomingPathLoggingMode határozza meg:

  • Formatted: A kérelem elérési útját paraméterek nélkül naplózza.
  • Structured: Naplózza a kérelem elérési útját a benne foglalt paraméterekkel.
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 meghatározza, hogyan legyenek elrejtve a kérelem elérési útjának útvonalparaméterei; akár Strict, Loose, vagy None által, a HttpRouteParameterRedactionMode által beállítva:

  • Strict: A kérések útvonalának paraméterei bizalmasnak minősülnek, explicit jelölést igényelnek egy adatbesorolással, és alapértelmezés szerint cenzúrázva vannak.
  • Loose: A rendszer minden paramétert nem bizalmasnak tekint, és alapértelmezés szerint as-is tartalmazza.
  • None: Az útvonalparaméterek nem kerülnek eltávolításra az adatbesorolási jelölések jelenlététől függetlenül.
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 leképezi a kérelemfejléceket az adatbesorolásukra, amely meghatározza, hogyan lesznek elrejtve.

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, hasonló a RequestHeadersDataClasses", de a válaszfejlécekhez:

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 az útvonalparamétereket az adatbesorolásukhoz rendeli:

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 olyan útvonalakat határoz meg, amelyeket teljes mértékben ki kell zárni a naplózásból:

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 lehetővé teszi a nem egyező útvonalak jelentését. Ha true be van állítva, naplózza az útválasztás által nem azonosított útvonalak teljes útvonalát, az útvonalattribútum naplózandó Unknown értéke helyett:

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