Spring Boot 入門(五):集成 AOP 進行日志管理


本篇文章是接着 Spring boot 入門(四):集成 Shiro 實現登陸認證和權限管理寫的,按照前面幾篇博客的教程,可以搭建一個簡單的項目,主要包含了 Pagehelper+MyBatis 分頁查詢,Generator 代碼自動生成器,Shiro登錄及權限管理。本篇博客主要是集成 AOP 進行日志管理

1.導入 jar 包

1 <!-- aop -->
2         <dependency>
3             <groupId>org.springframework.boot</groupId>
4             <artifactId>spring-boot-starter-aop</artifactId>
5         </dependency>

2.配置 Logback-spring 文件

關於 Logback-spring 的配置網上很多,隨便copy一份基本上就能使用,Logback-spring.xml 中主要配置了下列內容

  • (1).日志寫道控制台
  • (2).日志寫道本地文件中
  • (3).日志級別
  • (4).日志生成方式(按照日期滾動生成,還是按照日期單獨生成)
  • (5).日志來源的配置,一般直接配置到 Control

我也是直接在copy了一份,代碼如下

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <configuration  scan="true" scanPeriod="60 seconds" debug="false">
 3     <contextName>logback</contextName>
 4 <!--
 5     &lt;!&ndash; 文件輸出格式 &ndash;&gt;
 6     <property name="PATTERN" value="%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) |-%-5level [%thread] %c [%L] -| %msg%n" />
 7     &lt;!&ndash; test文件路徑 &ndash;&gt;
 8     <property name="TEST_FILE_PATH" value="c:/log" />
 9 
10     -->
11 
12     <!--輸出到控制台-->
13     <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
14         <encoder>
15             <pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
16         </encoder>
17     </appender>
18 
19     <!--按天生成日志-->
20     <appender name="logFile"  class="ch.qos.logback.core.rolling.RollingFileAppender">
21         <Prudent>true</Prudent>
22         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
23             <FileNamePattern>
24                 applog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log
25             </FileNamePattern>
26         </rollingPolicy>
27         <layout class="ch.qos.logback.classic.PatternLayout">
28             <Pattern>
29                 %d{yyyy-MM-dd HH:mm:ss} -%msg%n
30             </Pattern>
31         </layout>
32     </appender>
33 
34     <logger name="com.tswc.edu" additivity="false">
35         <appender-ref ref="console"/>
36         <appender-ref ref="logFile" />
37     </logger>
38 
39     <root level="error">
40         <appender-ref ref="console"/>
41         <appender-ref ref="logFile" />
42     </root>
43 
44 </configuration>

這里用戶也可以配置多個級別使用於多個環境,對每個日志級別進行配置不同的屬性,然后在 Application.xml 中選擇不同的級別環境。在實際項目開發的過程中,一般配置2個環境,開發環境,生產環境。在開發環境中,只需要配置日志輸出到控制台,便於開發人員調試。生成環境相反,需要配置日志輸出到文件,控制台盡量不要輸出日志,這樣可以減少控制台對虛擬機內存的消耗,一旦產生 Bug ,用戶查詢日志文件即可

上述代碼中即配置了日志輸出到控制台,也配置了日志輸出到日志文件

3.配置日志級別

只需要在 Application.xml 中配置即可:

日志級別分為5個等級,debug<info<warn<Error<Fatal,其中常用的級別為:debug和info
  • debug 級別最低,可以隨意的使用於任何覺得有利於在調試時更詳細的了解系統運行狀態的東東;
  • info 重要,輸出信息:用來反饋系統的當前狀態給最終用戶的; 后三個,警告、錯誤、嚴重錯誤,這三者應該都在系統運行時檢測到了一個不正常的狀態。
  • warn, 可修復,系統可繼續運行下去;
  • Error, 可修復性,但無法確定系統會正常的工作下去;
  • Fatal, 相當嚴重,可以肯定這種錯誤已經無法修復,並且如果系統繼續運行下去的話后果嚴重。

4.編寫日志類

 1 @Aspect
 2 @Component
 3 public class WebLogAspect {
 4 
 5     private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
 6 
 7     @Pointcut("execution( * com.tswc.edu.controller.*.*(..))")//兩個..代表所有子目錄,最后括號里的兩個..代表所有參數
 8     public void logPointCut() {
 9     }
10 
11 
12     @Before("logPointCut()")
13     public void doBefore(JoinPoint joinPoint) throws Throwable {
14         // 接收到請求,記錄請求內容
15         ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
16         HttpServletRequest request = attributes.getRequest();
17 
18         // 記錄下請求內容
19         logger.info("請求地址 : " + request.getRequestURL().toString());
20         //logger.info("方法描述 : " + );
21         logger.info("HTTP METHOD : " + request.getMethod());
22         // 獲取真實的ip地址
23         //logger.info("IP : " + IPAddressUtil.getClientIpAddress(request));
24         logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
25                 + joinPoint.getSignature().getName());
26         logger.info("參數 : " + Arrays.toString(joinPoint.getArgs()));
27 //        loggger.info("參數 : " + joinPoint.getArgs());
28 
29     }
30 
31     @AfterReturning(returning = "ret", pointcut = "logPointCut()")// returning的值和doAfterReturning的參數名一致
32     public void doAfterReturning(Object ret) throws Throwable {
33         // 處理完請求,返回內容(返回值太復雜時,打印的是物理存儲空間的地址)
34         logger.debug("返回值 : " + ret);
35     }
36 
37     @Around("logPointCut()")
38     public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
39         long startTime = System.currentTimeMillis();
40         Object ob = pjp.proceed();// ob 為方法的返回值
41         logger.info("耗時 : " + (System.currentTimeMillis() - startTime));
42         return ob;
43     }
44 }

這是個通用類,主要約定控制台或者日志文件中日志的格式,關於此公共類,網上有大量的講解,這里就不詳細說明了。

再次啟動項目,控制台將輸出日志,並將日志寫入到文件中:



5.新增加部分

其中自定義日志文件可以不要,這里用戶自己定義了日志輸出的說明部分
自定義了 @Log 注記的識別,並配置一些文件說明,那么在請求到這個類的時候,日志中將輸出文章描述部分

自定義配置文件的代碼:

  • Log
1 @Target(ElementType.METHOD)
2 @Retention(RetentionPolicy.RUNTIME)
3 //自定義注解類   ArchivesLog.java(獲取Controller描述用的)
4 public @interface Log {
5     String value() default "";
6 }
  • LogAspect
 1 public class LogAspect {
 2     private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
 3     //切點
 4     @Pointcut("@annotation(com.tswc.edu.annotation.Log)")
 5     public void logPointCut() {
 6     }
 7 
 8     @Around("logPointCut()")
 9     public Object around(ProceedingJoinPoint point) throws Throwable {
10         long beginTime = System.currentTimeMillis();
11         // 執行方法
12         Object result = point.proceed();
13         // 執行時長(毫秒)
14         long time = System.currentTimeMillis() - beginTime;
15         //異步保存日志
16         //saveLog(point, time);
17         return result;
18     }
19 
20 }

其中LogAspect中也可以寫一些對日志進行 CRUD 的業務邏輯操作,大多數情況下,此處可以將日志的保存邏輯寫入到此類中。

6.問題

本項目在啟動的時候,報了一個關於日志的警告,沒有找到解決方案

 


項目中並沒有用到log4j,不知道為什么會警告,項目中缺少log4j的配置文件,如果有大神知道原因,歡迎留言

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM