ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/client/monitors/Heartbeat__Monitor.java
Revision: 1.3
Committed: Mon Mar 5 23:14:30 2001 UTC (23 years, 2 months ago) by tdb
Branch: MAIN
Changes since 1.2: +25 -12 lines
Log Message:
Added error checking, and also changed to an "implements Runnable" Thread. This
is because we may be moving to an abstract class soon.

File Contents

# Content
1 //---PACKAGE DECLARATION---
2 package uk.ac.ukc.iscream.client.monitors;
3
4 //---IMPORTS---
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import uk.ac.ukc.iscream.client.*;
8 import uk.ac.ukc.iscream.core.*;
9 import uk.ac.ukc.iscream.util.*;
10 import uk.ac.ukc.iscream.componentmanager.*;
11
12 /**
13 * This Monitor watches heartbeats
14 *
15 * @author $Author: tdb1 $
16 * @version $Id: Heartbeat__Monitor.java,v 1.2 2001/03/05 15:47:48 tdb1 Exp $
17 */
18 public class Heartbeat__Monitor implements PluginMonitor, Runnable {
19
20 //---FINAL ATTRIBUTES---
21
22 /**
23 * The current CVS revision of this class
24 */
25 public final String REVISION = "$Revision: 1.2 $";
26
27 public final String DESC = "Monitors Heartbeats.";
28
29 public final int DEFAULT_CHECK_PERIOD = 60;
30
31 //---STATIC METHODS---
32
33 //---CONSTRUCTORS---
34
35 public Heartbeat__Monitor() {
36 new Thread(this).start();
37 }
38
39 //---PUBLIC METHODS---
40
41 public void run() {
42 ConfigurationProxy cp = ConfigurationProxy.getInstance();
43 while(true) {
44 // this cycle period of this monitor's checks
45 int checkPeriod = 0;
46 try {
47 checkPeriod = Integer.parseInt(cp.getProperty(_name, "Monitor.Heartbeat.checkPeriod"));
48 } catch (PropertyNotFoundException e) {
49 checkPeriod = DEFAULT_CHECK_PERIOD;
50 _logger.write(toString(), Logger.WARNING, "Monitor.Heartbeat.checkPeriod value unavailable using default of " + checkPeriod + " seconds");
51 } catch (NumberFormatException e) {
52 checkPeriod = DEFAULT_CHECK_PERIOD;
53 _logger.write(toString(), Logger.WARNING, "Erronous Monitor.Heartbeat.checkPeriod value in configuration using default of " + checkPeriod + " seconds");
54 }
55
56 // perform the checks (use HB hash, although they *should* be the same)
57 Iterator i = _hostsHB.keySet().iterator();
58 while(i.hasNext()) {
59 // get host
60 String source = (String) i.next();
61 // check it
62 analyseHB(source);
63 }
64
65 // wait a while
66 try {Thread.sleep(checkPeriod * 1000);} catch (InterruptedException e) {}
67 }
68 }
69
70 // only use attribute num 0 :)
71 public void analyseHB(String source) {
72 ConfigurationProxy cp = ConfigurationProxy.getInstance();
73 Register reg = (Register) _hostsReg.get(source);
74
75 // get host's HB interval (seconds)
76 // this should always exist, thus we set to 0
77 int hostHBinterval = 0;
78 try {
79 hostHBinterval = Integer.parseInt(cp.getProperty("Host."+source, "TCPUpdateTime"));
80 } catch (PropertyNotFoundException e) {
81 hostHBinterval = 0;
82 _logger.write(toString(), Logger.WARNING, "TCPUpdateTime value unavailable using default of " + hostHBinterval + " seconds");
83 } catch (NumberFormatException e) {
84 hostHBinterval = 0;
85 _logger.write(toString(), Logger.WARNING, "Erronous TCPUpdateTime value in configuration using default of " + hostHBinterval + " seconds");
86 }
87
88 // get host's last HB time (seconds)
89 long lastHeartbeat = ((HeartbeatHolder) _hostsHB.get(source)).getLastHeartbeat();
90 // time since last heartbeat (seconds)
91 long timeSinceLastHB = (System.currentTimeMillis()/1000) - lastHeartbeat;
92
93 // find out the threshold level we're at
94 int result = checkAttributeThreshold(timeSinceLastHB, reg);
95
96 // decide what threshold level we're on, if we've changed, record that
97 if (result != reg.getLastThresholdLevel(0)) {
98 reg.setLastThresholdLevel(0, result);
99 }
100
101 // as long as this isn't a normal level
102 if(reg.getLastThresholdLevel(0) != Alert.thresholdNORMAL) {
103 // if the time since the last alert is more than the time for
104 // its timeout, fire an alert, escalate the alert
105 long timeout = reg.getLastAlertTimeout(0);
106 if ((timeout > 0) && (reg.getTimeLastSent(0) > 0)) {
107 if((System.currentTimeMillis() - reg.getTimeLastSent(0)) > timeout) {
108 int lastAlert = reg.getLastAlertLevel(0);
109 reg.escalateAlert(0);
110 reg.setTimeLastSent(0, System.currentTimeMillis());
111 reg.setLastAlertTimeout(0, reg.getAlertTimeout(reg.getLastAlertLevel(0), 0));
112 // -- SEND
113 fireAlert(source, timeSinceLastHB, reg, lastAlert);
114 }
115 // if we don't have a timeout configured...we got STRAIGHT to the next level
116 } else {
117 int lastAlert = reg.getLastAlertLevel(0);
118 reg.escalateAlert(0);
119 reg.setTimeLastSent(0, System.currentTimeMillis());
120 reg.setLastAlertTimeout(0, reg.getAlertTimeout(reg.getLastAlertLevel(0), 0));
121 // -- SEND
122 fireAlert(source, timeSinceLastHB, reg, lastAlert);
123 }
124
125 // we must be on ok, check the timeout value for this
126 } else {
127 // if we were on an OK alert before, then we don't do anything
128 // but if we weren't we only set OK, once the timeout of the last
129 // alert has occourd
130 if (reg.getLastAlertLevel(0) != Alert.alertOK) {
131 long timeout = reg.getLastAlertTimeout(0);
132 if ((timeout > 0) && (reg.getTimeLastSent(0) > 0)) {
133 if ((System.currentTimeMillis() - reg.getTimeLastSent(0)) > timeout) {
134 int lastAlert = reg.getLastAlertLevel(0);
135 reg.setLastAlertLevel(0, Alert.alertOK);
136 reg.setTimeLastSent(0, System.currentTimeMillis());
137 reg.setLastAlertTimeout(0, timeout);
138 // -- SEND
139 fireAlert(source, timeSinceLastHB, reg, lastAlert);
140 }
141 }
142 }
143 }
144 }
145
146 public void analysePacket(XMLPacket packet) {
147 if (packet.getParam("packet.attributes.type").equals("heartbeat")) {
148 String source = packet.getParam("packet.attributes.machine_name");
149 if (!_hostsHB.containsKey(source)) {
150 _hostsReg.put(source, new Register(source, _name, 1));
151 _hostsHB.put(source, new HeartbeatHolder());
152 }
153 HeartbeatHolder lastHeartbeat = (HeartbeatHolder) _hostsHB.get(source);
154 lastHeartbeat.setLastHeartbeat(System.currentTimeMillis()/1000);
155 }
156 }
157
158 /**
159 * Overrides the {@link java.lang.Object#toString() Object.toString()}
160 * method to provide clean logging (every class should have this).
161 *
162 * This uses the uk.ac.ukc.iscream.util.NameFormat class
163 * to format the toString()
164 *
165 * @return the name of this class and its CVS revision
166 */
167 public String toString() {
168 return FormatName.getName(
169 _name,
170 getClass().getName(),
171 REVISION);
172 }
173
174 /**
175 * return the String representation of what the monitor does
176 */
177 public String getDescription(){
178 return DESC;
179 }
180
181 //---PRIVATE METHODS---
182
183 private int checkAttributeThreshold(long timeSinceLastHB, Register reg) {
184 for(int thresholdLevel = Alert.thresholdLevels.length - 1; thresholdLevel >= 0; thresholdLevel--) {
185 if (reg.getThreshold(thresholdLevel) != -1.0) {
186 if (((long) reg.getThreshold(thresholdLevel)) < timeSinceLastHB) {
187 return thresholdLevel;
188 }
189 }
190 }
191 return 0;
192 }
193
194 private void fireAlert(String source, long timeSinceLastHB, Register reg, int lastAlert) {
195 int alertLevel = reg.getLastAlertLevel(0);
196 int thresholdLevel = reg.getLastThresholdLevel(0);
197 String currentValue = String.valueOf(timeSinceLastHB);
198 String attributeName = "Heartbeat";
199 String thresholdValue = String.valueOf(reg.getThreshold(thresholdLevel));
200 String time = Long.toString(reg.getAlertTimeout(reg.getLastAlertLevel(0), 0) / 1000);
201 if (thresholdLevel == Alert.thresholdNORMAL) {
202 thresholdValue = "-";
203 }
204 if (alertLevel == Alert.alertOK) {
205 time = "0";
206 }
207 Alert alert = new Alert(alertLevel, lastAlert, thresholdLevel, source, thresholdValue, currentValue, attributeName, time);
208 _alerterQueue.add(alert);
209 _logger.write(toString(), Logger.DEBUG, "Fired alert for source:" + source + " at alert level:" + Alert.alertLevels[alertLevel] + " on:" + attributeName + " for threshold level:" + Alert.thresholdLevels[thresholdLevel] + " at:" + currentValue + " exceeding threshold of:" +thresholdValue + " next alert sent in:" + time + "secs");
210 }
211
212 //---ACCESSOR/MUTATOR METHODS---
213
214 //---ATTRIBUTES---
215
216 /**
217 * This is the friendly identifier of the
218 * component this class is running in.
219 * eg, a Filter may be called "filter1",
220 * If this class does not have an owning
221 * component, a name from the configuration
222 * can be placed here. This name could also
223 * be changed to null for utility classes.
224 */
225 private String _name = "Heartbeat";
226
227 /**
228 * This holds a reference to the
229 * system logger that is being used.
230 */
231 private Logger _logger = ReferenceManager.getInstance().getLogger();
232
233 private Queue _alerterQueue = ClientMain._alerterQueue;
234
235 /**
236 * A reference to the configuration proxy in use
237 */
238 private ConfigurationProxy _cp = ConfigurationProxy.getInstance();
239
240 private HashMap _hostsHB = new HashMap();
241 private HashMap _hostsReg = new HashMap();
242
243 //---STATIC ATTRIBUTES---
244
245 //---INNER CLASSES---
246
247 private class HeartbeatHolder {
248
249 public void setLastHeartbeat(long lastHeartbeat) {
250 _lastHeartbeat = lastHeartbeat;
251 }
252
253 public long getLastHeartbeat() {
254 return _lastHeartbeat;
255 }
256
257 private long _lastHeartbeat;
258 }
259
260 }