问题
We are using spring boot framework, generating access logs by embedded tomcat, the format of access logs is following the property below :
server.tomcat.access-log-enabled=true
server.tomcat.access-log-pattern="%h %l %u %t '%r' %s %b %D"
server.tomcat.basedir=/data/logs/Waijule/SchoolService/access
Fortunately, access logs generated succeed, we got a positive result :
"127.0.0.1 - - [01/Mar/2016:11:25:47 +0800] 'POST /school-svc/index-summary HTTP/1.1' 200 127 21"
"127.0.0.1 - - [01/Mar/2016:11:25:47 +0800] 'POST /school-svc/wechat/signature/get HTTP/1.1' 200 238 9"
"127.0.0.1 - - [01/Mar/2016:11:25:47 +0800] 'POST /school-svc/wechat/ticket/get HTTP/1.1' 200 225 148"
To make sure the service healthy, we have kept running health check every 5 seconds, the requests which we want to filter so that we could get clear access logs, health check url is like the sample :
"127.0.0.1 - - [01/Mar/2016:12:04:10 +0800] 'GET /school-svc/isHealth HTTP/1.1' 200 6 104"
How to filter health check requests?
Thanks for help.
According to documentation on access loging, I tried to use conditionIf to solve the problems, in our spring framework, I tried to override customize function in EmbeddedServletContainerCustomizer class so that conditionIf could set up, our realization likes the following sample :
@Configuration
public class Application implements EmbeddedServletContainerCustomizer {
@Override
public void customize(ConfigurableEmbeddedServletContainer container)
{
if (container instanceof TomcatEmbeddedServletContainerFactory)
{
log.debug("It is TomcatEmbeddedServletContainerFactory");
TomcatEmbeddedServletContainerFactory factory = (TomcatEmbeddedServletContainerFactory) container;
AccessLogValve accessLogValve = new AccessLogValve();
accessLogValve.setConditionIf("ignore");
factory.addContextValves(accessLogValve);
}
else
{
log.error("WARNING! this customizer does not support your configured container");
}
}
}
In my comprehension, the next step we need to do is set attribute parameter, so I wrote interceptor on the above of health check controller, realization likes that:
@Component
@Aspect
public class HealthCheckInterceptor
{
@Before("execution(* com.waijule.home.controller.HealthCheckController.process(..))")
private void beforeGetHomeDetailByHomeIdWithTry(JoinPoint joinPoint)
{
try
{
Object[] args = joinPoint.getArgs();
Prediction.checkTrue(args[0] instanceof HttpServletRequest);
HttpServletRequest request = (HttpServletRequest) args[0];
request.setAttribute("ignore", "true");
}
catch (Exception e)
{
log.error(e.getMessage());
}
}
}
In the end, checked if attribute("ignore") of RequestServlet evaluated.
@RestController
@RequestMapping(value = { "/home-svc/isHealth" }, method = { RequestMethod.GET, RequestMethod.HEAD })
public class HealthCheckController
{
private String HEALTH = "health";
@RequestMapping
public String process(HttpServletRequest request)
{
log.debug("ignore attribute is {}", request.getAttribute("ignore"));
return HEALTH;
}
}
output: ignore attribute is true
However, access informs of health check still be found in access logs:
"127.0.0.1 - - [03/Mar/2016:11:34:00 +0800] 'GET /home-svc/isHealth HTTP/1.1' 200 6 120"
I supposed attribute parameter 'ignore' set up late in the process, when and how to setAttribute for HttpServletRequest?
If our supposition not correct, what makes the operations not work?
Thanks for help.
来源:https://stackoverflow.com/questions/35714626/how-to-filter-access-logs-generated-by-tomcat-under-spring-boot-framework