利用切面程式設計實現排程任務的時間計算
阿新 • • 發佈:2018-12-20
在工作中使用Scheduled註解實現任務排程
現在需要記錄排程的開始時間,實際結束時間,如果報錯則記錄報錯資訊,並記錄報錯時間。
日誌採用springboot自帶的logback,配置檔案logback-spring.xml如下
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern> %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n </pattern> </layout> </appender> <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <encoder> <pattern> %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n </pattern> </encoder> <!--滾動策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--路徑--> <fileNamePattern>D:/log/logbackInfo.%d.log</fileNamePattern> </rollingPolicy> </appender> <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <encoder> <pattern> %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method:%L -%msg%n </pattern> </encoder> <!--滾動策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--路徑--> <fileNamePattern>D:/log/logbackError.%d.log</fileNamePattern> </rollingPolicy> </appender> <root level="INFO"> <appender-ref ref="consoleLog"/> <appender-ref ref="fileInfoLog"/> <appender-ref ref="fileErrorLog"/> </root> </configuration>
同時將排程執行資訊放入mysql表中
檔案目錄如下
日誌實現核心為ScheduledTimeCal類,程式碼如下:
package com.cecgw.cq.aspect; import com.cecgw.cq.util.TimeUtil; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Method; import java.util.Date; /** * @author:lifuyi * @Date: 2018/12/11 10:41 * @Description:利用切面程式設計實現排程任務的時間計算 */ @Aspect @Order(-1)// 保證該AOP在@Transactional之前執行 @Component public class ScheduledTimeCal { @Autowired JdbcTemplate jdbcTemplate; private final static Logger logger = LoggerFactory.getLogger(ScheduledTimeCal.class); @Around(value = "execution(* com.cecgw.cq.schedule..*.*(..))") public void aroundLog(ProceedingJoinPoint joinPoint) { Date startDate = new Date(); long startTime = startDate.getTime(); //獲得訪問的方法名稱 String methodName = joinPoint.getSignature().getName(); //定義的介面方法 Method abstractMethod = ((MethodSignature) joinPoint.getSignature()).getMethod(); try { if (abstractMethod.isAnnotationPresent(Scheduled.class)) { logger.info("排程:" + methodName + "開始時間:" + TimeUtil.formatDate(startDate, "yyyy-MM-dd HH:mm:ss")); joinPoint.proceed(); Date date1 = new Date(); long endTime = date1.getTime(); logger.info("排程:" + methodName + "結束時間:" + TimeUtil.formatDate(date1, "yyyy-MM-dd HH:mm:ss")); Object[] objects = {methodName, TimeUtil.formatDate(startDate, "yyyy-MM-dd HH:mm:ss"), TimeUtil.formatDate(date1, "yyyy-MM-dd HH:mm:ss"), 1, endTime - startTime}; jdbcTemplate.update("INSERT into schedule_time(schedule_name,start_time,end_time,flag,`time`) " + "VALUES(?,?,?,?,?)", objects); } else { joinPoint.proceed(); } } catch (Throwable throwable) { logger.error(errInfo((Exception) throwable)); if (abstractMethod.isAnnotationPresent(Scheduled.class)) { Date date1 = new Date(); logger.info("排程:" + methodName + "失敗時間:" + TimeUtil.formatDate(date1, "yyyy-MM-dd HH:mm:ss")); long endTime = date1.getTime(); Object[] objects = {methodName, TimeUtil.formatDate(startDate, "yyyy-MM-dd HH:mm:ss"), TimeUtil.formatDate(date1, "yyyy-MM-dd HH:mm:ss"), 0, throwable.toString(), endTime - startTime}; jdbcTemplate.update("INSERT into schedule_time(schedule_name,start_time,end_time,flag,err,`time`) " + "VALUES(?,?,?,?,?,?)", objects); } } } public static String errInfo(Exception e) { StringWriter sw = null; PrintWriter pw = null; try { sw = new StringWriter(); pw = new PrintWriter(sw); // 將出錯的棧資訊輸出到printWriter中 e.printStackTrace(pw); pw.flush(); sw.flush(); } finally { if (sw != null) { try { sw.close(); } catch (IOException e1) { e1.printStackTrace(); } } if (pw != null) { pw.close(); } } return sw.toString(); } }