SchedulerX 2.0 と Simple Log Service を統合するには、Log4j または Logback の構成を追加するだけで済みます。その後、SchedulerX 2.0 コンソールでトリガーされたジョブ(分散ジョブを含む)のログを表示できます。このトピックでは、SchedulerX 2.0 と Simple Log Service を統合してジョブのログを表示する方法について説明します。
前提条件
手順
SchedulerX エージェントの更新
SchedulerX エージェントを最新バージョンに更新します。最新バージョンについては、Java SDK トピックのリリースノートセクションをご参照ください。次のサンプルコードでは、Spring Boot Starter を使用しています。アプリケーションの pom.xml ファイルに SchedulerxWorker 依存関係を追加します。
<dependency>
<groupId>com.aliyun.schedulerx</groupId>
<artifactId>schedulerx2-spring-boot-starter</artifactId>
<version>${SchedulerX クライアントの最新バージョン}</version>
</dependency>ログ収集のためのログアペンダーの設定
Log4j2 Appender
方法 1: トリガーされたジョブのログのみを収集する
ビジネス要件に基づいて、トラブルシューティングのためにトリガーされたジョブのログのみを収集できます。
Log4j 2にアペンダーとロガーを追加します。次の例は、構成を示しています。<?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>次の例を参照してコードを変更します。 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"); // schedulerx という名前のロガーを使用 @Override public ProcessResult process(JobContext context) throws Exception { LOGGER.info("hello HelloWorldJob3"); return new ProcessResult(true); } }
方法 2: すべてのサービスログを収集する
この方法を使用する場合、Log4j ファイルを設定するだけで済みます。ルートロガーに schedulerxLog という名前のアペンダーを設定すると、すべてのログが 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" /> // ルートロガーに schedulerxLog アペンダーを追加 </Root> </Loggers> </Configuration>
Log4j Appender
方法 1: トリガーされたジョブのログのみを収集する
log4j.propertiesファイルにアペンダーとロガーを追加します。log4j.rootLogger = INFO,console log4j.logger.schedulerx=schedulerxLog // schedulerx という名前のロガーを追加 log4j.appender.schedulerxLog=com.alibaba.schedulerx.worker.log.appender.SchedulerxLog4jAppender // schedulerxLog アペンダーを定義次の例を参照してコードを変更します。 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"); // schedulerx という名前のロガーを使用 @Override public ProcessResult process(JobContext context) throws Exception { logger.info("hello HelloWorldJob3"); return new ProcessResult(true); } }
方法 2: すべてのログを収集する
log4j.propertiesファイルにアペンダーを追加し、このアペンダーをルートロガーで設定します。log4j.rootLogger = INFO,console,schedulerxLog // ルートロガーに schedulerxLog アペンダーを追加 log4j.appender.schedulerxLog=com.alibaba.schedulerx.worker.log.appender.SchedulerxLog4jAppender // schedulerxLog アペンダーを定義
Logback Appender
SchedulerxLogbackAppender クラスは schedulerx2-worker.jar パッケージにあります。SchedulerX エージェントを最新バージョンに更新する必要があります。エージェントの最新バージョンについては、Java SDK トピックの リリースノート セクションをご参照ください。
方法 1: トリガーされたジョブのログのみを収集する
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"> // schedulerx という名前のロガーを追加 <appender-ref ref="schedulerxLog"/> </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"); // schedulerx という名前のロガーを使用 @Override public ProcessResult process(JobContext context) throws Exception { LOGGER.info("hello HelloWorldJob3"); return new ProcessResult(true); } }
方法 2: すべてのログを収集する
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"/> // ルートロガーに schedulerxLog アペンダーを追加 </root>
ログの表示
SchedulerX コンソール にログインします。
左側のナビゲーションペインで、[タスク管理] をクリックします。
[タスク管理] ページで、管理するジョブを見つけ、[操作] 列の タスクインスタンスレコード を選択して パネルに移動します。
[タスクインスタンスレコード] パネルで、管理するジョブインスタンスを見つけ、操作列の [ログ] をクリックします。
ログには、次のフィールドが含まれています。
ip: ログを出力したワーカーの IP アドレス。executionId: ジョブインスタンスの実行 ID。値は${jobId}_${jobInstanceId}_${taskId}形式です。level: ログレベル。log: ログの内容。throwable: エラーフィールド。このフィールドは、アプリケーションでエラーが発生した場合にのみ出力されます。time: ログが出力された時刻。
シナリオとデモ
サービス障害の原因を確認する
Simple Log Service と SchedulerX 2.0 を統合すると、SchedulerX 2.0 はジョブログとサービスログを収集し、例外を記録できます。
コードを作成します。
ジョブを作成し、SchedulerX 2.0 を使用してログを出力します。
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 2.0 を使用してログを収集します。** 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); } }サービスのコードを作成し、SchedulerX 2.0 を使用してログを出力します。
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 2.0 を使用してログを収集します。** 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; } }
SchedulerX コンソールでジョブを設定します。
1 を 0 で除算すると、ジョブのビジネスロジックによりエラーが発生します。

ジョブを 1 回実行し、[タスクインスタンスレコード] パネルに移動してジョブログを表示します。
ログの内容は、TestServiceImpl が「ゼロによる除算」エラーをスローしたためにジョブが失敗したことを示しています。

分散ジョブエラーの原因を確認する
SchedulerX 2.0 の分散ジョブを使用してバッチ処理を実行できます。分散ジョブが失敗した場合、次の操作を実行して失敗したタスクを特定できます。
ジョブを作成し、SchedulerX 2.0 を使用してログを出力します。
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"); // SchedulerX 2.0 でログを収集 @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("ルートタスクを開始します"); 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={}、失敗", task); return new ProcessResult(false); } else { LOGGER.info("msg={}、成功", task); } return new ProcessResult(true); } return new ProcessResult(false); } }SchedulerX コンソールでジョブを設定し、ジョブを 1 回トリガーします。

ログを表示します。詳細については、このトピックの「ログの表示」セクションをご参照ください。
ログでキーワードを検索して、失敗したタスクとその原因をすばやく特定します。
キーワードによるログデータのクエリ
SchedulerX 2.0 は、ジョブインスタンスの最新の 60 件の実行レコードのみを保持します。履歴実行レコードに基づいてエラーをトラブルシューティングする場合は、SchedulerX コンソールの左側のナビゲーションペインで [ログクエリ] をクリックします。 [ログクエリ] ページでは、ジョブ ID、キーワード、または期間でログデータをクエリできます。
