Spring boot 日誌切面配置
阿新 • • 發佈:2018-11-30
依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
LogsAspect.java
/** * 日誌切面 * * @author 向振華 * @date 2018/11/29 14:27 */ @Slf4j @Order(100) @Aspect @Configuration public class LogsAspect { /** * 請求地址 */ private ThreadLocal<String> requestPath = new ThreadLocal<>(); private ThreadLocal<String> requestMethod = new ThreadLocal<>(); /** * 傳入引數 */ private ThreadLocal<Map<?, ?>> inputMap = new ThreadLocal<>(); /** * 輸出結果 */ private ThreadLocal<Map<String, Object>> outputMap = new ThreadLocal<>(); private ThreadLocal<Long> startTimeMills = new ThreadLocal<>(); /** * 結束時間 */ private ThreadLocal<Long> endTimeMills = new ThreadLocal<>(); private ThreadLocal<String> ip = new ThreadLocal<>(); /** * 使用者名稱 */ private ThreadLocal<String> userName = new ThreadLocal<>(); @Resource(name = "loginService") private LoginService loginService; /** * 記錄方法開始執行的時間 */ @Before("execution(* com.mmtvip.frontprovider.controller..*.*(..))") public void doBeforeInServiceLayer() { startTimeMills.set(System.currentTimeMillis()); } @Around("execution(* com.mmtvip.frontprovider.controller..*.*(..))") public Object getReqAndResInfo(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; HttpServletRequest request = servletRequestAttributes.getRequest(); requestMethod.set(request.getMethod()); inputMap.set(request.getParameterMap()); requestPath.set(request.getRequestURI()); ip.set(IPUtil.getIpAddr()); Map<String, Object> outputMaps = new HashMap<>(16); Object res; res = proceedingJoinPoint.proceed(); if (res instanceof ModelAndView) { } else { outputMaps.put("result", res); } outputMap.set(outputMaps); User user = loginService.currentUser(); if (user != null) { userName.set(user.getName()); //重新整理使用者的快取 loginService.setCurrentUserSession(user); } return res; } @After("execution(* com.mmtvip.frontprovider.controller..*.*(..))") public void doAfterInServiceLayer() { endTimeMills.set(System.currentTimeMillis()); pringLog(); removeThreadLocal(); } /** * 回收ThreadLocal變數 */ private void removeThreadLocal() { requestPath.remove(); requestMethod.remove(); inputMap.remove(); outputMap.remove(); startTimeMills.remove(); endTimeMills.remove(); ip.remove(); userName.remove(); } /** * 輸出日誌 */ private void pringLog() { log.info("請求IP:[{}],userName:[{}],url:[{}],type:[{}],handle_time:{}ms,params:{},res:{}", ip.get(), userName.get(), requestPath.get(), requestMethod.get(), (endTimeMills.get() - startTimeMills.get()), JSONObject.toJSONString(inputMap.get()), outputMap.get()); } }
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true"> <property name="LOG_HOME" value="front_log"/> <!-- 彩色日誌 --> <!-- 彩色日誌依賴的渲染類 --> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/> <!-- 彩色日誌格式 --> <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <!-- Console 輸出設定 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 無彩色控制檯輸出 --> <!--<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">--> <!--<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">--> <!--<!–格式化輸出:%d表示日期,%thread表示執行緒名,%-5level:級別從左顯示5個字元寬度%msg:日誌訊息,%n是換行符–>--> <!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>--> <!--</encoder>--> <!--</appender>--> <!-- 輸出到檔案 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--按日按大小進行拆分--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!--日誌檔案輸出的檔名--> <FileNamePattern> ${LOG_HOME}${file.separator}%d{yyyy-MM-dd}${file.separator}log.%d{yyyy-MM-dd}.%i.log </FileNamePattern> <!--日誌檔案保留天數--> <maxFileSize>100MB</maxFileSize> <maxHistory>30</maxHistory> </rollingPolicy> <append>true</append> <encoder> <pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n </pattern> </encoder> </appender> <!-- 錯誤日誌相關配置 --> <appender name="ERROR-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 日誌級別過濾器 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 過濾的級別 --> <level>ERROR</level> <!-- 匹配時的操作:接收(記錄) --> <onMatch>ACCEPT</onMatch> <!-- 不匹配時的操作:拒絕(不記錄) --> <onMismatch>DENY</onMismatch> </filter> <!--按日按大小進行拆分--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!--日誌檔案輸出的檔名--> <FileNamePattern> ${LOG_HOME}${file.separator}%d{yyyy-MM-dd}${file.separator}error.%d{yyyy-MM-dd}.%i.log </FileNamePattern> <!--日誌檔案保留天數--> <maxFileSize>100MB</maxFileSize> <maxHistory>30</maxHistory> </rollingPolicy> <append>true</append> <encoder> <pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n </pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="FILE"/> <appender-ref ref="STDOUT"/> <appender-ref ref="ERROR-OUT"/> </root> </configuration>