1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
137 return computeHistory(jobName, 10);
138 }
139
140 private JobExecution getLatestJobExecution(String jobName) {
141 try {
142
143
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
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
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 }