代码之家  ›  专栏  ›  技术社区  ›  Fencer

为什么春天不和我说话?(或:如何正确配置Spring日志?)

  •  4
  • Fencer  · 技术社区  · 7 年前

    我的实际问题是Spring安全性和为身份验证服务器配置OAuth2,但为了跟踪我的问题,我希望Spring告诉我当请求到达端点时实际发生了什么。我正在使用Spring Boot 2.0.0-SNAPSHOT和日志启动器 spring-boot-starter-log4j2 实际上,它似乎工作得很好。我的log4j2配置为:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE Configuration>
    <Configuration status="WARN">
      <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
          <PatternLayout pattern="%-5level%d{MMM dd, yyyy HH:mm:ss.SSS} [%t] %X %logger{36}%n  %msg%n"/>
        </Console>
      <File name="File" fileName="logs/application.log">
        <PatternLayout pattern="%-5level%d{MMM dd, yyyy HH:mm:ss.SSS} [%t] %X %logger{36} %msg%n"/>
      </File>
      </Appenders>
      <Loggers>    
        <Root level="debug">
          <AppenderRef ref="Console"/>
          <AppenderRef ref="File"/>
        </Root>
        <logger name="org.springframework" level="debug" additivity="false">
          <AppenderRef ref="Console"/>
          <AppenderRef ref="File"/>
        </logger>
        <logger name="org.springframework.security" level="debug" additivity="false">
          <AppenderRef ref="Console"/>
          <AppenderRef ref="File"/>
        </logger>
        <logger name="org.hibernate" level="info" additivity="false">
          <AppenderRef ref="Console"/>
          <AppenderRef ref="File"/>
        </logger>
      </Loggers>
    </Configuration>
    

    在启动应用程序(嵌入式Tomcat)时,我可以看到实际上使用了配置,Spring在这个过程中记录了很多东西:

    ...
    INFO Feb 02, 2018 11:31:00.295 [restartedMain] {} org.hibernate.type.BasicTypeRegistry
      HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@41229bd4
    INFO Feb 02, 2018 11:31:00.345 [restartedMain] {} org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
      Initialized JPA EntityManagerFactory for persistence unit 'default'
    DEBUG Feb 02, 2018 11:31:00.440 [restartedMain] {} org.springframework.data.jpa.repository.query.JpaQueryFactory
      Looking up query for method findByEmail
    ...
    

    但是,当我向应用程序发送请求以获取接收到4xx错误的Oauth2访问令牌时,我希望Spring告诉我它是怎么做的,以便我可以找到我的配置错误。但它不会记录任何内容。我看到了冬眠的东西和我自己的日志,但春天依然沉默。由于跟踪配置,我预计会有很多消息。

    谁能想象我做错了什么?还是春天根本不爱说话?

    2018年8月2日更新:
    看来,我的问题必然与春天的安全有关。我做了一些调试,找到了Spring Security和框架其他部分的不同记录器。
    例如,在 org.springframework.data.jpa.repository.query.JpaQueryFactory Spring正在使用记录器 org.apache.logging.slf4j.Log4jLogger (在我的配置中设置为DEBUG),但Spring security使用 org.apache.commons.logging.impl.Jdk14Logger 例如,在 org.springframework.security.web.FilterChainProxy (尽管我配置了log4j2,但它还是设置为INFO)。

    所以我试着调试代码 FilterChainProxy 已分配。但不幸的是,代码要么从未到达,要么我的断点不起作用。我想这是第二个。

    2 回复  |  直到 7 年前
        1
  •  5
  •   Fencer    7 年前

    我自己找到了问题的原因:
    弹簧广泛使用 slf4J 用于日志记录。为此,我在我的项目中包括了一个桥接器,它工作得非常好,并生成了问题中的日志输出。
    但是Spring安全性(可能还有Spring的其他部分)使用 Apache Commons日志记录 这本身就没有问题 弹簧5 随附 春天jcl公司 其中一座桥 Apache Commons日志记录 日志4J2 .
    但这里有一件可怕的事情:我引入了另一个库,它对 通用日志记录 因此,我将“Apache Commons Logging”的直接实现纳入了我的项目中。所以我有两个不同的 org.apache.commons.logging.LogFactory 我的类路径中的类。Spring security决定在中使用该实现 公用日志记录 而不是 弹簧jcl 当然,因此我的log4j配置不会影响Spring security的记录器。

    实际上我所要做的就是排除 公用日志记录 在我的构建文件中 弹簧jcl 再做一次。

        2
  •  0
  •   secondbreakfast    7 年前

    一种选择是扩展 DefaultAuthenticationEventPublisher 这将使您连接到身份验证成功/失败。当然,您可以用自己的日志记录替换打印语句。

    @Component
    public class CustomAuthenticationEventPublisher extends DefaultAuthenticationEventPublisher {
    
        @Override
        public void publishAuthenticationSuccess(Authentication authentication) {
            super.publishAuthenticationSuccess(authentication);
            System.out.println("AUTH SUCCESS " + authentication);
        }
    
        @Override
        public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) {
            super.publishAuthenticationFailure(exception, authentication);
            System.out.println("AUTH ERROR " + exception.getLocalizedMessage());
        }
    }