項目中通常有記錄請求日志的需求,可以通過 AOP、Filter來實現,而 Spring web 也提供了 CommonsRequestLoggingFilter 來進行簡單的請求日志記錄,下面來使用CommonsRequestLoggingFilter進行請求日志記錄
先來編寫一個測試用的 Controller:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class TestController {
@GetMapping("get")
public Map<String, Object> testGet(String p1, Integer p2) {
return Map.of("p1", p1, "p2", p2);
}
@PostMapping("post")
public Map<String, Object> testGet(@RequestBody Map<String, Object> map) {
return map;
}
}
編寫配置 創建 CommonsRequestLoggingFilter
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CommonsRequestLoggingFilter;
@Configuration
public class AppConfig {
@Bean
public CommonsRequestLoggingFilter requestLoggingFilter() {
CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
loggingFilter.setIncludeHeaders(true);
loggingFilter.setIncludeClientInfo(true);
loggingFilter.setIncludeQueryString(true);
loggingFilter.setIncludePayload(true);
loggingFilter.setMaxPayloadLength(2000);
return loggingFilter;
}
}
現在訪問接口還不會有日志輸出,從 CommonsRequestLoggingFilter 的源碼可以看出,日志是在 debug 級別下輸出,所以需要配置 CommonsRequestLoggingFilter 的日志級別。
在 application.properties 中添加:
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=debug
現在訪問接口,可以看到有下面信息輸出:
Before request [GET /get?p1=p1&p2=12345, client=0:0:0:0:0:0:0:1, headers=[...]]
After request [GET /get?p1=p1&p2=12345, client=0:0:0:0:0:0:0:1, headers=[...]]
headers 中的內容去掉了,因為內容比較多,放在這里影響觀看
在這里就實現了使用 CommonsRequestLoggingFilter 來進行打印請求日志。如果有一些額外的需求(例如需要把打印的信息保存到數據庫),可以繼承 CommonsRequestLoggingFilter 然后重寫其方法來進行一些額外操作。
下面是配置項的詳細說明
setIncludeHeaders
loggingFilter.setIncludeHeaders(true);
設置打印請求頭,默認值為 false,即不打印。
當 setIncludeHeaders 設置為true時,還可以通過 setHeaderPredicate 來配置需要打印值的 header,對於不匹配的 header,值都輸出 masked
Predicate<String> p = str -> str.equals("user-agent");
loggingFilter.setHeaderPredicate(p);
輸出如下:
headers=[user-agent:"PostmanRuntime/7.26.8", accept:"masked", cache-control:"masked", postman-token:"masked", host:"masked", accept-encoding:"masked", connection:"masked"]
setIncludeClientInfo
loggingFilter.setIncludeClientInfo(true);
設置打印請求的 ip 地址,SESSIONID,默認值為 false,如果請求沒有 session,不會打印 sessionid。
輸出如下:
client=0:0:0:0:0:0:0:1, session=641CCA6182A0368C3C36104D08B21A6E
setIncludeQueryString
loggingFilter.setIncludeQueryString(true);
設置打印URL上的請求參數,默認值為 false
輸出如下:
/get?p1=p1&p2=12345
setIncludePayload
loggingFilter.setIncludePayload(true);
loggingFilter.setMaxPayloadLength(2000);
設置是否打印 request body,默認值為 false,setMaxPayloadLength 用於設置打印的長度,默認為50,即只打印前50個字符,可根據實際項目需要進行調整。
輸出如下:
payload={"name": "張三"}
其他配置
loggingFilter.setBeforeMessagePrefix(""); // 設置 before request 日志前綴,默認為:Before request [
loggingFilter.setBeforeMessageSuffix(""); // 設置 before request 日志后綴,默認為:]
loggingFilter.setAfterMessagePrefix(""); // 設置 before request 日志前綴,默認為:After request [
loggingFilter.setAfterMessageSuffix(""); // 設置 after request 日志后綴,默認為:]