admin.jmx.StepExecutionServiceLevelMonitor.java Source code

Java tutorial

Introduction

Here is the source code for admin.jmx.StepExecutionServiceLevelMonitor.java

Source

/*
 * Copyright 2006-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package admin.jmx;

import javax.management.ObjectName;
import javax.management.monitor.GaugeMonitor;
import javax.management.monitor.MonitorMBean;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

/**
 * Monitors executions of a given step and sends JMX notifications if it takes
 * too long. The monitor is a {@link MonitorMBean} so it can be automatically
 * exposed to an existing MBeanServer using Spring JMX. JMX clients subscribe to
 * notifications and receive them whenever the thresholds are crossed.
 * 
 * @author Dave Syer
 * 
 */
public class StepExecutionServiceLevelMonitor implements FactoryBean<GaugeMonitor>, InitializingBean {

    private String defaultDomain = BatchMBeanExporter.DEFAULT_DOMAIN;

    private String stepName;

    private String jobName;

    private int upperThreshold = 0;

    private int lowerThreshold = 0;

    private boolean autoStart = true;

    private String observedAttribute = "LatestDuration";

    /**
     * The name of the attribute to monitor on the step. Defaults to
     * <code>LatestDuration</code>. This can be changed at runtime, but note
     * that if the type of the observed metric changes (e.g. from double to
     * integer) then the thresholds will also have to be changed so their type
     * matches.
     * 
     * @param observedAttribute the observed attribute to set
     */
    public void setObservedAttribute(String observedAttribute) {
        this.observedAttribute = observedAttribute;
    }

    /**
     * Should the monitor start immediately or wait to be started manually?
     * 
     * @param autoStart the auto start flag to set
     */
    public void setAutoStart(boolean autoStart) {
        this.autoStart = autoStart;
    }

    /**
     * The domain name to use in constructing object names for the monitored
     * step. Default to <code>org.springframework.batch</code> (same as
     * {@link BatchMBeanExporter}).
     * 
     * @param defaultDomain the default domain to set
     */
    public void setDefaultDomain(String defaultDomain) {
        this.defaultDomain = defaultDomain;
    }

    /**
     * @param stepName the stepName to set
     */
    public void setStepName(String stepName) {
        this.stepName = stepName;
    }

    /**
     * @param jobName the jobName to set
     */
    public void setJobName(String jobName) {
        this.jobName = jobName;
    }

    /**
     * Upper threshold for observed attribute. Mandatory with no default.
     * 
     * @param upperThreshold the upper threshold to set
     */
    public void setUpperThreshold(int upperThreshold) {
        this.upperThreshold = upperThreshold;
    }

    /**
     * Optional lower threshold. Defaults to 80% of the upper threshold.
     * 
     * @param lowerThreshold the lower threshold to set
     */
    public void setLowerThreshold(int lowerThreshold) {
        this.lowerThreshold = lowerThreshold;
    }

    public GaugeMonitor getObject() throws Exception {
        GaugeMonitor monitor = new GaugeMonitor();
        monitor.setNotifyHigh(true);
        monitor.addObservedObject(new ObjectName(
                String.format("%s:type=JobExecution,name=%s,step=%s", defaultDomain, jobName, stepName)));
        monitor.setObservedAttribute(observedAttribute);
        if (observedAttribute.endsWith("Duration")) {
            monitor.setThresholds(new Double(upperThreshold), new Double(lowerThreshold));
        } else {
            monitor.setThresholds(new Integer(upperThreshold), new Integer(lowerThreshold));
        }
        if (autoStart) {
            monitor.start();
        }
        return monitor;
    }

    public Class<?> getObjectType() {
        return GaugeMonitor.class;
    }

    public boolean isSingleton() {
        return true;
    }

    public void afterPropertiesSet() throws Exception {
        Assert.state(jobName != null, "A Job name must be provided");
        Assert.state(stepName != null, "A Step name must be provided");
        Assert.state(upperThreshold > 0, "A threshold must be provided");
        Assert.state(lowerThreshold < upperThreshold, "A threshold must be provided");
        if (lowerThreshold == 0) {
            lowerThreshold = upperThreshold * 8 / 10;
        }
    }

}