在 Spring 应用程序中记录容器启动时的静止端点

Posted

技术标签:

【中文标题】在 Spring 应用程序中记录容器启动时的静止端点【英文标题】:Log restful endpoints on container startup in a Spring application 【发布时间】:2016-11-15 22:43:34 【问题描述】:

我有一个 Spring 应用程序,它通过 Controller 类中的 @RequestMapping 注解公开 restful 端点。

我希望在服务器启动时,所有应用程序控制器的所有端点都登录到控制台。

我使用 tomcat 服务器和 log4j 进行日志记录。

谢谢。

【问题讨论】:

【参考方案1】:

对于使用 spring-boot 的人:

在最新的 spring-boot 版本(自 v2.1 起)中,他们更改了映射默认日志级别(如发行说明 here 中所述)。

将以下属性之一添加到 application.properties 文件:

logging.level.web=TRACE logging.level.org.springframework.web=TRACE

控制台输出示例:

2018-12-12 11:16:51.793 TRACE 11868 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping
    c.n.c.MyController:
    POST /users: addUser(User)
    DELETE /users: deleteUser(User)
    PUT /users: updateUser(User)
    GET /users/id: getUserById(String)
    GET /users: getUsers()
    GET /users_static: getUsersStaticList()
2018-12-12 11:16:51.795 TRACE 11868 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping
    o.s.b.a.w.s.e.BasicErrorController:
     /error: error(HttpServletRequest)
     /error, produces [text/html]: errorHtml(HttpServletRequest,HttpServletResponse)

【讨论】:

实际上没有任何属性适用于 Spring Boot 2.1.4。只有在我将此行添加到我的 logback.xml 之后,我才在控制台中看到了我的端点: 虽然这可行,但要小心,因为它还会在运行时在 TRACE 上记录更多内容——这是您在生产系统中可能不想要的。对我来说,下面带有执行器映射端点的提示是我真正需要的:***.com/a/40621584/1326662【参考方案2】:

在 log4J 中,添加 info 日志级别 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping类。

同级别INFO

log4j.category.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=INFO

你应该有这种信息(行被截断):

2016-11-15 23:34:30.040  INFO 10156 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/api/contacts/id],methods=[GET],produces=[application/json]" o
2016-11-15 23:34:30.040  INFO 10156 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/api/contacts/id],methods=[DELETE],produces=[application/json]
2016-11-15 23:34:30.040  INFO 10156 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/api/contacts],methods=[POST],consumes=[application/json],produce
2016-11-15 23:34:30.040  INFO 10156 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/api/contacts/id],methods=[PUT],consumes=[application/json],pro
2016-11-15 23:34:30.040  INFO 10156 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/api/contacts],methods=[GET],produces=[application/json]" onto p
2016-11-15 23:34:30.040  INFO 10156 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/api/contacts/search],methods=[GET],params=[group-id],produces=[a

更新

自 Spring MVC 5.1/Spring Boot 2 以来,日志记录策略发生了变化。 现在使用INFO 级别记录的信息很少,DEBUG 级别提供了更多信息但并不详细。 只有TRACE 级别会提供详细信息。

这是changelog(重点是我的):

日志修订:

标准的 Commons Logging 可以检测 Spring 的 JCL 桥接器。

信息噪音小、调试日志可读、跟踪级别的详细信息

因此以这种方式更改日志记录配置以列出所有映射:

Log4J 属性方式:

log4j.category.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=TRACE

回退方式:

<logger level="TRACE" name="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

【讨论】:

它可以工作,但是它也会因应用程序中的任何请求而导致进一步的日志污染。 “RequestMappingHandlerMapping - 映射到...” 报告了一个问题github.com/spring-projects/spring-framework/issues/26539【参考方案3】:

要添加到Spring Boot 中的上一个答案,还有Actuator,其中公开了一个名为mappings 的专用Endpoint,可在/mappings 下访问。

【讨论】:

【参考方案4】:

从 Spring 5.3.5 开始,可以使用特殊的专用隐藏 Logger 来记录端点映射,而无需记录所有请求处理的开销。

<Logger name="_org.springframework.web.servlet.HandlerMapping.Mappings" level="debug" additivity = "false">

此功能在https://github.com/spring-projects/spring-framework/issues/26539中引入

【讨论】:

servlet 映射和过滤器映射是否还有隐藏的记录器?较早的 Spring 版本在信息级别记录这些映射(来自 ServletRegistrationBeanFilterRegistrationBean)。 @Pino 我可以通过查询 github.com/spring-projects/spring-framework/… 搜索 - 没有。也许更深入地检查 Spring 框架代码或文档可以帮助找到这些

以上是关于在 Spring 应用程序中记录容器启动时的静止端点的主要内容,如果未能解决你的问题,请参考以下文章

Spring容器启动过程

spring cloud使用做消费端时的eureka.client.registerWithEureka/eureka.client.fetchRegistry是否配置的问题

从Servlet开始谈Spring框架的启动原理

8 -- 深入使用Spring -- 7...1 启动Spring 容器

web项目启动Spring容器

web项目启动Spring容器