JBatch: report about a previous step!


JBatch is a nice API proposing some auto-monitoring. As all operations, the entry point is the JobOperator and from an executionId you can get several information like status, metrics, start/end time etc about the job and its steps.

But is it possible to auto monitor a batch?

Of course it is (otherwise why writing a post right ;)).

Before seeing how to do it let write a small report method taking a StepExecution and logging its data:

private void doReport(final StepExecution execution) {
    LOGGER.info("Step: " + execution.getStepName());
    LOGGER.info("ExecutionId: " + execution.getStepExecutionId());
    LOGGER.info("Status: " + execution.getExitStatus());
    LOGGER.info("Start: " + execution.getStartTime());
    LOGGER.info("Stop: " + execution.getEndTime());
    LOGGER.info("Metrics:");
    asList(execution.getMetrics()).stream()
            .sorted((o1, o2) -> o1.getType().name().compareTo(o2.getType().name()))
            .forEach(m -> LOGGER.info("  - " + m.getType().name() + " = " + m.getValue()));
}

Output would look like (for a chunk):

INFOS: Step: process
INFOS: Execution Id: 1
INFOS: Status: COMPLETED
INFOS: Start: Thu Mar 26 18:20:44 CET 2015
INFOS: Stop: Thu Mar 26 18:21:46 CET 2015
INFOS: Metrics:
INFOS:   - COMMIT_COUNT = 5306
INFOS:   - FILTER_COUNT = 0
INFOS:   - PROCESS_SKIP_COUNT = 0
INFOS:   - READ_COUNT = 53059
INFOS:   - READ_SKIP_COUNT = 0
INFOS:   - ROLLBACK_COUNT = 0
INFOS:   - WRITE_COUNT = 53059
INFOS:   - WRITE_SKIP_COUNT = 0

great, so how to get the StepExecution during a batch? Browsing JobOperator API you’ll see getStepExecutions(jobExecutionId) method. It provides all steps executions.

We move forward, how to get the job execution id during the batch execution? here the answer is simple: just reuse JobContext. This bean is injectable in any JBatch component and provides metadata about the job execution like its id thanks to getExecutionId() method.

So let’s put it all together:

@Named
public class Report extends AbstractBatchlet {
    private static final Logger LOGGER = Logger.getLogger(Report.class.getName());

    @Inject
    private JobContext context;

    @Inject
    @BatchProperty
    private Integer stepIndex;

    @Override
    public String process() throws Exception {
        final List<StepExecution> steps = BatchRuntime.getJobOperator().getStepExecutions(context.getExecutionId());
        if (steps.size() <= stepIndex) {
            throw new IllegalArgumentException("execution has only " + steps.size() + " steps");
        }
        doReport(steps.get(stepIndex));
        return "reported";
    }

    private void doReport(final StepExecution execution) {
        LOGGER.info("Step: " + execution.getStepName());
        LOGGER.info("Execution Id: " + execution.getStepExecutionId());
        LOGGER.info("Status: " + execution.getExitStatus());
        LOGGER.info("Start: " + execution.getStartTime());
        LOGGER.info("Stop: " + execution.getEndTime());
        LOGGER.info("Metrics:");
        asList(execution.getMetrics()).stream()
                .sorted((o1, o2) -> o1.getType().name().compareTo(o2.getType().name()))
                .forEach(m -> LOGGER.info("  - " + m.getType().name() + " = " + m.getValue()));
    }
}

Was not that hard finally ;).

To make it integrated to your batch just define a step with this batchlet:

<?xml version="1.0" encoding="UTF-8"?>
<job id="file-to-datase" version="1.0"
     xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="
      http://xmlns.jcp.org/xml/ns/javaee
      http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd">

  <step id="start" next="report">
    <chunk>
      <reader ref="myreader"/>
      <writer ref="myWriter" />
    </chunk>
  </step>
  <step id="report">
    <batchlet ref="report">
      <properties>
        <property name="stepIndex" value="0" />
      </properties>
    </batchlet>
  </step>

</job>
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s