Aracılığıyla paylaş


ASP.NET Core'da HTTP günlüğü

Note

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.

Warning

ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.

HTTP günlüğü, gelen HTTP istekleri ve HTTP yanıtları hakkındaki bilgileri günlüğe kaydeden bir ara yazılımdır. HTTP günlüğü şu günlükleri sağlar:

  • HTTP isteği bilgileri
  • Ortak özellikler
  • Headers
  • Body
  • HTTP yanıt bilgileri

HTTP günlüğü:

  • Tüm istekleri ve yanıtları veya yalnızca belirli ölçütleri karşılayan istekleri ve yanıtları günlüğe kaydetme.
  • İstek ve yanıtın hangi bölümlerinin günlüğe kaydedildiği seçin.
  • Günlüklerden hassas bilgileri yeniden düzenlemenize olanak sağlar.

HTTP günlüğü , özellikle istek ve yanıt gövdelerini günlüğe kaydetme sırasında uygulamanın performansını düşürebilir. Günlüğe kaydedilecek alanları seçerken performans etkisini göz önünde bulundurun. Seçili günlük özelliklerinin performans etkisini test edin.

Warning

HTTP günlüğü, kişisel bilgileri (PII) günlüğe kaydedebilir. Riski göz önünde bulundurun ve hassas bilgileri günlüğe kaydetmekten kaçının. Yeniden oluşturma hakkında daha fazla bilgi için hassas verileri yeniden işlemden geçirmeyi denetleyin

HTTP günlüğünü etkinleştirme

HTTP günlüğü, aşağıdaki örnekte gösterildiği gibi ve AddHttpLoggingçağrılarak UseHttpLogging etkinleştirilir:

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

Önceki çağrı AddHttpLogging örneğindeki boş lambda, ara yazılımı varsayılan yapılandırmayla ekler. Varsayılan olarak, HTTP günlüğü istekler ve yanıtlar için yol, durum kodu ve üst bilgiler gibi ortak özellikleri günlüğe kaydeder.

HTTP günlüklerinin görüntülenmesi için appsettings.Development.json dosyasına "LogLevel": { düzeyinde aşağıdaki satırı ekleyin:

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

Varsayılan yapılandırmada, istek ve yanıt aşağıdaki örneğe benzer bir ileti çifti olarak günlüğe kaydedilir:

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 günlük seçenekleri

HTTP günlüğe kaydetme ara yazılımı için genel seçenekleri yapılandırmak için, AddHttpLoggingProgram.cslambda kullanarak komutunu çağırın HttpLoggingOptions.

using Microsoft.AspNetCore.HttpLogging;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.All;
    logging.RequestHeaders.Add("sec-ch-ua");
    logging.ResponseHeaders.Add("MyResponseHeader");
    logging.MediaTypeOptions.AddText("application/javascript");
    logging.RequestBodyLogLimit = 4096;
    logging.ResponseBodyLogLimit = 4096;
    logging.CombineLogs = true;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
}

app.UseStaticFiles();

app.UseHttpLogging();

app.Use(async (context, next) =>
{
    context.Response.Headers["MyResponseHeader"] =
        new string[] { "My Response Header Value" };

    await next();
});

app.MapGet("/", () => "Hello World!");

app.Run();

Note

Yukarıdaki örnekte ve aşağıdaki örneklerde, 'den sonra UseHttpLoggingçağrılır, UseStaticFiles bu nedenle statik dosyalar için HTTP günlüğü etkinleştirilmez. Statik dosya HTTP günlüğünü etkinleştirmek için önce UseHttpLoggingöğesini arayınUseStaticFiles.

LoggingFields

HttpLoggingOptions.LoggingFields, isteğin belirli bölümlerini yapılandıran ve günlüğe yanıt veren bir sabit listesi bayrağıdır. LoggingFields varsayılan olarak RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders şeklinde ayarlanır.

RequestHeaders ve ResponseHeaders

RequestHeaders ve ResponseHeaders günlüğe kaydedilen HTTP üst bilgi kümeleridir. Üst bilgi değerleri yalnızca bu koleksiyonlardaki üst bilgi adları için günlüğe kaydedilir. Aşağıdaki kod öğesine ekler sec-ch-uaRequestHeaders, böylece üst bilginin değeri sec-ch-ua günlüğe kaydedilir. Üst bilginin değeri MyResponseHeader günlüğe ResponseHeaderskaydedilecek şekilde öğesine eklenirMyResponseHeader. Bu satırlar kaldırılırsa, bu üst bilgilerin değerleri olur [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 belirli bir medya türü için hangi kodlamanın kullanılacağını seçmek üzere yapılandırma sağlar.

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

Bu yaklaşım, varsayılan olarak günlüğe kaydedilmeyen veriler için günlüğe kaydetmeyi etkinleştirmek için de kullanılabilir (örneğin, veya application/x-www-form-urlencodedgibi multipart/form-data bir medya türüne sahip olabilecek form verileri).

MediaTypeOptions yöntemleri

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

ayarı CombineLogstrue , ara yazılımı bir istek ve yanıt için etkinleştirilen tüm günlüklerini sonundaki tek bir günlükte birleştirecek şekilde yapılandırıyor. Buna istek, istek gövdesi, yanıt, yanıt gövdesi ve süre dahildir.

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

Uç noktaya özgü yapılandırma

En düşük API uygulamalarında uç noktaya özgü yapılandırma için bir WithHttpLogging uzantı yöntemi kullanılabilir. Aşağıdaki örnekte, bir uç nokta için HTTP günlüğünü yapılandırma işlemi gösterilmektedir:

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

Denetleyici kullanan uygulamalarda uç noktaya özgü yapılandırma için [HttpLogging] özniteliği kullanılabilir. Öznitelik, aşağıdaki örnekte gösterildiği gibi minimum API uygulamalarında da kullanılabilir:

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

IHttpLoggingInterceptor

IHttpLoggingInterceptor , günlüğe kaydedilen ayrıntıları özelleştirmek için istek başına ve yanıt başına geri çağırmaları işlemek için uygulanabilen bir hizmetin arabirimidir. Uç noktaya özgü günlük ayarları önce uygulanır ve daha sonra bu geri çağırmalarda geçersiz kılınabilir. Bir uygulama:

  • bir isteği veya yanıtı inceleyin.
  • Herhangi bir HttpLoggingFieldsöğesini etkinleştirin veya devre dışı bırakın.
  • İstek veya yanıt gövdesinin ne kadarının günlüğe kaydedilmiş olduğunu ayarlayın.
  • Günlüklere özel alanlar ekleyin.

içinde IHttpLoggingInterceptorçağrısı AddHttpLoggingInterceptor yaparak bir Program.cs uygulamayı kaydedin. Birden çok IHttpLoggingInterceptor örnek kayıtlıysa, bunlar kayıtlı sırayla çalıştırılır.

Aşağıdaki örnekte bir IHttpLoggingInterceptor uygulamanın nasıl kaydedilecekleri gösterilmektedir:

var builder = WebApplication.CreateBuilder(args);

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

Aşağıdaki örnek şu şekilde bir IHttpLoggingInterceptor uygulamadır:

  • İstek yöntemini inceler ve POST istekleri için günlüğe kaydetmeyi devre dışı bırakır.
  • POST olmayan istekler için:
    • İstek yolunu, istek üst bilgilerini ve yanıt üst bilgilerini yeniden düzenler.
    • İstek ve yanıt günlüklerine özel alanlar ve alan değerleri ekler.
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");
    }
}

Bu kesme noktası ile, HTTP günlüğü günlüğe kaydetmek üzere yapılandırılmış olsa bile post isteği herhangi bir günlük HttpLoggingFields.Alloluşturmaz. GET isteği aşağıdaki örneğe benzer günlükler oluşturur:

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

Öncelik yapılandırma sırasını günlüğe kaydetme

Aşağıdaki listede günlük yapılandırması için öncelik sırası gösterilmektedir:

  1. 'den HttpLoggingOptionsgenel yapılandırma çağrısı AddHttpLoggingyaparak ayarlayın.
  2. Özniteliğinden veya uzantı yönteminden [HttpLogging] uç noktaya özgü yapılandırma, genel yapılandırmayı WithHttpLogging geçersiz kılar.
  3. IHttpLoggingInterceptor sonuçlarla birlikte çağrılır ve istek başına yapılandırmayı daha fazla değiştirebilir.

HTTP Günlüğü, gelen HTTP istekleri ve HTTP yanıtları hakkındaki bilgileri günlüğe kaydeden bir ara yazılımdır. HTTP günlüğü şu günlükleri sağlar:

  • HTTP isteği bilgileri
  • Ortak özellikler
  • Headers
  • Body
  • HTTP yanıt bilgileri

HTTP Günlüğü, aşağıdakiler için çeşitli senaryolarda değerlidir:

  • Gelen istekler ve yanıtlar hakkındaki bilgileri kaydetme.
  • İsteğin ve yanıtın hangi bölümlerinin günlüğe kaydedildiği filtreleme.
  • Günlüğe kaydedilecek üst bilgileri filtreleme.

HTTP Günlüğü, özellikle istek ve yanıt gövdelerini günlüğe kaydettiğinizde uygulamanın performansını azaltabilir. Günlüğe kaydedilecek alanları seçerken performans etkisini göz önünde bulundurun. Seçili günlük özelliklerinin performans etkisini test edin.

Warning

HTTP Günlüğü potansiyel olarak kişisel bilgileri (PII) günlüğe kaydedebilir. Riski göz önünde bulundurun ve hassas bilgileri günlüğe kaydetmekten kaçının.

HTTP günlüğünü etkinleştirme

HTTP Günlüğü, http günlüğü ara yazılımını ekleyen UseHttpLogging ile etkinleştirilir.

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

Varsayılan olarak, HTTP Günlüğü, istekler ve yanıtlar için yol, durum kodu ve üst bilgiler gibi ortak özellikleri günlüğe kaydeder. HTTP günlüklerinin görüntülenmesi için appsettings.Development.json dosyasına "LogLevel": { düzeyinde aşağıdaki satırı ekleyin:

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

Çıkış, LogLevel.Information konumunda tek bir ileti olarak günlüğe kaydedilir.

Örnek istek çıkışı

HTTP Günlüğü seçenekleri

HTTP günlüğü ara yazılımını yapılandırmak AddHttpLogging içinden Program.cs çağırın.

using Microsoft.AspNetCore.HttpLogging;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.All;
    logging.RequestHeaders.Add("sec-ch-ua");
    logging.ResponseHeaders.Add("MyResponseHeader");
    logging.MediaTypeOptions.AddText("application/javascript");
    logging.RequestBodyLogLimit = 4096;
    logging.ResponseBodyLogLimit = 4096;

});

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

Yukarıdaki örnekte ve aşağıdaki örneklerde, 'den sonra UseHttpLoggingçağrılır, UseStaticFiles bu nedenle statik dosya için HTTP günlüğü etkinleştirilmez. Statik dosya HTTP günlüğünü etkinleştirmek için önce UseHttpLoggingöğesini arayınUseStaticFiles.

LoggingFields

HttpLoggingOptions.LoggingFields, isteğin belirli bölümlerini yapılandıran ve günlüğe yanıt veren bir sabit listesi bayrağıdır. HttpLoggingOptions.LoggingFields varsayılan olarak RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders şeklinde ayarlanır.

RequestHeaders

Headers günlüğe kaydedilmesine izin verilen bir dizi HTTP İsteği Üst Bilgisidir. Üst bilgi değerleri yalnızca bu koleksiyondaki üst bilgi adları için günlüğe kaydedilir. Aşağıdaki kod "sec-ch-ua" istek üst bilgisini günlüğe kaydeder. logging.RequestHeaders.Add("sec-ch-ua"); kaldırılırsa, "sec-ch-ua" istek üst bilgisinin değeri yeniden oluşturulur. Aşağıdaki vurgulanan kod HttpLoggingOptions.RequestHeaders ve HttpLoggingOptions.ResponseHeaders özelliğini çağırır :

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 belirli bir medya türü için hangi kodlamanın kullanılacağını seçmek üzere yapılandırma sağlar.

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

Bu yaklaşım, varsayılan olarak günlüğe kaydedilmemiş veriler için günlüğe kaydetmeyi etkinleştirmek için de kullanılabilir. Örneğin, veya application/x-www-form-urlencodedgibi multipart/form-data bir medya türüne sahip olabilecek form verileri.

MediaTypeOptions yöntemleri

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

Hassas verileri yeniden işlemden geçirme

Redaction ile http günlüğü çağrılarak AddHttpLoggingRedactionetkinleştirilebilir:

var builder = WebApplication.CreateBuilder(args);

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

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

hakkında daha fazla bilgi için. NET'in veri redaksiyon kitaplığı, bkz. .NET'te veri yeniden eylem.

Kayıt tutma gizleme seçenekleri

Redaction ile günlüğe kaydetme seçeneklerini yapılandırmak için AddHttpLoggingRedaction içinde Program.cs yapılandırmak üzere LoggingRedactionOptions çağırırken lambda kullanın.

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

Önceki redaction yapılandırmasında çıkış aşağıdakine benzer:

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

İstek yolu /home özelliğine eklendiğinden günlüğe ExcludePathStartsWithkaydedilmez. http.request.header.accept ve http.response.header.content-typeMicrosoft.Extensions.Compliance.Redaction.ErasingRedactor tarafından gizlendi.

RequestPathLoggingMode

RequestPathLoggingMode, Formatted tarafından ayarlanan istek yolunun günlüğe nasıl kaydedileceğini, Structured mi yoksa IncomingPathLoggingMode mu, belirler:

  • Formatted: İstek yolunu parametreler olmadan kaydeder.
  • Structured: İstek yolunu parametreleriyle birlikte günlüğe kaydeder.
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, veya Strict, tarafından ayarlanmış LooseolsunNoneHttpRouteParameterRedactionMode, istek yolundaki yol parametrelerinin nasıl yeniden işlem yapılacağını belirtir:

  • Strict: İstek yolu parametreleri hassas kabul edilir, veri sınıflandırması ile belirgin ek açıklama gerektirir ve varsayılan olarak gizlenir.
  • Loose: Tüm parametreler, varsayılan olarak hassas olmayan ve as-is olarak kabul edilir.
  • None: Yol parametreleri, veri sınıflandırma ek açıklamalarının varlığından bağımsız olarak yeniden işlemden çıkarılmaz.
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 istek üst bilgilerini veri sınıflandırmasına eşler ve bu da bunların nasıl yeniden işlem yapıldığını belirler:

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, 'ye RequestHeadersDataClassesbenzer, ancak yanıt üst bilgileri için:

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 rota parametrelerini veri sınıflandırmalarına eşler:

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 günlüğe kaydetmenin tamamen dışında tutulması gereken yolları belirtir:

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 eşleşmeyen yolları raporlamaya izin verir. olarak ayarlanırsa, path özniteliği için günlüğe truekaydetme değeri yerine Yönlendirme tarafından tanımlanmayan yolların tüm yolunu günlüğe kaydeder Unknown :

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