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.12
Committed: Fri Mar 9 03:30:55 2001 UTC (23 years, 2 months ago) by ajm
Branch: MAIN
Changes since 1.11: +5 -5 lines
Log Message:
TOTALLY re-wrote the Register class and made appropriate changes thoughout.  It
is now much more obvious what is going on in many places.

The problem was probably caused by doing CPU as a first monitor and hard coding
the number of attributes a Register stores.  Now if a monitor wants to store
multiple attributes, it has to do that itself.  This makes alot of things
much more readable and inteligable as a result.

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