AOP與Filter攔截請求列印日誌實用例子

來源:互聯網
上載者:User

相信各位同道在寫代碼的時候,肯定會寫一些日誌列印,因為這對往後的營運而言,至關重要的。

那麼我們請求一個restfull介面的時候,哪些資訊是應該被日誌記錄的呢?

以下做了一個基本的簡單例子,這裡只是樣本說明基本常規實現記錄的資訊,根據項目的真實情況選用 : 

1 . Http請求攔截器(Filter) : 從 HttpServletRequest擷取基本的請求資訊

import name.ealen.util.HttpUtil;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.annotation.Order;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * Created by EalenXie on 2018/9/7 15:56. * Http請求攔截器,日誌列印請求基本相關資訊 */@Configurationpublic class FilterConfiguration {    private static final Logger log = LoggerFactory.getLogger(FilterConfig.class);    @Bean    @Order(Integer.MIN_VALUE)    @Qualifier("filterRegistration")    public FilterRegistrationBean filterRegistration() {        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();        registration.setFilter(controllerFilter());        registration.addUrlPatterns("/*");        return registration;    }    private Filter controllerFilter() {        return new Filter() {            @Override            public void init(FilterConfig filterConfig) {                log.info("ControllerFilter init Success");            }            @Override            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {                HttpServletRequest request = (HttpServletRequest) servletRequest;                HttpServletResponse response = (HttpServletResponse) servletResponse;                String requestId = request.getHeader("Request-Id");                if (requestId == null) requestId = request.getRequestedSessionId();                System.out.println();                log.info("Http Request Request-Id : " + requestId);                log.info("Http Request Information : {\"URI\":\"" + request.getRequestURL() +                        "\",\"RequestMethod\":\"" + request.getMethod() +                        "\",\"ClientIp\":\"" + HttpUtil.getIpAddress(request) +                        "\",\"Content-Type\":\"" + request.getContentType() +                        "\"}");                chain.doFilter(request, response);            }            @Override            public void destroy() {                log.info("ControllerFilter destroy");            }        };    }}

2 . Controller的攔截AOP : 擷取 請求的對象,請求參數,返回資料,請求返回狀態,內部方法耗時。

import com.alibaba.fastjson.JSON;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.core.env.Environment;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Component;import javax.annotation.Resource;/** * Created by EalenXie on 2018/9/7 14:19. * AOP列印日誌 : 請求的對象,請求參數,返回資料,請求狀態,內部方法耗時 */@Aspect@Componentpublic class ControllerInterceptor {    private static final Logger log = LoggerFactory.getLogger(ControllerInterceptor.class);    @Resource    private Environment environment;    @Around(value = "execution (*  name.ealen.web.*.*(..))")    public Object processApiFacade(ProceedingJoinPoint pjp) {        String appName;        try {            appName = environment.getProperty("spring.application.name").toUpperCase();        } catch (Exception e) {            appName = "UNNAMED";        }        long startTime = System.currentTimeMillis();        String name = pjp.getTarget().getClass().getSimpleName();        String method = pjp.getSignature().getName();        Object result = null;        HttpStatus status = null;        try {            result = pjp.proceed();            log.info("RequestTarget : " + appName + "." + name + "." + method);            log.info("RequestParam : " + JSON.toJSON(pjp.getArgs()));            if (result instanceof ResponseEntity) {                status = ((ResponseEntity) result).getStatusCode();            } else {                status = HttpStatus.OK;            }        } catch (Throwable throwable) {            status = HttpStatus.INTERNAL_SERVER_ERROR;            result = new ResponseEntity<>("{\"Internal Server Error\" : \"" + throwable.getMessage() + "\"}", status);            throwable.printStackTrace();        } finally {            log.info("ResponseEntity : {" + "\"HttpStatus\":\"" + status.toString() + "\"" + ",\"ResponseBody\": " + JSON.toJSON(result) + "}");            log.info("Internal Method Cost Time: {}ms", System.currentTimeMillis() - startTime);        }        return result;    }}

3 . 提供一個簡單的restfull介面 : 

package name.ealen.web;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * Created by EalenXie on 2018/9/7 14:24. */@RestControllerpublic class SayHelloController {    @RequestMapping("/sayHello")    public String sayHello() {        return "hello world";    }    @RequestMapping("/say")    public ResponseEntity<?> say(@RequestBody Object o) {        return new ResponseEntity<>(o, HttpStatus.OK);    }}

4 . 使用Postman進行基本測試 : 

5 . 控制台可以看到基本效果 : 

 

 以上只是關於Controller應該記錄日誌的一個簡單的例子,完整代碼可見 github.com/EalenXie/springboot-controller-logger

感謝各位提出意見和支援。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.