Spring Boot - 如何在一个地方记录所有请求和异常响应?

2022-08-31 04:58:17

我正在开发带有弹簧启动的REST API。我需要使用输入参数记录所有请求(例如,使用方法。GET、POST 等),请求路径、查询字符串、此请求的对应类方法,以及此操作的响应,既有成功也有错误。例如:

请求成功:

http://example.com/api/users/1

日志应如下所示:

{
   HttpStatus: 200,
   path: "api/users/1",
   method: "GET",
   clientIp: "0.0.0.0",
   accessToken: "XHGu6as5dajshdgau6i6asdjhgjhg",
   method: "UsersController.getUser",
   arguments: {
     id: 1 
   },
   response: {
      user: {
        id: 1,
        username: "user123",
        email: "user123@example.com"   
      }
   },
   exceptions: []       
}

请求有错误:

http://example.com/api/users/9999

日志应如下所示:

{
   HttpStatus: 404,
   errorCode: 101,                 
   path: "api/users/9999",
   method: "GET",
   clientIp: "0.0.0.0",
   accessToken: "XHGu6as5dajshdgau6i6asdjhgjhg",
   method: "UsersController.getUser",
   arguments: {
     id: 9999 
   },
   returns: {            
   },
   exceptions: [
     {
       exception: "UserNotFoundException",
       message: "User with id 9999 not found",
       exceptionId: "adhaskldjaso98d7324kjh989",
       stacktrace: ...................    
   ]       
}

我希望请求/响应是单个实体,在成功和错误情况下都具有与此实体相关的自定义信息。

在春季实现这一目标的最佳实践是什么,可能是用过滤器?如果是,你能提供具体的例子吗?

我已经玩过 和 ,但正如我所提到的,我需要在一个地方(和单个日志)处理所有成功和错误请求。@ControllerAdvice@ExceptionHandler


答案 1

不要编写任何拦截器,过滤器,组件,方面等,这是一个非常普遍的问题,并且已经解决了很多次。

Spring Boot有一个名为Dector的模块,它提供了开箱即用的HTTP请求日志记录。有一个映射到 (SB1.x) 或 (SB2.0+) 的终结点,它将显示最近 100 个 HTTP 请求。您可以对其进行自定义以记录每个请求或写入数据库。/trace/actuator/httptrace

要获取所需的端点,您需要 spring-boot-starter-actuator 依赖项,还需要将您要查找的端点“列入白名单”,并可能为其设置或禁用安全性。

另外,此应用程序将在哪里运行?您会使用 PaaS 吗?托管服务提供商,例如Heroku,提供请求日志记录作为其服务的一部分,您无需进行任何编码


答案 2

Spring已经提供了一个过滤器来完成这项工作。将以下 Bean 添加到您的配置中

@Bean
public CommonsRequestLoggingFilter requestLoggingFilter() {
    CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
    loggingFilter.setIncludeClientInfo(true);
    loggingFilter.setIncludeQueryString(true);
    loggingFilter.setIncludePayload(true);
    loggingFilter.setMaxPayloadLength(64000);
    return loggingFilter;
}

不要忘记将 的日志级别更改为 。org.springframework.web.filter.CommonsRequestLoggingFilterDEBUG


推荐