You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为指定控制器记录HTTP请求?能否通过自定义中间件实现?

实现指定控制器的HTTP请求日志记录

一、自定义中间件完全可以实现需求

核心思路是用自定义特性标记需要日志的控制器/Action,再在中间件里判断标记,选择性执行日志逻辑,完美适配未来扩展。

1. 先做标记:自定义特性

定义一个特性,用来标记需要记录请求的控制器或单个Action:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class LogHttpRequestAttribute : Attribute
{
}

2. 编写中间件:判断标记并记录日志

在中间件里读取当前请求的路由信息,检查是否带有上面的特性,再决定是否记录HTTP请求:

public class HttpRequestLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<HttpRequestLoggingMiddleware> _logger;

    public HttpRequestLoggingMiddleware(RequestDelegate next, ILogger<HttpRequestLoggingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 从端点元数据里检查是否有日志标记
        var endpoint = context.GetEndpoint();
        var needLog = endpoint?.Metadata.GetMetadata<LogHttpRequestAttribute>() != null;

        if (needLog)
        {
            // 读取并记录请求核心信息:方法、路径、Query、请求体
            context.Request.EnableBuffering();
            using var reader = new StreamReader(context.Request.Body, leaveOpen: true);
            var requestBody = await reader.ReadToEndAsync();
            context.Request.Body.Position = 0;

            _logger.LogInformation("HTTP Request: {Method} {Path}, Query: {Query}, Body: {Body}",
                context.Request.Method,
                context.Request.Path,
                context.Request.QueryString,
                requestBody);
        }

        // 继续执行后续请求管道
        await _next(context);
    }
}

3. 注册中间件+标记目标控制器

在Program.cs里注册中间件:

app.UseMiddleware<HttpRequestLoggingMiddleware>();

给需要日志的控制器/Action加特性即可:

// 给整个控制器加日志
[LogHttpRequest]
public class OrderController : ControllerBase
{
    // ... 控制器逻辑
}

// 给单个Action加日志
public class UserController : ControllerBase
{
    [LogHttpRequest]
    public IActionResult GetUserDetail(int id)
    {
        // ...
    }
}

后续要给新控制器加日志,直接加特性就行,不用改中间件代码。

二、现成工具推荐

如果不想自己写中间件,这些成熟日志库支持按控制器/Action过滤:

  • Serilog:可以通过过滤规则匹配路由或自定义特性。比如在配置里指定只记录特定路径的请求:
"Serilog": {
  "Filter": [
    {
      "Name": "ByIncludingOnly",
      "Args": {
        "expression": "RequestPath like '/order/%' or RequestPath like '/user/getuserdetail'"
      }
    }
  ]
}

也可以结合自定义特性,通过Enrich把特性信息加入日志上下文后再过滤。

  • NLog:通过配置文件的rules节点,用filter匹配控制器名称或路由,实现精准日志记录。

三、结合已有的DTO日志

你已经实现了DTO日志,可以用关联ID把HTTP请求日志和DTO日志绑定,方便后续排查:

  1. 在中间件里生成关联ID并存入HttpContext:
var correlationId = Guid.NewGuid().ToString();
context.Items["CorrelationId"] = correlationId;
_logger.LogInformation("HTTP Request [CorrelationId: {Id}]: ...", correlationId);
  1. 在DTO日志逻辑里取出关联ID一起记录:
var correlationId = HttpContext.Items["CorrelationId"]?.ToString();
_logger.LogInformation("Received DTO [CorrelationId: {Id}]: {DtoContent}", correlationId, JsonSerializer.Serialize(dto));

内容的提问来源于stack exchange,提问作者ducksauce88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 10:10:49