1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.monitoring;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import org.apache.hadoop.hbase.classification.InterfaceAudience;
28 import org.apache.hadoop.hbase.util.GsonUtil;
29 import org.apache.hbase.thirdparty.com.google.gson.Gson;
30
31 @InterfaceAudience.Private
32 class MonitoredTaskImpl implements MonitoredTask {
33 private long startTime;
34 private long statusTime;
35 private long stateTime;
36 private long warnTime;
37
38 private volatile String status;
39 private volatile String description;
40
41 protected volatile State state = State.RUNNING;
42
43 private boolean journalEnabled = false;
44 private List<StatusJournalEntry> journal;
45
46 private static final Gson GSON = GsonUtil.createGson().create();
47
48 public MonitoredTaskImpl() {
49 startTime = System.currentTimeMillis();
50 statusTime = startTime;
51 stateTime = startTime;
52 warnTime = startTime;
53 }
54
55 private static class StatusJournalEntryImpl implements StatusJournalEntry {
56 private long statusTime;
57 private String status;
58
59 public StatusJournalEntryImpl(String status, long statusTime) {
60 this.status = status;
61 this.statusTime = statusTime;
62 }
63
64 @Override
65 public String getStatus() {
66 return status;
67 }
68
69 @Override
70 public long getTimeStamp() {
71 return statusTime;
72 }
73
74 @Override
75 public String toString() {
76 StringBuilder sb = new StringBuilder();
77 sb.append(status);
78 sb.append(" at ");
79 sb.append(statusTime);
80 return sb.toString();
81 }
82 }
83
84 @Override
85 public synchronized MonitoredTaskImpl clone() {
86 try {
87 return (MonitoredTaskImpl) super.clone();
88 } catch (CloneNotSupportedException e) {
89 throw new AssertionError();
90 }
91 }
92
93 @Override
94 public long getStartTime() {
95 return startTime;
96 }
97
98 @Override
99 public String getDescription() {
100 return description;
101 }
102
103 @Override
104 public String getStatus() {
105 return status;
106 }
107
108 @Override
109 public long getStatusTime() {
110 return statusTime;
111 }
112
113 @Override
114 public State getState() {
115 return state;
116 }
117
118 @Override
119 public long getStateTime() {
120 return stateTime;
121 }
122
123 @Override
124 public long getWarnTime() {
125 return warnTime;
126 }
127
128 @Override
129 public long getCompletionTimestamp() {
130 if (state == State.COMPLETE || state == State.ABORTED) {
131 return stateTime;
132 }
133 return -1;
134 }
135
136 @Override
137 public void markComplete(String status) {
138 setState(State.COMPLETE);
139 setStatus(status);
140 }
141
142 @Override
143 public void pause(String msg) {
144 setState(State.WAITING);
145 setStatus(msg);
146 }
147
148 @Override
149 public void resume(String msg) {
150 setState(State.RUNNING);
151 setStatus(msg);
152 }
153
154 @Override
155 public void abort(String msg) {
156 setStatus(msg);
157 setState(State.ABORTED);
158 }
159
160 @Override
161 public void setStatus(String status) {
162 this.status = status;
163 statusTime = System.currentTimeMillis();
164 if (journalEnabled) {
165 journal.add(new StatusJournalEntryImpl(this.status, statusTime));
166 }
167 }
168
169 protected void setState(State state) {
170 this.state = state;
171 stateTime = System.currentTimeMillis();
172 }
173
174 @Override
175 public void setDescription(String description) {
176 this.description = description;
177 }
178
179 @Override
180 public void setWarnTime(long t) {
181 this.warnTime = t;
182 }
183
184 @Override
185 public void cleanup() {
186 if (state == State.RUNNING) {
187 setState(State.ABORTED);
188 }
189 }
190
191
192
193
194
195 public void expireNow() {
196 stateTime -= 180 * 1000;
197 }
198
199 @Override
200 public Map<String, Object> toMap() {
201 Map<String, Object> map = new HashMap<String, Object>();
202 map.put("description", getDescription());
203 map.put("status", getStatus());
204 map.put("state", getState());
205 map.put("starttimems", getStartTime());
206 map.put("statustimems", getCompletionTimestamp());
207 map.put("statetimems", getCompletionTimestamp());
208 return map;
209 }
210
211 @Override
212 public String toJSON() throws IOException {
213 return GSON.toJson(toMap());
214 }
215
216 @Override
217 public String toString() {
218 StringBuilder sb = new StringBuilder(512);
219 sb.append(getDescription());
220 sb.append(": status=");
221 sb.append(getStatus());
222 sb.append(", state=");
223 sb.append(getState());
224 sb.append(", startTime=");
225 sb.append(getStartTime());
226 sb.append(", completionTime=");
227 sb.append(getCompletionTimestamp());
228 return sb.toString();
229 }
230
231
232
233
234
235
236
237 @Override
238 public List<StatusJournalEntry> getStatusJournal() {
239 if (journal == null) {
240 return Collections.emptyList();
241 } else {
242 return Collections.unmodifiableList(journal);
243 }
244 }
245
246
247
248
249
250 @Override
251 public void enableStatusJournal(boolean includeCurrentStatus) {
252 if (journalEnabled && journal != null) {
253 return;
254 }
255 journalEnabled = true;
256 if (journal == null) {
257 journal = new ArrayList<StatusJournalEntry>();
258 }
259 if (includeCurrentStatus && status != null) {
260 journal.add(new StatusJournalEntryImpl(status, statusTime));
261 }
262 }
263
264 @Override
265 public void disableStatusJournal() {
266 journalEnabled = false;
267 }
268
269 @Override
270 public String prettyPrintJournal() {
271 StringBuilder sb = new StringBuilder();
272 for (int i = 0; i < journal.size(); i++) {
273 StatusJournalEntry je = journal.get(i);
274 sb.append(je.toString());
275 if (i != 0) {
276 StatusJournalEntry jep = journal.get(i-1);
277 long delta = je.getTimeStamp() - jep.getTimeStamp();
278 if (delta != 0) {
279 sb.append(" (+" + delta + " ms)");
280 }
281 }
282 sb.append("\n");
283 }
284 return sb.toString();
285 }
286
287 }