Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Note
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 10 dari artikel ini.
Warning
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 9 dari artikel ini.
Pengelogan HTTP adalah middleware yang mencatat informasi tentang permintaan HTTP masuk dan respons HTTP. Pengelogan HTTP menyediakan log dari:
- Informasi permintaan HTTP
- Properti umum
- Headers
- Body
- Informasi respons HTTP
Pengelogan HTTP dapat:
- Catat semua permintaan dan respons atau hanya permintaan dan respons yang memenuhi kriteria tertentu.
- Pilih bagian mana dari permintaan dan respons yang dicatat.
- Memungkinkan Anda untuk meredaksi informasi sensitif dari log.
Pengelogan HTTP dapat mengurangi performa aplikasi, terutama saat mencatat isi permintaan dan respons. Pertimbangkan dampak performa saat memilih bidang yang akan dicatat. Uji dampak performa dari properti log yang dipilih.
Warning
Pengelogan HTTP berpotensi mencatat informasi pengidentifikasi pribadi (PII). Pertimbangkan risikonya dan hindari pengelogan informasi sensitif. Untuk informasi selengkapnya tentang redaksi, periksa meredaksi data sensitif
Aktifkan pengelogan HTTP
Pengelogan HTTP diaktifkan dengan memanggil AddHttpLogging dan UseHttpLogging, seperti yang ditunjukkan dalam contoh berikut:
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();
Lambda kosong dalam contoh panggilan AddHttpLogging sebelumnya menambahkan middleware dengan konfigurasi default. Secara default, log pengelogan HTTP mencatat properti umum seperti jalur, kode status, dan header untuk permintaan dan respons.
Tambahkan baris berikut ke file appsettings.Development.json di tingkat "LogLevel": { sehingga log HTTP ditampilkan:
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
Dengan konfigurasi default, permintaan dan respons dicatat sebagai sepasang pesan yang mirip dengan contoh berikut:
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
Opsi pengelogan HTTP
Untuk mengonfigurasi opsi global untuk middleware pengelogan HTTP, panggil AddHttpLogging di Program.cs, menggunakan lambda untuk mengonfigurasi 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
Dalam sampel sebelumnya dan sampel berikut, UseHttpLogging dipanggil setelah UseStaticFiles, sehingga pengelogan HTTP tidak diaktifkan untuk file statis. Untuk mengaktifkan pengelogan HTTP file statis, panggil UseHttpLogging sebelum UseStaticFiles.
LoggingFields
HttpLoggingOptions.LoggingFields adalah bendera enum yang mengonfigurasi bagian tertentu dari permintaan dan respons terhadap log.
LoggingFields defaultnya adalah RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.
RequestHeaders dan ResponseHeaders
RequestHeaders dan ResponseHeaders merupakan set header HTTP yang dicatat. Nilai header hanya dicatat untuk nama header yang ada di koleksi ini. Kode berikut menambahkan sec-ch-ua ke RequestHeaders, sehingga nilai sec-ch-ua header dicatat. Dan menambahkan MyResponseHeader ke ResponseHeaders, sehingga nilai MyResponseHeader header dicatat. Jika baris ini dihapus, nilai header ini adalah [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 menyediakan konfigurasi untuk memilih pengodean mana yang akan digunakan untuk jenis media tertentu.
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();
Pendekatan ini juga dapat digunakan untuk mengaktifkan pengelogan untuk data yang tidak dicatat secara default (misalnya, data formulir, yang mungkin memiliki jenis media seperti application/x-www-form-urlencoded atau multipart/form-data).
Metode MediaTypeOptions
RequestBodyLogLimit dan 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
Pengaturan CombineLogs untuk true mengonfigurasi middleware untuk mengonsolidasikan semua log yang diaktifkan untuk permintaan dan respons ke dalam satu log di akhir. Ini termasuk permintaan, isi permintaan, respons, isi respons, dan durasi.
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();
Konfigurasi khusus titik akhir
Untuk konfigurasi khusus untuk endpoint pada aplikasi API minimal, tersedia metode ekstensi WithHttpLogging. Contoh berikut menunjukkan cara mengonfigurasi pengelogan HTTP untuk satu titik akhir:
app.MapGet("/response", () => "Hello World! (logging response)")
.WithHttpLogging(HttpLoggingFields.ResponsePropertiesAndHeaders);
Untuk konfigurasi khusus titik akhir di aplikasi yang menggunakan pengontrol, [HttpLogging] atribut tersedia. Atribut juga dapat digunakan dalam aplikasi API minimal, seperti yang ditunjukkan dalam contoh berikut:
app.MapGet("/duration", [HttpLogging(loggingFields: HttpLoggingFields.Duration)]
() => "Hello World! (logging duration)");
IHttpLoggingInterceptor
IHttpLoggingInterceptor adalah antarmuka untuk layanan yang dapat diimplementasikan untuk menangani panggilan balik per permintaan dan per respons untuk menyesuaikan detail apa yang dicatat. Setiap pengaturan log khusus titik akhir diterapkan terlebih dahulu dan kemudian dapat ditimpa dalam fungsi panggilan balik ini. Implementasi dapat:
- Periksa permintaan atau respons.
- Aktifkan atau nonaktifkan HttpLoggingFields.
- Sesuaikan berapa banyak isi permintaan atau respons yang dicatat.
- Tambahkan bidang kustom ke log.
IHttpLoggingInterceptor Daftarkan implementasi dengan memanggil AddHttpLoggingInterceptor di Program.cs. Jika beberapa IHttpLoggingInterceptor instans terdaftar, instans tersebut dijalankan dalam urutan terdaftar.
Contoh berikut menunjukkan cara mendaftarkan IHttpLoggingInterceptor implementasi:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.Duration;
});
builder.Services.AddHttpLoggingInterceptor<SampleHttpLoggingInterceptor>();
Contoh berikut adalah implementasi IHttpLoggingInterceptor yang:
- Memeriksa metode permintaan dan menonaktifkan pengelogan untuk permintaan POST.
- Untuk permintaan non-POST:
- Meredaksi jalur permintaan, header permintaan, dan header respons.
- Menambahkan bidang kustom dan nilai bidang ke log permintaan dan respons.
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");
}
}
Dengan pencegat ini, permintaan POST tidak menghasilkan log apa pun bahkan jika pengelogan HTTP dikonfigurasi untuk mencatat HttpLoggingFields.All. Permintaan GET menghasilkan log yang mirip dengan contoh berikut:
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
Urutan konfigurasi pengelogan prioritas
Daftar berikut menunjukkan urutan prioritas untuk konfigurasi pengelogan:
- Konfigurasi global dari HttpLoggingOptions, diatur dengan memanggil AddHttpLogging.
- Konfigurasi khusus titik akhir dari
[HttpLogging]atribut atau metode WithHttpLogging ekstensi menggantikan konfigurasi global. -
IHttpLoggingInterceptordipanggil dengan hasil dan dapat memodifikasi konfigurasi lebih lanjut per permintaan.
Pengelogan HTTP adalah middleware yang mencatat informasi tentang permintaan HTTP dan respons HTTP. Pengelogan HTTP menyediakan log dari:
- Informasi permintaan HTTP
- Properti umum
- Headers
- Body
- Informasi respons HTTP
Pengelogan HTTP berguna dalam beberapa skenario untuk:
- Mencatat informasi tentang permintaan dan respons yang masuk.
- Memfilter bagian mana dari permintaan dan respons yang dicatat.
- Memilih header mana yang akan dicatat.
Pengelogan HTTP dapat mengurangi performa aplikasi, terutama saat melakukan pengelogan badan permintaan dan respons. Pertimbangkan dampak performa saat memilih bidang yang akan dicatat. Uji dampak performa dari properti log yang dipilih.
Warning
Pengelogan HTTP berpotensi dapat mencatat informasi pengidentifikasi pribadi (PII). Pertimbangkan risikonya dan hindari pengelogan informasi sensitif.
Mengaktifkan pengelogan HTTP
Pengelogan HTTP diaktifkan dengan UseHttpLogging, yang menambahkan middleware pengelogan 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();
Secara default, Pengelogan HTTP mencatat properti umum seperti jalur, kode status, dan header untuk permintaan dan respons. Tambahkan baris berikut ke file appsettings.Development.json di tingkat "LogLevel": { sehingga log HTTP ditampilkan:
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
Outputnya dicatat sebagai satu pesan di LogLevel.Information.
Opsi Pengelogan HTTP
Untuk mengonfigurasi middleware pengelogan HTTP, panggil AddHttpLogging di 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
Dalam sampel sebelumnya dan sampel berikut, UseHttpLogging dipanggil setelah UseStaticFiles, sehingga pengelogan HTTP tidak diaktifkan untuk file statis. Untuk mengaktifkan pengelogan HTTP file statis, panggil UseHttpLogging sebelum UseStaticFiles.
LoggingFields
HttpLoggingOptions.LoggingFields adalah bendera enum yang mengonfigurasi bagian tertentu dari permintaan dan respons terhadap log.
HttpLoggingOptions.LoggingFields defaultnya adalah RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders.
RequestHeaders
Headers adalah sekumpulan Header Permintaan HTTP yang diizinkan untuk dicatat. Nilai header hanya dicatat untuk nama header yang ada di koleksi ini. Kode berikut mencatat header permintaan "sec-ch-ua". Jika logging.RequestHeaders.Add("sec-ch-ua"); dihapus, nilai header permintaan "sec-ch-ua" akan dihapus. Kode yang disorot berikut memanggil HttpLoggingOptions.RequestHeaders dan 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 menyediakan konfigurasi untuk memilih pengodean mana yang akan digunakan untuk jenis media tertentu.
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();
Pendekatan ini juga dapat digunakan untuk mengaktifkan pengelogan untuk data yang tidak dicatat secara default. Misalnya, data formulir, yang mungkin memiliki jenis media seperti application/x-www-form-urlencoded atau multipart/form-data.
Metode MediaTypeOptions
RequestBodyLogLimit dan 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();
Menyunting data sensitif
Pencatatan HTTP dengan penyuntingan dapat diaktifkan dengan memanggil AddHttpLoggingRedaction:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
logging.LoggingFields = HttpLoggingFields.Duration;
});
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op => { });
Untuk informasi selengkapnya tentang pustaka penyuntingan data .NET, lihat penyuntingan data di .NET.
Opsi redaksi pengelogan
Untuk mengonfigurasi opsi pencatatan dengan redaksi, panggil AddHttpLoggingRedaction di Program.cs dengan menggunakan lambda untuk mengonfigurasi LoggingRedactionOptions:
using Microsoft.Extensions.Compliance.Classification;
namespace HttpLoggingSample
{
public static class MyTaxonomyClassifications
{
public static string Name => "MyTaxonomy";
public static DataClassification Private => new(Name, nameof(Private));
public static DataClassification Public => new(Name, nameof(Public));
public static DataClassification Personal => new(Name, nameof(Personal));
}
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(o => { });
builder.Services.AddRedaction();
builder.Services.AddHttpLoggingRedaction(op =>
{
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
{
{ "one", MyTaxonomyClassifications.Personal },
};
// Add the paths that should be filtered, with a leading '/'.
op.ExcludePathStartsWith.Add("/home");
op.IncludeUnmatchedRoutes = true;
});
var app = builder.Build();
app.UseHttpLogging();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.MapGet("/", () => "Logged!");
app.MapGet("/home", () => "Not logged!");
app.Run();
Dengan konfigurasi redaksi sebelumnya, outputnya mirip dengan yang berikut ini:
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
Jalur /home permintaan tidak dicatat karena termasuk dalam ExcludePathStartsWith atribut.
http.request.header.accept dan http.response.header.content-type diredaksi oleh Microsoft.Extensions.Compliance.Redaction.ErasingRedactor.
RequestPathLoggingMode
RequestPathLoggingMode menentukan bagaimana jalur permintaan dicatat, baik Formatted atau Structured, yang ditetapkan oleh IncomingPathLoggingMode:
-
Formatted: Mencatat jalur permintaan tanpa parameter. -
Structured: Mencatat jalur permintaan dengan parameter yang disertakan.
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 menentukan bagaimana parameter rute dalam jalur permintaan harus diredaksi, baik Strict, , Looseatau None, yang ditetapkan oleh HttpRouteParameterRedactionMode:
-
Strict: Parameter rute permintaan dianggap sensitif, memerlukan anotasi eksplisit dengan klasifikasi data, dan diredaksi secara default. -
Loose: Semua parameter dianggap tidak sensitif dan disertakan as-is secara default. -
None: Parameter rute tidak diredaksi terlepas dari adanya anotasi klasifikasi data.
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 memetakan header permintaan ke klasifikasi data mereka, yang menentukan bagaimana header tersebut diredaksi:
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, mirip dengan RequestHeadersDataClasses, tetapi untuk header respons:
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 memetakan parameter rute ke klasifikasi data mereka:
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 menentukan jalur yang harus dikecualikan dari pengelogan sepenuhnya:
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 memungkinkan pelaporan rute yang tidak cocok. Jika diatur ke true, mencatat seluruh jalur dari rute yang tidak diidentifikasi oleh Perutean alih-alih mencatat nilai Unknown untuk atribut jalur:
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();
ASP.NET Core