网站首页 > 开源技术 正文
海豚调度dolphinscheduler目前是 Apache 顶级项目,作为国内优秀的开源项目,它的架构设计理念会有很多值得我们学习和借鉴。
海豚调度dolphinscheduler是分布式易扩展的可视化DAG工作流任务调度系统
本文会包含如下内容:
- 如何将不同任务的日志输出到不同的日志文件
本篇文章适合人群:架构师、技术专家以及对任务调度非常感兴趣的高级工程师
本文以海豚1.3.5的源代码进行分析。
1. 相关知识介绍
1.1 SiftingAppender
SiftingAppender是Logback Appender的实现类,可以包含根据MDC值动态构建的appender。
SiftingAppender将Logback委托的日志事件根据接口Discriminator实现类的getDiscriminatingValue的返回值选择对应的appender, 然后由对应的appender写到不同的日志文件中。
源代码如下: 详细ch.qos.logback.core.sift.SiftingAppenderBase 97行
注意:在获取appender的getOrCreate方法是一个同步方法,估计在日志量很大时,可能存在性能问题
@Override
protected void append(E event) {
if (!isStarted()) {
return;
}
String discriminatingValue = discriminator.getDiscriminatingValue(event);
long timestamp = getTimestamp(event);
Appender<E> appender = appenderTracker.getOrCreate(discriminatingValue, timestamp);
// marks the appender for removal as specified by the user
if (eventMarksEndOfLife(event)) {
appenderTracker.endOfLife(discriminatingValue);
}
appenderTracker.removeStaleComponents(timestamp);
appender.doAppend(event);
}
配置示例
通过Discriminator定义Discriminator接口的实现类,及设置用于指定鉴别值(discriminating value)的key或变量名
通过sift配置动态构建appender的配置
<appender name="TASKLOGFILE" class="ch.qos.logback.classic.sift.SiftingAppender">
<!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter> -->
<filter class="org.apache.dolphinscheduler.server.log.TaskLogFilter"/>
<Discriminator class="org.apache.dolphinscheduler.server.log.TaskLogDiscriminator">
<key>taskAppId</key>
<logBase>${log.base}</logBase>
</Discriminator>
<sift>
<appender name="FILE-${taskAppId}" class="org.apache.dolphinscheduler.server.log.TaskLogAppender">
<file>${log.base}/${taskAppId}.log</file>
<encoder>
<pattern>
[%level] %date{yyyy-MM-dd HH:mm:ss.SSS} %logger{96}:[%line] - %messsage%n
</pattern>
<charset>UTF-8</charset>
</encoder>
<append>true</append>
</appender>
</sift>
</appender>
1.2 接口Discriminator
实现此接口是为了针对一个给定的日志事件计算discriminating值,discriminating值用来区分不同的日志事件。
SiftingAppender根据discriminating值来创建或选择已经存在的appender,如果在配置时,不指定具体class时,默认使用MDCBasedDiscriminator。
MDCBasedDiscriminator本质上是根据配置中指定的key,在MDC(Mapped Diagnostic Context,映射调试上下文)中获取对应的值,如果不存在,则返回默认值
MDC本质上一个ThreadLocal<Map<String, String>>,所以需要在写日志前,需要通过MDC.put("keyxx", discriminating-value),比如程序中不同线程的日志输出到不同的LOGER, discriminating-value填写线程ID即可。
如果需要根据业务需要,如海豚调度中,将不同任务的日志输出到不同的文件中,则需要实现此接口。
以下是Discriminator的类图
2. 海豚的任务日志
海豚调度是基于Logback日志框架的SiftingAppender,根据Task的流程定义ID、流程实例ID、任务实例ID来创建logger,并在Discriminator的接口实现类中将流程定义ID、流程实例ID、任务实例ID转化为目录
流程定义ID/流程实例ID/任务实例ID.log, 以实现将不同Task的日志输出到不同的日志文件。
2.1 任务日志的配置
任务是在WorkerServer中执行的,对应的日志配置在logback-worker.xml中,如下:
<!--workerserver的stdout配置及-->
<appender name="TASKLOGFILE" class="ch.qos.logback.classic.sift.SiftingAppender">
<!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter> -->
<filter class="org.apache.dolphinscheduler.server.log.TaskLogFilter"/>
<Discriminator class="org.apache.dolphinscheduler.server.log.TaskLogDiscriminator">
<key>taskAppId</key>
<logBase>${log.base}</logBase>
</Discriminator>
<sift>
<appender name="FILE-${taskAppId}" class="org.apache.dolphinscheduler.server.log.TaskLogAppender">
<file>${log.base}/${taskAppId}.log</file>
<encoder>
<pattern>
[%level] %date{yyyy-MM-dd HH:mm:ss.SSS} %logger{96}:[%line] - %messsage%n
</pattern>
<charset>UTF-8</charset>
</encoder>
<append>true</append>
</appender>
</sift>
</appender>
<!--workerserver的WORKERLOGFILE配置及-->
<root level="INFO">
<appender-ref ref="TASKLOGFILE"/>
<appender-ref ref="WORKERLOGFILE"/>
</root>
2.2 如何在task中指定logger
在task中指定logger的过程如下:
- WokerServer中的TaskExecuteProcessor在接收到TaskExecuteRequestCommand命令后,会根据流程定义ID、流程实例ID、任务实例ID创建一个新的taskLogger
- 在构建TaskExecuteThread时,将logger作为参数传入 workerExecService.submit(new TaskExecuteThread(taskExecutionContext, taskCallbackService, taskLogger));
- 在TaskExecuteThread的run方法中,构建Task实现,task = TaskManager.newTask(taskExecutionContext, taskLogger);
- 海豚中的所有任务继承AbstractTask类,并使用构建Task实例指定的logger打印日志
// 1 custom logger
Logger taskLogger = LoggerFactory.getLogger(LoggerUtils.buildTaskId(LoggerUtils.TASK_LOGGER_INFO_PREFIX,
taskExecutionContext.getProcessDefineId(),
taskExecutionContext.getProcessInstanceId(),
taskExecutionContext.getTaskInstanceId()));
//2 submit task
workerExecService.submit(new TaskExecuteThread(taskExecutionContext, taskCallbackService, taskLogger));
//3 指定Task的logger
task = TaskManager.newTask(taskExecutionContext, taskLogger);
/**
* constructor
* @param taskExecutionContext taskExecutionContext
* @param logger logger
*/
protected AbstractTask(TaskExecutionContext taskExecutionContext, Logger logger) {
this.taskExecutionContext = taskExecutionContext;
this.logger = logger;
}
2.3 TaskLogDiscriminator
源代码如下,将logger名称中的流程定义ID、流程实例ID、任务实例ID转换为目录,这样不同任务的日志就输出到不同的日志文件中
/**
* logger name should be like:
* Task Logger name should be like: Task-{processDefinitionId}-{processInstanceId}-{taskInstanceId}
*/
@Override
public String getDiscriminatingValue(ILoggingEvent event) {
String loggerName = event.getLoggerName()
.split(Constants.EQUAL_SIGN)[1];
String prefix = LoggerUtils.TASK_LOGGER_INFO_PREFIX + "-";
if (loggerName.startsWith(prefix)) {
return loggerName.substring(prefix.length(),
loggerName.length() - 1).replace("-","/");
} else {
return "unknown_task";
}
}
猜你喜欢
- 2024-09-12 盘点 12 月份爆火的 GitHub 项目(github排行榜)
- 2024-09-12 DolphinScheduler海豚调度器删除历史日志问题
- 2024-09-12 数据质量管理(数据质量管理平台目前支持通过扫描)
- 2024-09-12 dolphin scheduler多数据库存储(hibernate多数据库支持)
- 2024-09-12 海豚DolphinScheduler系统调度操作分析
- 2024-09-12 运维实战:DolphinScheduler 生产环境升级
- 2024-09-12 任务调度工具(任务调度工具怎么用)
- 2024-09-12 dolphinscheduler集成数据质量任务
- 2024-09-12 源码解析--海豚调度MasterServer流程执行过程分析
- 2024-09-12 大数据组件部署——dolphinscheduler集群部署
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)