利用切面编程实现调度任务的时间计算

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

}

猜你喜欢

转载自blog.csdn.net/qq_34295546/article/details/84956177