すべてのプロダクト
Search
ドキュメントセンター

SchedulerX:SchedulerX 2.0 と Simple Log Service の統合

最終更新日:Mar 12, 2026

スケジュールされたジョブが失敗したり、予期しない結果を生成したりした場合、根本原因を特定するには、一元管理され検索可能なログが必要です。これは特に、複数のワーカーで実行される分散ジョブの場合に重要です。SchedulerX 2.0 の Simple Log Service は、分散ジョブを含むすべてのジョブタイプから実行ログを収集し、SchedulerX コンソールで検索可能にします。この統合をセットアップするには、Log4j2、Log4j、または Logback の設定に SchedulerX のアペンダーを追加します。

事前準備

以下が準備できていることを確認してください:

説明

ログは有効化後、最大 2 週間保持されます。期限切れのログは自動的に削除されます。

ステップ 1:SchedulerX エージェントの更新

SchedulerX エージェントを最新バージョンに更新します。バージョンの詳細については、「リリースノート」をご参照ください。

アプリケーションが Spring Boot Starter を使用している場合は、次の依存関係を pom.xml に追加します:

<dependency>
    <groupId>com.aliyun.schedulerx</groupId>
    <artifactId>schedulerx2-spring-boot-starter</artifactId>
    <version>${SchedulerX クライアントの最新バージョン}</version>
</dependency>

ステップ 2:ログアペンダーの設定

SchedulerX は、Log4j2、Log4j、および Logback 用のアペンダーを提供します。ご利用のロギングフレームワークに一致するセクションを選択してください。

2 つの収集戦略が利用可能です:

戦略スコープトレードオフ
ジョブログのみschedulerx ロガーに書き込まれたログジョブログをアプリケーションログから分離します。ほとんどのユースケースで推奨されます。
すべてのアプリケーションログルートロガー経由のすべてのログすべてをキャプチャしますが、ジョブログが一般的なアプリケーション出力と混在し、クエリ効率が低下します。

Log4j2

ジョブログのみを収集 (推奨)

  1. Log4j2 設定ファイルに SchedulerX アペンダーと専用の 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" />
                </Root>
                <Logger name="schedulerx" level="info" additivity="false">
                    <AppenderRef ref="schedulerxLog" />
                </Logger>
            </Loggers>
        </Configuration>
  2. ジョブプロセッサで、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 {
            // "schedulerx" ロガーを使用して Simple Log Service にログを送信します
            private static final Logger logger = LoggerFactory.getLogger("schedulerx");
    
            @Override
            public ProcessResult process(JobContext context) throws Exception {
                logger.info("hello HelloWorldJob3");
                return new ProcessResult(true);
            }
        }

すべてのアプリケーションログを収集

すべてのログを収集するには、専用のロガーの代わりに、schedulerxLog アペンダーをルートロガーに追加します:

<?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

ジョブログのみを収集 (推奨)

  1. アペンダーと専用の schedulerx ロガーを log4j.properties に追加します:

        log4j.rootLogger = INFO,console
        log4j.logger.schedulerx=schedulerxLog
        log4j.appender.schedulerxLog=com.alibaba.schedulerx.worker.log.appender.SchedulerxLog4jAppender
  2. ジョブプロセッサで、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 {
            // "schedulerx" ロガーを使用して Simple Log Service にログを送信します
            private static final Logger logger = LoggerFactory.getLogger("schedulerx");
    
            @Override
            public ProcessResult process(JobContext context) throws Exception {
                logger.info("hello HelloWorldJob3");
                return new ProcessResult(true);
            }
        }

すべてのアプリケーションログを収集

すべてのログを収集するには、schedulerxLog アペンダーを log4j.properties のルートロガーに追加します:

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

Logback

説明

SchedulerxLogbackAppenderschedulerx2-worker.jar にパッケージ化されています。このアペンダーを設定する前に、SchedulerX エージェントを最新バージョンに更新していることを確認してください。バージョンの詳細については、「リリースノート」をご参照ください。

ジョブログのみを収集 (推奨)

  1. アペンダーと専用の schedulerx ロガーを logback.xml に追加します:

        <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. ジョブプロセッサで、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 {
            // "schedulerx" ロガーを使用して Simple Log Service にログを送信します
            private static final Logger logger = LoggerFactory.getLogger("schedulerx");
    
            @Override
            public ProcessResult process(JobContext context) throws Exception {
                logger.info("hello HelloWorldJob3");
                return new ProcessResult(true);
            }
        }

すべてのアプリケーションログを収集

すべてのログを収集するには、schedulerxLog アペンダーを logback.xml のルートロガーに追加します:

<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>

ステップ 3:ジョブログの表示

  1. SchedulerX コンソールにログインします。

  2. 左側のナビゲーションウィンドウで、タスク管理 をクリックします。

  3. 対象のジョブを見つけ、操作 列で その他 > 履歴 を選択します。

  4. タスクインスタンスの履歴 パネルで、対象のジョブインスタンスを見つけ、操作 列の ログ をクリックします。

ログフィールド

フィールド説明
ipログエントリを生成したワーカーの IP アドレス。
executionId実行 ID。フォーマットは ${jobId}_${jobInstanceId}_${taskId} です。この ID を使用して、分散タスク間のログを関連付けます。
levelログレベル (INFO、WARN、ERROR など)。
logログの内容。
throwable例外のスタックトレース。アプリケーションがエラーをスローした場合にのみ存在します。
timeログエントリのタイムスタンプ。

キーワードによるログのクエリ

SchedulerX 2.0 は、ジョブインスタンスの最新 60 件の実行レコードのみを保持します。古い実行を検索するには、左側のナビゲーションウィンドウで ログクエリ をクリックします。ログクエリ ページで、ジョブ ID、キーワード、または時間範囲でフィルターします。

トラブルシューティングの例

ジョブの失敗の診断

Simple Log Service を統合すると、SchedulerX はジョブレベルのログとサービスレベルの例外の両方をキャプチャします。この例では、ゼロ除算エラーがログ出力にどのように表示されるかを示します。

  1. サービスメソッドを呼び出し、結果をログに記録するジョブプロセッサを作成します:

        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" ロガーを使用して Simple Log Service にログを送信します
            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. サービスクラスを作成します:

        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" ロガーを使用して Simple Log Service にログを送信します
            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;
            }
        }
  3. SchedulerX コンソールでジョブを設定します。ジョブパラメーターを 1 0 に設定して、ゼロ除算エラーをトリガーします。

    Job configuration with parameters 1 0

  4. ジョブをトリガーし、タスクインスタンスの履歴 パネルを開き、ログを確認します。ログには、TestServiceImplArithmeticException ("/ by zero") をスローし、これによりジョブが失敗したことが示されます。

    Log showing division by zero error

分散ジョブの失敗の診断

分散ジョブは、バッチ処理のために複数のワーカーにサブタスクをディスパッチします。サブタスクが失敗した場合は、ログを検索して、失敗したタスクとその原因を特定します。

  1. メッセージをディスパッチするマップジョブプロセッサを作成します。この例では、msg_23 は意図的に失敗するように設定されています:

        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. SchedulerX コンソールでジョブを設定し、トリガーします。

    Distributed job configuration

  3. ログビューアを開きます。手順については、「ステップ 3:ジョブログの表示」をご参照ください。

  4. failed などのキーワードで検索して、失敗したサブタスク (msg_23) と根本原因を特定します。