全部产品
Search
文档中心

分布式任务调度 SchedulerX:如何接入日志服务

更新时间:Aug 26, 2026

阿里巴巴分布式任务调度系统SchedulerX 2.0提供日志服务,您无需修改代码,只需增加一个Log4j或Logback的配置,即可在控制台看到每次任务调度(包括分布式任务)的业务日志。本文介绍如何通过SchedulerX接入并查看日志服务。

前提条件

  • 创建命名空间、应用、任务、工作流等资源,详情参见创建资源

  • 应用升级为专业版并开通日志服务。具体操作,请参见如何升级为专业版。在编辑应用分组基本配置页面,将版本设置为专业版,并开启日志服务开关。

    说明

    开通日志服务后,当前日志最多可保留2周,超过2周的日志会被清理。

接入配置

升级SchedulerX客户端版本

将SchedulerX客户端版本升级到最新版本,客户端最新版本,请参见客户端发布记录。以Spring Boot Starter为例,在应用程序的pom.xml文件中添加SchedulerxWorker依赖。

<dependency>
    <groupId>com.aliyun.schedulerx</groupId>
    <artifactId>schedulerx2-spring-boot-starter</artifactId>
    <version>${schedulerx最新版本}</version>  
</dependency>

配置Log Appender采集日志服务

Log4j2 Appender

  • 方法一:单独收集任务调度日志

    该方法可以由业务自己控制,只将任务调度日志采集,其他业务代码不会被采集,方便排查问题。

    1. log4j2增加一个Appender和Logger如下:

      <?xml version="1.0" encoding="UTF-8"?>
      <Configuration status="off">
          <Appenders>
              <Console name="Console" target="SYSTEM_OUT">
                  <PatternLayout
                      pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %m%n" />
              </Console>
              <SchedulerxLog4j2Appender name="schedulerxLog"
                  timeFormat="yyyy-MM-dd'T'HH:mmZ"
                  timeZone="UTC"
                  ignoreExceptions="true">
                  <PatternLayout pattern="%d %-5level [%thread] %logger{0}: %msg"/>
              </SchedulerxLog4j2Appender>
          </Appenders>
          <Loggers>
              <Root level="info">
                  <AppenderRef ref="Console" />
              </Root>
              <Logger name="schedulerx" level="info" additivity="false">
                  <AppenderRef ref="schedulerxLog" />
              </Logger>
          </Loggers>
      </Configuration>
    2. 修改业务代码如下,使用Logger: schedulerx采集任务调度的日志。

      package com.hxm.test.processor;
      import com.alibaba.schedulerx.worker.domain.JobContext;
      import com.alibaba.schedulerx.worker.processor.JavaProcessor;
      import com.alibaba.schedulerx.worker.processor.ProcessResult;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.stereotype.Component;
      @Component
      public class HelloWorldJob3 extends JavaProcessor {
          private static final Logger logger = LoggerFactory.getLogger("schedulerx");
          @Override
          public ProcessResult process(JobContext context) throws Exception {
              LOGGER.info("hello HelloWorldJob3");
              return new ProcessResult(true);
          }
      }
  • 方法二:搜集所有业务日志

    该方法只需要配置Log4j文件,不需要修改一行业务代码。如果将SchedulerxLog配置在rootLogger里,会让所有日志都通过SchedulerX采集,不仅搜索速度较慢,而且业务日志和任务调度日志会混在一起,难以排查问题。配置如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="off">
        <Appenders>
            <Console name="Console" target="SYSTEM_OUT">
                <PatternLayout
                    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %m%n" />
            </Console>
            <SchedulerxLog4j2Appender name="schedulerxLog"
                timeFormat="yyyy-MM-dd'T'HH:mmZ"
                timeZone="UTC"
                ignoreExceptions="true">
                <PatternLayout pattern="%d %-5level [%thread] %logger{0}: %msg"/>
            </SchedulerxLog4j2Appender>
        </Appenders>
        <Loggers>
            <Root level="info">
                <AppenderRef ref="Console" />
                <AppenderRef ref="schedulerxLog" />
            </Root>
        </Loggers>
    </Configuration>

Log4j Appender

  • 方法一:单独收集任务调度日志

    1. log4j.properties增加一个Appender和Logger。

      log4j.rootLogger = INFO,console
      log4j.logger.schedulerx=schedulerxLog
      log4j.appender.schedulerxLog=com.alibaba.schedulerx.worker.log.appender.SchedulerxLog4jAppender
    2. 修改业务代码如下,使用Logger: schedulerx采集任务调度的日志。

      package com.hxm.test.processor;
      import com.alibaba.schedulerx.worker.domain.JobContext;
      import com.alibaba.schedulerx.worker.processor.JavaProcessor;
      import com.alibaba.schedulerx.worker.processor.ProcessResult;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.stereotype.Component;
      @Component
      public class HelloWorldJob3 extends JavaProcessor {
          private static final Logger logger = LoggerFactory.getLogger("schedulerx");
          @Override
          public ProcessResult process(JobContext context) throws Exception {
              logger.info("hello HelloWorldJob3");
              return new ProcessResult(true);
          }
      }
  • 方法二:收集所有日志

    log4j.properties增加一个Appender,将这个Appender配置在rootLogger里:

    log4j.rootLogger = INFO,console,schedulerxLog
    log4j.appender.schedulerxLog=com.alibaba.schedulerx.worker.log.appender.SchedulerxLog4jAppender

Logback Appender

说明

SchedulerxLogbackAppender这个类在依赖的SDK schedulerx2-worker JAR包里面,需要升级SchedulerX客户端到最新版本。客户端最新版本,请参见客户端发布记录

  • 方法一:单独收集任务调度日志

    1. logback.xml增加一个Appender和Logger。

      <appender name="schedulerxLog" class="com.alibaba.schedulerx.worker.log.appender.SchedulerxLogbackAppender">
          <timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
          <timeZone>UTC</timeZone>
      </appender>
      <root level="INFO">
          <appender-ref ref="CONSOLE" />
      </root>
      <logger name="schedulerx" level="INFO">
          <appender-ref ref="schedulerxLog"/>
      </logger>
    2. 修改业务代码如下,使用Logger: schedulerx采集任务调度的日志。

      package com.hxm.test.processor;
      import com.alibaba.schedulerx.worker.domain.JobContext;
      import com.alibaba.schedulerx.worker.processor.JavaProcessor;
      import com.alibaba.schedulerx.worker.processor.ProcessResult;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.stereotype.Component;
      @Component
      public class HelloWorldJob3 extends JavaProcessor {
          private static final Logger logger = LoggerFactory.getLogger("schedulerx");
          @Override
          public ProcessResult process(JobContext context) throws Exception {
              LOGGER.info("hello HelloWorldJob3");
              return new ProcessResult(true);
          }
      }
  • 方法二:收集所有日志

    logback.xml增加一个Appender,将其配置在rootLogger里:

    <appender name="schedulerxLog" class="com.alibaba.schedulerx.worker.log.appender.SchedulerxLogbackAppender">
        <timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
        <timeZone>UTC</timeZone>
    </appender>
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="schedulerxLog"/>
    </root>

查看输出的日志

  1. 登录分布式任务调度平台

  2. 在左侧导航栏单击任务管理

  3. 在任务列表中找到目标任务,在目标任务的操作列选择更多 > 历史记录,进入到任务实例记录页面。

  4. 任务实例记录页面,单击目标任务操作列的日志

    日志弹窗中显示任务执行日志,包含字段 ipexecutionIdlevellogtimethrowable(以黄色高亮标识)。示例日志包括一条 INFO 级别记录 testService.doDivision finished, a=1, b=0, c=-1,以及一条 ERROR 级别记录 java.lang.ArithmeticException: / by zero,堆栈跟踪包含 TestServiceImpl.doDivisionHelloWorldJob.processThreadContainer.start 等调用链。

日志中关键词的定义如下:

  • ip: 打印该日志的执行机器。

  • executionId: 本次任务实例的执行ID,格式为${jobId}_${jobInstanceId}_${taskId}

  • level: 日志的级别。

  • log:日志的信息。

  • throwable: 应用抛出异常时,会打印该字段。

  • time:打印日志的时间。

应用场景及演示

查询业务失败的原因

SchedulerX 2.0的日志服务可以收集任务的执行日志和异常,包括Service的日志都可以收集。

  1. 新建代码。

    1. 新建任务代码,配置使用SchedulerX打印日志。

      package com.hxm.test.processor;
      import com.alibaba.schedulerx.test.service.TestService;
      import com.alibaba.schedulerx.worker.domain.JobContext;
      import com.alibaba.schedulerx.worker.processor.JavaProcessor;
      import com.alibaba.schedulerx.worker.processor.ProcessResult;
      import org.apache.logging.log4j.LogManager;
      import org.apache.logging.log4j.Logger;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Component;
      @Component
      public class HelloWorldJob extends JavaProcessor {
          /**使用SchedulerX收集日志**/
          private static final Logger LOGGER = LogManager.getLogger("schedulerx");
          @Autowired
          private TestService testService;
          @Override
          public ProcessResult process(JobContext context) throws Exception {
              String parameters = context.getJobParameters();
              String tokens[] = parameters.split(" ");
              int a = Integer.valueOf(tokens[0]);
              int b = Integer.valueOf(tokens[1]);
              int c = testService.doDivision(a, b);
              LOGGER.info("testService.doDivision finished, a={}, b={}, c={}", a, b, c);
              if (c < 0) {
                  return new ProcessResult(false, "result=" + c);
              }
              return new ProcessResult(true);
          }
      }
    2. 新建Service业务代码,配置使用SchedulerX打印日志。

      package com.hxm.test.service;
      import org.apache.logging.log4j.LogManager;
      import org.apache.logging.log4j.Logger;
      import org.springframework.stereotype.Service;
      @Service("testService")
      public class TestServiceImpl implements TestService {
          /**使用SchedulerX收集日志**/
          private static final Logger LOGGER = LogManager.getLogger("schedulerx");
          @Override
          public int doDivision(int a, int b) {
              try {
                   LOGGER.info("start to do division c = " + a + "/" + b);
                   int c = a/b;
                   LOGGER.info("c=" + c);
                   return c;
              } catch (Exception e) {
                  LOGGER.error("", e);
              }
              return -1;
          }
      }
  2. 控制台配置任务。

    根据代码逻辑可知1除以0肯定会抛出异常。设置任务名hello任务类型选择JavaClass全路径填写com.hxm.test.processor.HelloWorldJob执行模式选择单机运行优先级选择任务参数填写10

  3. 任务运行一次后,通过任务实例列表查看日志。

    在任务实例列表中找到状态为失败的任务记录,单击其操作列的日志按钮查看执行日志。

    根据日志内容,可得出失败的原因是TestServiceImpl抛出了除0的异常。

    ip : 30.2xxx.xxx.xx
    executionId : 1040057_5xxxxxxxxx_0
    level : INFO
    log : 2022-01-25 17:52:59,513 INFO [Schedulerx-Container-Thread-1040057_xxxxxxxxxx56-0] schedulerx: testService.doDivision finished. a=1. b=0. c=-1
    time : 2022-04-16 16:45:12
    ---
    ip : 30.2xxx.xxx.xx
    executionId : 1040057_8xxxxxxxxx_x
    level :   ERROR
    log : 2022-01-25 17:52:59,512   ERROR   [Schedulerx-Container-Thread-xxx_xxx_xxx56-0] schedulerx:
    java.lang.ArithmeticException: / by zero
            at com.alibaba.schedulerx.test.service.TestServiceImpl.doDivision(TestServiceImpl.java:19) [classes/:?]
            at com.alibaba.schedulerx.test.processor.HelloWorldJob.process(HelloWorldJob.java:27) [classes/:?]
            at com.alibaba.schedulerx.worker.container.ThreadContainer.start(ThreadContainer.java:94) [schedulerx-worker-1.4.0-SNAPSHOT.jar:?]
            at com.alibaba.schedulerx.worker.container.ThreadContainer.run(ThreadContainer.java:60) [schedulerx-worker-1.4.0-SNAPSHOT.jar:?]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_144]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_144]
            at java.lang.Thread.run(Thread.java:748) [?:1.8.0_144]
    throwable : java.lang.ArithmeticException: / by zero
            at com.alibaba.schedulerx.test.service.TestServiceImpl.doDivision(TestServiceImpl.java:19)

查询分布式任务失败原因

SchedulerX 2.0的分布式任务用来执行批量任务,例如某个任务批次执行失败了,您想查询具体是哪个子任务失败时,可执行如下操作:

  1. 新建任务代码,配置使用SchedulerX打印日志。

    package com.hxm.test.processor;
    import java.util.ArrayList;
    import java.util.List;
    import com.alibaba.schedulerx.worker.domain.JobContext;
    import com.alibaba.schedulerx.worker.processor.MapJobProcessor;
    import com.alibaba.schedulerx.worker.processor.ProcessResult;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    public class TestMapJobProcessor extends MapJobProcessor {
        private static final Logger LOGGER = LogManager.getLogger("schedulerx");
        @Override
        public ProcessResult process(JobContext context) throws Exception {
            String taskName = context.getTaskName();
            String parameter = context.getJobParameters();
            int dispatchNum = Integer.valueOf(parameter);
            if (isRootTask(context)) {
                LOGGER.info("start root task");
                List<String> msgList = new ArrayList<>();
                for (int i = 0; i <= dispatchNum; i++) {
                    msgList.add("msg_" + i);
                }
                return map(msgList, "Level1Dispatch");
            } else if (taskName.equals("Level1Dispatch")) {
                String task = (String)context.getTask();
                if (task.equals("msg_23")) {
                    LOGGER.error("msg={}, failed", task);
                    return new ProcessResult(false);
                } else {
                    LOGGER.info("msg={}, success", task);
                }
                return new ProcessResult(true);
            }
            return new ProcessResult(false);
        }
    }
                    
  2. 控制台配置任务并执行一次。

    在编辑任务页面的基本配置步骤中,设置任务名为"订单处理",任务类型选择"Java",Class全路径填写com.hxm.test.processor.TestMapJobProcessor执行模式选择"MapReduce",任务参数填写100

  3. 查看日志。具体操作,请参见查看输出的日志

  4. 在日志中搜索关键字,快速定位失败的任务及原因。

    例如,在搜索框中输入关键字ERROR并指定时间范围,单击搜索后可查看匹配的日志条目,包含executionIdlevel及具体错误日志等字段。

根据关键字查询历史日志

任务实例的历史记录只保留最近60条。如果想排查历史上任务失败的原因,可以通过控制台左侧导航栏的日志查询来检索。日志查询支持根据任务ID、关键字和时间区间搜索。

需先在应用下拉框中选择目标应用,再进行检索。查询结果以列表形式展示,每条日志包含 ip、executionId、time、level、log 等字段。