簡體   English   中英

spring boot框架下如何過濾tomcat生成的訪問日志

[英]How to filter access logs generated by tomcat under spring boot framework

我們使用的是spring boot框架,通過內嵌的tomcat生成訪問日志,訪問日志的格式如下屬性:

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

幸運的是,訪問日志生成成功,我們得到了肯定的結果:

"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"

為了確保服務健康,我們一直每 5 秒運行一次健康檢查,我們要過濾的請求以便我們可以獲得清晰的訪問日志,健康檢查 url 如下示例:

"127.0.0.1 - - [01/Mar/2016:12:04:10 +0800] 'GET /school-svc/isHealth HTTP/1.1' 200 6 104"

如何過濾健康檢查請求?

感謝幫助。


根據訪問日志的文檔,我嘗試使用conditionIf來解決問題,在我們的spring框架中,我嘗試覆蓋EmbeddedServletContainerCustomizer類中的customize函數,以便可以設置conditionIf,我們的實現如下示例:

 @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");
            }
      }    
}

在我的理解中,下一步我們需要做的是設置屬性參數,所以我在健康檢查控制器上面寫了攔截器,實現如下:

@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());
        }
    }
}

最后,檢查是否評估了 RequestServlet 的屬性(“忽略”)。

@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;
    }
}

輸出:忽略屬性為真

但是,在訪問日志中仍然可以找到健康檢查的訪問通知:

"127.0.0.1 - - [03/Mar/2016:11:34:00 +0800] 'GET /home-svc/isHealth HTTP/1.1' 200 6 120"

我假設屬性參數“忽略”在過程后期設置,何時以及如何為 HttpServletRequest 設置屬性?

如果我們的假設不正確,是什么導致操作不起作用?

感謝幫助。

正如響應https://stackoverflow.com/a/55569199/3346298在這個問題Exclude某些 requests from Tomcat's log所建議的那樣,您應該使用過濾器並將此過濾器添加到 filterChain 而不是通過 AOP 添加它。

出於同樣的原因,似乎在執行 AOP 方面之前檢查了日志/非日志功能。

PD:抱歉回復晚了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM