首页 > 其他分享 >Quartz使用监听器插入定时任务执行日志

Quartz使用监听器插入定时任务执行日志

时间:2022-12-04 16:46:15浏览次数:51  
标签:Quartz 监听器 runningLog quartz context org import 日志 public

Quartz使用监听器插入定时任务执行日志

使用springboot,将监听器交给spring容器管理,并像其中注入日志服务类,环境准备工作实现任务调度需要导入两个quartz的maven依赖

<dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
 </dependency>
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
            <version>2.7.3</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
  </dependency>       
        

创建一个监听器类,实现JobListener接口。


import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.JobListener;
import org.quartz.TriggerKey;
import org.springframework.stereotype.Component;

import java.util.Date;

@Slf4j
@Component
public class QuartzJobListener implements JobListener {

	private final QuartzRunningLogService logService;

	private static ThreadLocal<QuartzRunningLog> logThreadLocal = ThreadLocal.withInitial(QuartzRunningLog::new);

	public QuartzJobListener(QuartzRunningLogService logService) {
		this.logService = logService;
	}

	@Override
	public String getName() {
		return "jobLogListener";
	}
	/**
	*
	*Scheduler在JobDetail将要被执行时调用这个方法
	**/
	@Override
	public void jobToBeExecuted(JobExecutionContext context) {
		QuartzRunningLog quartzRunningLog = QuartzRunningLog
				.builder()
				.startTime(new Date())
				.build();
		logThreadLocal.set(quartzRunningLog);
	}
	/**
	*
	*Scheduler在JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法
	**/
	@Override
	public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {

	}
	/**
	*
	*Scheduler在JobDetail被执行之后调用这个方法
	**/
	@Override
	public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
		JobKey jobKey = context.getJobDetail().getKey();
		TriggerKey triggerKey = context.getTrigger().getKey();
		Date fireTime = context.getFireTime();
		Class jobClass = context.getJobDetail().getJobClass();
		JobDataMap dataMap = context.getMergedJobDataMap();
		String taskName = (String) dataMap.get(CommonConst.TASK_NAME);
		String cronExpression = (String) dataMap.get(CommonConst.CRON_EXPRESSION);
		String jobName = (String) dataMap.get(CommonConst.JOB_NAME);
		log.info("JobClass:{},Job:{},Trigger:{},FireTime:{}", jobClass, jobKey, triggerKey, DateUtil.formatDateTime(fireTime));
		if (null != jobException) {
			//保存错误记录
			QuartzRunningLog runningLog = logThreadLocal.get();
			runningLog.setJobName(jobName);
			runningLog.setCronExpression(cronExpression);
			runningLog.setEndTime(new Date());
			runningLog.setStatus("FAIL");
			runningLog.setTaskId(Long.valueOf(jobKey.getName()));
			runningLog.setTaskName(taskName);
			runningLog.setFailReason(jobException.getMessage());
			logService.save(runningLog);
			logThreadLocal.remove();
			return;
		}
		//保存执行记录
		QuartzRunningLog runningLog = logThreadLocal.get();
		runningLog.setJobName(jobName);
		runningLog.setCronExpression(cronExpression);
		runningLog.setEndTime(new Date());
		runningLog.setStatus("SUCESS");
		runningLog.setTaskId(Long.valueOf(jobKey.getName()));
		runningLog.setTaskName(taskName);
		logService.save(runningLog);
		logThreadLocal.remove();
	}
}

quartzconfig配置类



import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class QuartzConfig {

	@Autowired
	private ApplicationContext applicationContext;

	/**
	 * Create the job factory bean
	 *
	 * @return Job factory bean
	 */
	@Bean
	public JobFactory jobFactory() {
		ApplicationContextHolder jobFactory = new ApplicationContextHolder();
		jobFactory.setApplicationContext(applicationContext);
		return jobFactory;
	}

	/**
	 * Create the Scheduler Factory bean
	 *
	 * @return scheduler factory object
	 */
	@Bean
	public SchedulerFactoryBean schedulerFactory() {
		SchedulerFactoryBean factory = new SchedulerFactoryBean();
		factory.setAutoStartup(true);
		factory.setSchedulerName("Scheduler");
		factory.setOverwriteExistingJobs(true);
		factory.setJobFactory(jobFactory());
		return factory;
	}

	/**
	 * Create the Scheduler bean
	 *
	 * @param logService
	 * @return Scheduler
	 * @throws SchedulerException
	 */
	@Bean
	public Scheduler scheduler(@Autowired QuartzRunningLogService logService) throws SchedulerException {
        //在这里注入日志服务类且激活监听器,如果直接在监听器类里面使用@Autowired会出现注入为null
		schedulerFactory().getScheduler().getListenerManager().addJobListener(new QuartzJobListener(logService));
		return schedulerFactory().getScheduler();
	}

}

容器工具类


import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextHolder extends SpringBeanJobFactory
		implements ApplicationContextAware {
	private static ApplicationContext context;
	private transient AutowireCapableBeanFactory beanFactory;

	@Override
	public void setApplicationContext(final ApplicationContext context) {
		beanFactory = context.getAutowireCapableBeanFactory();
		ApplicationContextHolder.context = context;
	}

	@Override
	protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
		final Object job = super.createJobInstance(bundle);
		beanFactory.autowireBean(job);
		return job;
	}

	public static ApplicationContext getContext() {
		return context;
	}
}

标签:Quartz,监听器,runningLog,quartz,context,org,import,日志,public
From: https://www.cnblogs.com/ndchao/p/16950093.html

相关文章

  • easylogging++的那些事(四)源码分析(五)日志格式配置方式
    目录通过加载配置文件Configurations类支持从配置文件中加载配置Logger类提供了配置相关的接口。Logger类支持通过configurations类来配置Logger类支持从Configurat......
  • easylogging++的那些事(四)源码分析(四)日志格式配置管理类
    目录Configurations类成员变量成员函数析构函数默认构造函数从配置文件中加载配置解析配置文件解析字符串形式的配置设置指定日志级别的指定配置项通过Configuration对......
  • Java实现MySQL binlog日志监听
    使用案例引入maven依赖<dependency><groupId>com.github.shyiko</groupId><artifactId>mysql-binlog-connector-java</artifactId><version>0.21.0</version></......
  • 日志类
    //Log.h#ifndefLOG_HEAD_DEF#defineLOG_HEAD_DEF#pragmaonce#include"stdio.h"#include<stdarg.h>////用变参函数所必须的#include<time.h>#include<d......
  • 轻量化日志 Loki 全攻略,运维利器要收好
    1、前言在对公司容器云的日志方案进行设计的时候,发现主流的ELK(Elasticsearch,Logstash,Kibana)或者EFK(Elasticsearch,FilebeatorFluentd,Kibana)比较重,再加上现阶段对于ES复......
  • MySQL Linux服务器快照克隆引起的binlog日志无法正常删除导致文件系统满
       最近,一个mysql数据库Linux服务器文件系统空间满,查看是binlog消耗绝大部分空间;经了解mysql数据库每天进行全备并删除1天前binlog日志;然而,2022.11.15日开始的binlog......
  • Quartz深度实战
    概述Java语言中最正统的任务调度框架,几乎是首选。后来和SpringSchedule平分秋色;再后来会被一些轻量级的分布式任务调度平台,如XXL-Job取代。另外近几年Quartz的维护和发布几......
  • 基于Nacos实现日志级别的动态切换
    想要实现日志级别动态切换有两个要点:1.监听Nacos配置文件修改2.根据配置动态设置当前日志级别监听Nacos监听类代码:packagecom.yibing.nacosprovider.listener;impor......
  • Linux 查看日志命令总结
    服务器日志往往使我们排查问题很好的帮手,那么如何快速查询需要的信息,就需要我们掌握了。这里记录一下日常使用较多的几个查看日志的命令:1、查找文件所在位置根据文件名搜索......
  • MySQL日志管理,备份和恢复
    一.MySQL日志管理1.1mysql日志概述备份的主要目的是灾难恢复,备份还可以测试应用、回滚数据修改、查询历史数据、审计等。在备份、恢复中,日志起到了很重要的作用。MySQ......