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.8
Committed: Wed Mar 7 01:22:47 2001 UTC (23 years, 3 months ago) by tdb
Branch: MAIN
Changes since 1.7: +11 -4 lines
Log Message:
The threshold values now represent the time in seconds "since the heartbeat was
expected". Before this change, you could set a value of less than the heartbeat
period and alerts would be fired when the heartbeat is simply not due.

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.7 2001/03/06 22:35:01 tdb1 Exp $
17 */
18 public class Heartbeat__Monitor extends MonitorSkeleton implements Runnable {
19
20 //---FINAL ATTRIBUTES---
21
22 /**
23 * The current CVS revision of this class
24 */
25 public final String REVISION = "$Revision: 1.7 $";
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 = _hosts.keySet().iterator();
58 while(i.hasNext()) {
59 // get host
60 String source = (String) i.next();
61 // check it
62 boolean remove = analyseHB(source);
63 if(remove) {
64 i.remove();
65 }
66 }
67
68 // wait a while
69 try {Thread.sleep(checkPeriod * 1000);} catch (InterruptedException e) {}
70 }
71 }
72
73 public void analysePacket(XMLPacket packet) {
74 if (packet.getParam("packet.attributes.type").equals("heartbeat")) {
75 String source = packet.getParam("packet.attributes.machine_name");
76 if (!_hosts.containsKey(source)) {
77 HashMap registerHash = new HashMap();
78 registerHash.put(source, new Register(source, _name, 1));
79 _hosts.put(source, new HeartbeatHolder(registerHash));
80 }
81 HeartbeatHolder lastHeartbeat = (HeartbeatHolder) _hosts.get(source);
82 lastHeartbeat.setLastHeartbeat(System.currentTimeMillis()/1000);
83 }
84 }
85
86 /**
87 * Overrides the {@link java.lang.Object#toString() Object.toString()}
88 * method to provide clean logging (every class should have this).
89 *
90 * This uses the uk.ac.ukc.iscream.util.NameFormat class
91 * to format the toString()
92 *
93 * @return the name of this class and its CVS revision
94 */
95 public String toString() {
96 return FormatName.getName(
97 _name,
98 getClass().getName(),
99 REVISION);
100 }
101
102 /**
103 * return the String representation of what the monitor does
104 */
105 public String getDescription(){
106 return DESC;
107 }
108
109 //---PRIVATE METHODS---
110
111 private boolean analyseHB(String source) {
112 ConfigurationProxy cp = ConfigurationProxy.getInstance();
113 HeartbeatHolder hbHolder = (HeartbeatHolder) _hosts.get(source);
114 Register reg = (Register) ((HashMap) hbHolder.getRegisterHash()).get(source);
115
116 // get host's HB interval (seconds)
117 // this should always exist, thus we set to 0
118 int hostHBinterval = 0;
119 try {
120 hostHBinterval = Integer.parseInt(cp.getProperty("Host."+source, "Host.TCPUpdateTime"));
121 } catch (PropertyNotFoundException e) {
122 hostHBinterval = 0;
123 _logger.write(toString(), Logger.WARNING, "TCPUpdateTime value unavailable using default of " + hostHBinterval + " seconds");
124 } catch (NumberFormatException e) {
125 hostHBinterval = 0;
126 _logger.write(toString(), Logger.WARNING, "Erronous TCPUpdateTime value in configuration using default of " + hostHBinterval + " seconds");
127 }
128
129 // get host's last HB time (seconds)
130 long lastHeartbeat = hbHolder.getLastHeartbeat();
131 // time since last heartbeat (seconds)
132 long timeSinceLastHB = (System.currentTimeMillis()/1000) - lastHeartbeat;
133 // time since (or until if negative) the expected heartbeat
134 long timeSinceExpectedHB = timeSinceLastHB + (long) hostHBinterval;
135
136 // best do a check in case the expected heartbeat is in the future
137 if(timeSinceExpectedHB < 0) {
138 timeSinceExpectedHB = 0;
139 }
140
141 // find out the threshold level we're at
142 int newThreshold = checkAttributeThreshold(timeSinceExpectedHB, reg);
143
144 // process the alert
145 processAlert(newThreshold, 0, "Heartbeat", reg, source, String.valueOf(timeSinceExpectedHB));
146
147 if(reg.getLastAlertLevel(0) == Alert.alertFINAL) {
148 return true;
149 }
150 return false;
151 }
152
153 private int checkAttributeThreshold(long timeSinceLastHB, Register reg) {
154 for(int thresholdLevel = Alert.thresholdLevels.length - 1; thresholdLevel >= 0; thresholdLevel--) {
155 if (reg.getThreshold(thresholdLevel) != -1.0) {
156 if (((long) reg.getThreshold(thresholdLevel)) < timeSinceLastHB) {
157 return thresholdLevel;
158 }
159 }
160 }
161 return Alert.thresholdNORMAL;
162 }
163
164 //---ACCESSOR/MUTATOR METHODS---
165
166 //---ATTRIBUTES---
167
168 /**
169 * This is the friendly identifier of the
170 * component this class is running in.
171 * eg, a Filter may be called "filter1",
172 * If this class does not have an owning
173 * component, a name from the configuration
174 * can be placed here. This name could also
175 * be changed to null for utility classes.
176 */
177 private String _name = "Heartbeat";
178
179 /**
180 * A reference to the configuration proxy in use
181 */
182 private ConfigurationProxy _cp = ConfigurationProxy.getInstance();
183
184 private HashMap _hosts = new HashMap();
185
186 //---STATIC ATTRIBUTES---
187
188 //---INNER CLASSES---
189
190 private class HeartbeatHolder {
191
192 public HeartbeatHolder(HashMap registerHash) {
193 _registerHash = registerHash;
194 }
195
196 public void setLastHeartbeat(long lastHeartbeat) {
197 _lastHeartbeat = lastHeartbeat;
198 }
199
200 public long getLastHeartbeat() {
201 return _lastHeartbeat;
202 }
203
204 public HashMap getRegisterHash() {
205 return _registerHash;
206 }
207
208 private long _lastHeartbeat;
209 private HashMap _registerHash;
210 }
211
212 }