在工作中使用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();
}
}