执行器新增配置项("xxl.job.executor.logretentiondays"):日志保存天数,执行器自动删除过期日志文件。限制配置最少保存3天,否则功能无效。
This commit is contained in:
parent
cceccc6276
commit
dd94810416
|
@ -1112,6 +1112,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
|
||||||
- 28、新增"任务ID"属性,移除"JobKey"属性,前者承担所有功能,方便后续增强任务依赖功能。
|
- 28、新增"任务ID"属性,移除"JobKey"属性,前者承担所有功能,方便后续增强任务依赖功能。
|
||||||
- 29、任务循环依赖问题修复,避免子任务与父任务重复导致的调度死循环;
|
- 29、任务循环依赖问题修复,避免子任务与父任务重复导致的调度死循环;
|
||||||
- 30、任务列表新增筛选条件 "任务描述",快速检索任务;
|
- 30、任务列表新增筛选条件 "任务描述",快速检索任务;
|
||||||
|
- 31、执行器新增配置项("xxl.job.executor.logretentiondays"):日志保存天数,执行器自动删除过期日志文件。限制配置最少保存3天,否则功能无效。
|
||||||
|
|
||||||
### TODO LIST
|
### TODO LIST
|
||||||
- 1、任务权限管理:执行器为粒度分配权限,核心操作校验权限;
|
- 1、任务权限管理:执行器为粒度分配权限,核心操作校验权限;
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.xxl.job.core.handler.annotation.JobHandler;
|
||||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||||
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
|
||||||
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
|
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
|
||||||
|
import com.xxl.job.core.thread.JobLogFileCleanThread;
|
||||||
import com.xxl.job.core.thread.JobThread;
|
import com.xxl.job.core.thread.JobThread;
|
||||||
import com.xxl.job.core.util.NetUtil;
|
import com.xxl.job.core.util.NetUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -34,6 +35,7 @@ public class XxlJobExecutor implements ApplicationContextAware {
|
||||||
private String adminAddresses;
|
private String adminAddresses;
|
||||||
private String accessToken;
|
private String accessToken;
|
||||||
private String logPath;
|
private String logPath;
|
||||||
|
private int logRetentionDays;
|
||||||
|
|
||||||
public void setIp(String ip) {
|
public void setIp(String ip) {
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
|
@ -53,7 +55,9 @@ public class XxlJobExecutor implements ApplicationContextAware {
|
||||||
public void setLogPath(String logPath) {
|
public void setLogPath(String logPath) {
|
||||||
this.logPath = logPath;
|
this.logPath = logPath;
|
||||||
}
|
}
|
||||||
|
public void setLogRetentionDays(int logRetentionDays) {
|
||||||
|
this.logRetentionDays = logRetentionDays;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------- applicationContext ----------------------
|
// ---------------------- applicationContext ----------------------
|
||||||
private static ApplicationContext applicationContext;
|
private static ApplicationContext applicationContext;
|
||||||
|
@ -79,6 +83,9 @@ public class XxlJobExecutor implements ApplicationContextAware {
|
||||||
|
|
||||||
// init executor-server
|
// init executor-server
|
||||||
initExecutorServer(port, ip, appName, accessToken);
|
initExecutorServer(port, ip, appName, accessToken);
|
||||||
|
|
||||||
|
// init JobLogFileCleanThread
|
||||||
|
JobLogFileCleanThread.getInstance().start(logRetentionDays);
|
||||||
}
|
}
|
||||||
public void destroy(){
|
public void destroy(){
|
||||||
// destory JobThreadRepository
|
// destory JobThreadRepository
|
||||||
|
@ -91,6 +98,9 @@ public class XxlJobExecutor implements ApplicationContextAware {
|
||||||
|
|
||||||
// destory executor-server
|
// destory executor-server
|
||||||
stopExecutorServer();
|
stopExecutorServer();
|
||||||
|
|
||||||
|
// destory JobLogFileCleanThread
|
||||||
|
JobLogFileCleanThread.getInstance().toStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,8 @@ public class ScriptJobHandler extends IJobHandler {
|
||||||
String cmd = glueType.getCmd();
|
String cmd = glueType.getCmd();
|
||||||
|
|
||||||
// make script file
|
// make script file
|
||||||
String scriptFileName = XxlJobFileAppender.getLogPath()
|
String scriptFileName = XxlJobFileAppender.getGlueSrcPath()
|
||||||
.concat("/gluesource/")
|
.concat("/")
|
||||||
.concat(String.valueOf(jobId))
|
.concat(String.valueOf(jobId))
|
||||||
.concat("_")
|
.concat("_")
|
||||||
.concat(String.valueOf(glueUpdatetime))
|
.concat(String.valueOf(glueUpdatetime))
|
||||||
|
|
|
@ -20,8 +20,21 @@ public class XxlJobFileAppender {
|
||||||
public static final InheritableThreadLocal<String> contextHolder = new InheritableThreadLocal<String>();
|
public static final InheritableThreadLocal<String> contextHolder = new InheritableThreadLocal<String>();
|
||||||
|
|
||||||
|
|
||||||
// log base path
|
/**
|
||||||
|
* log base path
|
||||||
|
*
|
||||||
|
* strut like:
|
||||||
|
* ---/
|
||||||
|
* ---/gluesource/
|
||||||
|
* ---/gluesource/10_1514171108000.js
|
||||||
|
* ---/gluesource/10_1514171108000.js
|
||||||
|
* ---/2017-12-25/
|
||||||
|
* ---/2017-12-25/639.log
|
||||||
|
* ---/2017-12-25/821.log
|
||||||
|
*
|
||||||
|
*/
|
||||||
private static String logBasePath = "/data/applogs/xxl-job/jobhandler";
|
private static String logBasePath = "/data/applogs/xxl-job/jobhandler";
|
||||||
|
private static String glueSrcPath = logBasePath.concat("/gluesource");
|
||||||
public static void initLogPath(String logPath){
|
public static void initLogPath(String logPath){
|
||||||
// init
|
// init
|
||||||
if (logPath!=null && logPath.trim().length()>0) {
|
if (logPath!=null && logPath.trim().length()>0) {
|
||||||
|
@ -39,11 +52,14 @@ public class XxlJobFileAppender {
|
||||||
if (!glueBaseDir.exists()) {
|
if (!glueBaseDir.exists()) {
|
||||||
glueBaseDir.mkdirs();
|
glueBaseDir.mkdirs();
|
||||||
}
|
}
|
||||||
|
glueSrcPath = glueBaseDir.getPath();
|
||||||
}
|
}
|
||||||
public static String getLogPath() {
|
public static String getLogPath() {
|
||||||
return logBasePath;
|
return logBasePath;
|
||||||
}
|
}
|
||||||
|
public static String getGlueSrcPath() {
|
||||||
|
return glueSrcPath;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* log filename, like "logPath/yyyy-MM-dd/9999.log"
|
* log filename, like "logPath/yyyy-MM-dd/9999.log"
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
package com.xxl.job.core.thread;
|
||||||
|
|
||||||
|
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||||
|
import com.xxl.job.core.util.FileUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* job file clean thread
|
||||||
|
*
|
||||||
|
* @author xuxueli 2017-12-29 16:23:43
|
||||||
|
*/
|
||||||
|
public class JobLogFileCleanThread extends Thread {
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(JobLogFileCleanThread.class);
|
||||||
|
|
||||||
|
private static JobLogFileCleanThread instance = new JobLogFileCleanThread();
|
||||||
|
public static JobLogFileCleanThread getInstance(){
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Thread localThread;
|
||||||
|
private volatile boolean toStop = false;
|
||||||
|
public void start(final long logRetentionDays){
|
||||||
|
|
||||||
|
// limit min value
|
||||||
|
if (logRetentionDays < 3 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
localThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (!toStop) {
|
||||||
|
try {
|
||||||
|
// clean log dir, over logRetentionDays
|
||||||
|
File[] childDirs = new File(XxlJobFileAppender.getLogPath()).listFiles();
|
||||||
|
if (childDirs!=null && childDirs.length>0) {
|
||||||
|
|
||||||
|
// today
|
||||||
|
Calendar todayCal = Calendar.getInstance();
|
||||||
|
todayCal.set(Calendar.HOUR_OF_DAY,0);
|
||||||
|
todayCal.set(Calendar.MINUTE,0);
|
||||||
|
todayCal.set(Calendar.SECOND,0);
|
||||||
|
todayCal.set(Calendar.MILLISECOND,0);
|
||||||
|
|
||||||
|
Date todayDate = todayCal.getTime();
|
||||||
|
|
||||||
|
for (File childFile: childDirs) {
|
||||||
|
|
||||||
|
// valid
|
||||||
|
if (!childFile.isDirectory()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (childFile.getName().indexOf("-") == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// file create date
|
||||||
|
Date logFileCreateDate = null;
|
||||||
|
try {
|
||||||
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
logFileCreateDate = simpleDateFormat.parse(childFile.getName());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
if (logFileCreateDate == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((todayDate.getTime()-logFileCreateDate.getTime()) >= logRetentionDays * (24 * 60 * 60 * 1000) ) {
|
||||||
|
FileUtil.deleteRecursively(childFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
TimeUnit.DAYS.sleep(1);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info(">>>>>>>>>>> xxl-job, executor JobLogFileCleanThread thread destory.");
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
localThread.setDaemon(true);
|
||||||
|
localThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toStop() {
|
||||||
|
toStop = true;
|
||||||
|
|
||||||
|
if (localThread == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interrupt and wait
|
||||||
|
localThread.interrupt();
|
||||||
|
try {
|
||||||
|
localThread.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.xxl.job.core.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file tool
|
||||||
|
*
|
||||||
|
* @author xuxueli 2017-12-29 17:56:48
|
||||||
|
*/
|
||||||
|
public class FileUtil {
|
||||||
|
|
||||||
|
public static boolean deleteRecursively(File root) {
|
||||||
|
if (root != null && root.exists()) {
|
||||||
|
if (root.isDirectory()) {
|
||||||
|
File[] children = root.listFiles();
|
||||||
|
if (children != null) {
|
||||||
|
for (File child : children) {
|
||||||
|
deleteRecursively(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root.delete();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -31,10 +31,12 @@
|
||||||
<property name="appName" value="${xxl.job.executor.appname}" />
|
<property name="appName" value="${xxl.job.executor.appname}" />
|
||||||
<!-- 执行器注册中心地址[选填],为空则关闭自动注册 -->
|
<!-- 执行器注册中心地址[选填],为空则关闭自动注册 -->
|
||||||
<property name="adminAddresses" value="${xxl.job.admin.addresses}" />
|
<property name="adminAddresses" value="${xxl.job.admin.addresses}" />
|
||||||
<!-- 执行器日志路径[选填],为空则使用默认路径 -->
|
|
||||||
<property name="logPath" value="${xxl.job.executor.logpath}" />
|
|
||||||
<!-- 访问令牌[选填],非空则进行匹配校验 -->
|
<!-- 访问令牌[选填],非空则进行匹配校验 -->
|
||||||
<property name="accessToken" value="${xxl.job.accessToken}" />
|
<property name="accessToken" value="${xxl.job.accessToken}" />
|
||||||
|
<!-- 执行器日志路径[选填],为空则使用默认路径 -->
|
||||||
|
<property name="logPath" value="${xxl.job.executor.logpath}" />
|
||||||
|
<!-- 日志保存天数[选填],值大于3时生效 -->
|
||||||
|
<property name="logRetentionDays" value="${xxl.job.executor.logretentiondays}" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,11 @@ xxl.job.executor.appname=xxl-job-executor-sample
|
||||||
xxl.job.executor.ip=
|
xxl.job.executor.ip=
|
||||||
xxl.job.executor.port=9999
|
xxl.job.executor.port=9999
|
||||||
|
|
||||||
### xxl-job log path
|
|
||||||
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
|
|
||||||
|
|
||||||
### xxl-job, access token
|
### xxl-job, access token
|
||||||
xxl.job.accessToken=
|
xxl.job.accessToken=
|
||||||
|
|
||||||
|
### xxl-job log path
|
||||||
|
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
|
||||||
|
### xxl-job log retention days
|
||||||
|
xxl.job.executor.logretentiondays=-1
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue