View Javadoc
1   /*
2    * Copyright 2009-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.springframework.batch.admin.jmx;
17  
18  import java.util.Collection;
19  import java.util.Date;
20  
21  import org.springframework.batch.admin.domain.JobExecutionHistory;
22  import org.springframework.batch.admin.service.JobService;
23  import org.springframework.batch.core.JobExecution;
24  import org.springframework.batch.core.StepExecution;
25  import org.springframework.batch.core.launch.NoSuchJobException;
26  import org.springframework.jmx.export.annotation.ManagedResource;
27  
28  @ManagedResource
29  public class SimpleJobExecutionMetrics implements JobExecutionMetrics {
30  
31  	private final JobService jobService;
32  
33  	private final String jobName;
34  
35  	public SimpleJobExecutionMetrics(JobService jobService, String jobName) {
36  		this.jobService = jobService;
37  		this.jobName = jobName;
38  	}
39  
40  	public int getExecutionCount() {
41  		try {
42  			return jobService.countJobExecutionsForJob(jobName);
43  		}
44  		catch (NoSuchJobException e) {
45  			throw new IllegalStateException("Cannot locate job=" + jobName, e);
46  		}
47  	}
48  
49  	public int getFailureCount() {
50  
51  		int pageSize = 100;
52  		int start = 0;
53  		int count = 0;
54  
55  		Collection<JobExecution> jobExecutions;
56  		do {
57  
58  			try {
59  				jobExecutions = jobService.listJobExecutionsForJob(jobName, start, pageSize);
60  				start += pageSize;
61  			}
62  			catch (NoSuchJobException e) {
63  				throw new IllegalStateException("Cannot locate job=" + jobName, e);
64  			}
65  			for (JobExecution jobExecution : jobExecutions) {
66  				if (jobExecution.getStatus().isUnsuccessful()) {
67  					count++;
68  				}
69  			}
70  		} while (!jobExecutions.isEmpty());
71  
72  		return count;
73  
74  	}
75  
76  	public double getLatestDuration() {
77  		JobExecution jobExecution = getLatestJobExecution(jobName);
78  		JobExecutionHistory history = new JobExecutionHistory(jobName);
79  		history.append(jobExecution);
80  		return history.getDuration().getMean();
81  	}
82  
83  	public double getMeanDuration() {
84  		JobExecutionHistory history = computeHistory(jobName);
85  		return history.getDuration().getMean();
86  	}
87  
88  	public double getMaxDuration() {
89  		JobExecutionHistory history = computeHistory(jobName);
90  		return history.getDuration().getMax();
91  	}
92  
93  	public Date getLatestStartTime() {
94  		JobExecution jobExecution = getLatestJobExecution(jobName);
95  		return jobExecution==null ? null : jobExecution.getStartTime();
96  	}
97  
98  	public Date getLatestEndTime() {
99  		JobExecution jobExecution = getLatestJobExecution(jobName);
100 		return jobExecution==null ? null : jobExecution.getEndTime();
101 	}
102 
103 	public String getLatestExitCode() {
104 		JobExecution jobExecution = getLatestJobExecution(jobName);
105 		return jobExecution==null ? "NONE" : jobExecution.getExitStatus().getExitCode();
106 	}
107 
108 	public String getLatestStatus() {
109 		JobExecution jobExecution = getLatestJobExecution(jobName);
110 		return jobExecution==null ? "NONE" : jobExecution.getStatus().toString();
111 	}
112 
113 	public long getLatestExecutionId() {
114 		JobExecution jobExecution = getLatestJobExecution(jobName);
115 		return jobExecution==null ? -1 : jobExecution.getId();
116 	}
117 
118 	public String getLatestStepExitDescription() {
119 		JobExecution jobExecution = getLatestJobExecution(jobName);
120 		StepExecution stepExecution = getLatestStepExecution(jobExecution);
121 		return stepExecution==null ? "" : stepExecution.getExitStatus().getExitDescription();
122 	}
123 
124 	public String getLatestStepName() {
125 		JobExecution jobExecution = getLatestJobExecution(jobName);
126 		StepExecution stepExecution = getLatestStepExecution(jobExecution);
127 		return stepExecution==null ? "" : stepExecution.getStepName();
128 	}
129 
130 	public boolean isJobRunning() {
131 		JobExecution jobExecution = getLatestJobExecution(jobName);
132 		return jobExecution==null ? false : jobExecution.isRunning();
133 	}
134 
135 	private JobExecutionHistory computeHistory(String jobName) {
136 		// Running average over last 10 executions...
137 		return computeHistory(jobName, 10);
138 	}
139 
140 	private JobExecution getLatestJobExecution(String jobName) {
141 		try {
142 			// On the cautious side: grab the last 4 executions by ID and look for
143 			// the one that was last created...
144 			Collection<JobExecution> jobExecutions = jobService.listJobExecutionsForJob(jobName, 0, 4);
145 			if (jobExecutions.isEmpty()) {
146 				return null;
147 			}
148 			long lastUpdated = 0L;
149 			JobExecution result = null;
150 			for (JobExecution jobExecution : jobExecutions) {
151 				long updated = jobExecution.getCreateTime().getTime();
152 				if (updated > lastUpdated) {
153 					result = jobExecution;
154 					lastUpdated = updated;
155 				}
156 				else if (result!=null && updated == lastUpdated && jobExecution.getId() > result.getId()) {
157 					// Tie breaker using ID
158 					result = jobExecution;
159 				}
160 			}
161 			return result;
162 		}
163 		catch (NoSuchJobException e) {
164 			throw new IllegalStateException("Cannot locate job=" + jobName, e);
165 		}
166 	}
167 
168 	private StepExecution getLatestStepExecution(JobExecution jobExecution) {
169 		Collection<StepExecution> stepExecutions = jobExecution.getStepExecutions();
170 		StepExecution stepExecution = null;
171 		if (!stepExecutions.isEmpty()) {
172 			Date latest = new Date(0L);
173 			for (StepExecution candidate : stepExecutions) {
174 				Date stepDate = candidate.getEndTime();
175 				stepDate = stepDate==null ? new Date() : stepDate;
176 				if (stepDate.after(latest)) {
177 					latest = stepDate;
178 					stepExecution = candidate;
179 				}
180 				else if (stepExecution!=null && stepDate.equals(latest) && candidate.getId()>stepExecution.getId()) {
181 					// Tie breaker using ID
182 					stepExecution = candidate;						
183 				}
184 			}
185 		}
186 		return stepExecution;
187 	}
188 
189 	private JobExecutionHistory computeHistory(String jobName, int total) {
190 		JobExecutionHistory jobExecutionHistory = new JobExecutionHistory(jobName);
191 		try {
192 			for (JobExecution jobExecution : jobService.listJobExecutionsForJob(jobName, 0, total)) {
193 				jobExecutionHistory.append(jobExecution);
194 			}
195 		}
196 		catch (NoSuchJobException e) {
197 			throw new IllegalStateException("Cannot locate job=" + jobName, e);
198 		}
199 		return jobExecutionHistory;
200 	}
201 
202 }