ASP.NET Core 中的 HTTP 日志记录

HTTP 日志记录是一种中间件,用于记录传入 HTTP 请求和 HTTP 响应的相关信息。 HTTP 日志记录可以记录:

  • HTTP 请求信息
  • 公共属性
  • 标头
  • 正文
  • HTTP 响应信息

在以下几种方案中,HTTP 日志记录很有价值:

  • 记录传入请求和响应的相关信息。
  • 筛选请求和响应的哪些部分被记录。
  • 筛选要记录的头。

HTTP 日志记录可能会降低应用的性能,尤其是在记录请求和响应正文时。 在选择要记录的字段时请考虑性能影响。 测试所选日志记录属性的性能影响。

警告

HTTP 日志记录可能会记录个人身份信息 (PII)。 请考虑风险,并避免记录敏感信息。

启用 HTTP 日志记录

HTTP 日志记录是通过 UseHttpLogging 启用,它添加了 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();

HTTP 日志记录默认记录路径、状态代码以及请求头和响应头等常用属性。 将以下行添加到 "LogLevel": { 级别的 appsettings.Development.json 文件,以便显示 HTTP 日志:

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

输出作为单条消息记录在 LogLevel.Information 上。

示例请求输出

HTTP 日志记录选项

若要配置 HTTP 日志记录中间件,请在 Program.cs 中调用 AddHttpLogging

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

LoggingFields

HttpLoggingOptions.LoggingFields 是一个枚举标志,用于配置要记录的请求和响应的特定部分。 HttpLoggingOptions.LoggingFields 默认为 RequestPropertiesAndHeaders | ResponsePropertiesAndHeaders

RequestHeaders

Headers 是一组可以记录的 HTTP 请求头。 只记录此集合中的头名称的头值。 以下代码记录请求头 "sec-ch-ua"。 如果删除 logging.RequestHeaders.Add("sec-ch-ua");,则修订请求头 "sec-ch-ua" 的值。 以下突出显示的代码调用 HttpLoggingOptions.RequestHeadersHttpLoggingOptions.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 提供了选择要用于特定媒体类型的编码的配置。

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 方法

RequestBodyLogLimitResponseBodyLogLimit

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