logback-access的过滤器使用IAccessEvent而不是Janino

根据https://stackoverflow.com/questions/44710219/my-evaluatorfilter-doesnt-work-in-spring-boot-logback-access-xml上所述,在logback-access.xml中,需要使用AccessEvent而不是JaninoEventEvaluator来编写filter的表达式。因此,启动时会出现类似以下的错误消息。

20:46:19,031 |-ERROR in ch.qos.logback.access.boolex.JaninoEventEvaluator@7779f32e - Could not start evaluator with expression [return formattedMessage.contains("/hoge");] org.codehaus.commons.compiler.CompileException: Line 1, Column 25: Unknown variable or type "formattedMessage"
	at org.codehaus.commons.compiler.CompileException: Line 1, Column 25: Unknown variable or type "formattedMessage"
plugins {
  id 'java'
  id 'org.springframework.boot' version '3.0.5'
  id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
  mavenCentral()
}

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-web'
  implementation 'org.codehaus.janino:janino'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
  
  developmentOnly 'org.springframework.boot:spring-boot-devtools'
  implementation 'ch.qos.logback:logback-access'
}

tasks.named('test') {
  useJUnitPlatform()
}
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import ch.qos.logback.access.tomcat.LogbackValve;

@Configuration
public class LogbackAccessConfig {

  @Bean
  public WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory> webServerFactoryCustomizer() {
    return (factory) -> {
      LogbackValve v = new LogbackValve();
      // v.setFilename(new ClassPathResource("logback-access.xml").getPath());
      factory.addEngineValves(v);
    };
  }
}

以下是 src/main/resources/conf/logback-access.xml 的示例。如果URL中包含 /hoge,则不输出访问日志。事件的输出将使用 ch.qos.logback.access.spi.AccessEvent。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
      <evaluator>
        <expression>
        System.out.println(event);
        return (event.getRequestURL().contains("/hoge"));</expression>
      </evaluator>
      <OnMatch>DENY</OnMatch>
    </filter>
    <encoder>
      <Pattern>combined</Pattern>
      <Pattern>[ACCESS] %h %l %u %r %t{yyyy-MM-dd HH:mm:ss.SSS} %s %b %D ms</Pattern>
    </encoder>
  </appender>

  <appender-ref ref="STDOUT" />
</configuration>
bannerAds