1 8 9 package mx4j.monitor; 10 11 import java.math.BigDecimal ; 12 import java.math.BigInteger ; 13 import javax.management.MBeanNotificationInfo ; 14 import javax.management.NotCompliantMBeanException ; 15 import javax.management.ObjectName ; 16 import javax.management.monitor.MonitorNotification ; 17 18 import mx4j.log.Logger; 19 20 23 public class MX4JGaugeMonitor extends MX4JMonitor implements MX4JGaugeMonitorMBean 24 { 25 private static Integer ZERO = new Integer (0); 26 27 private Number highThreshold = ZERO; 28 private Number lowThreshold = ZERO; 29 private boolean notifyHigh; 30 private boolean notifyLow; 31 private boolean differenceMode; 32 33 public MX4JGaugeMonitor() throws NotCompliantMBeanException 34 { 35 super(MX4JGaugeMonitorMBean.class); 36 } 37 38 protected MX4JGaugeMonitor(Class management) throws NotCompliantMBeanException 39 { 40 super(management); 41 } 42 43 public MBeanNotificationInfo [] getNotificationInfo() 44 { 45 return new MBeanNotificationInfo [0]; 47 } 48 49 public synchronized Number getHighThreshold() 50 { 51 return highThreshold; 52 } 53 54 public synchronized Number getLowThreshold() 55 { 56 return lowThreshold; 57 } 58 59 public void setThresholds(Number highValue, Number lowValue) throws IllegalArgumentException 60 { 61 if (highValue == null) throw new IllegalArgumentException ("High Threshold cannot be null"); 62 if (lowValue == null) throw new IllegalArgumentException ("Low Threshold cannot be null"); 63 if (highValue.getClass() != lowValue.getClass()) throw new IllegalArgumentException ("Thresholds must be of the same type"); 64 if (compare(highValue, lowValue) < 0) throw new IllegalArgumentException ("High threshold cannot be lower than low threshold"); 65 highThreshold = highValue; 66 lowThreshold = lowValue; 67 } 68 69 public synchronized boolean getNotifyHigh() 70 { 71 return notifyHigh; 72 } 73 74 public synchronized boolean getNotifyLow() 75 { 76 return notifyLow; 77 } 78 79 public synchronized void setNotifyHigh(boolean notifyHigh) 80 { 81 this.notifyHigh = notifyHigh; 82 } 83 84 public synchronized void setNotifyLow(boolean notifyLow) 85 { 86 this.notifyLow = notifyLow; 87 } 88 89 public synchronized boolean getDifferenceMode() 90 { 91 return differenceMode; 92 } 93 94 public synchronized void setDifferenceMode(boolean differenceMode) 95 { 96 this.differenceMode = differenceMode; 97 } 98 99 public Number getDerivedGauge(ObjectName objectName) 100 { 101 GaugeMonitorInfo info = (GaugeMonitorInfo)getMonitorInfo(objectName); 102 return info.getGauge(); 103 } 104 105 public long getDerivedGaugeTimeStamp(ObjectName objectName) 106 { 107 GaugeMonitorInfo info = (GaugeMonitorInfo)getMonitorInfo(objectName); 108 return info.getTimestamp(); 109 } 110 111 protected MonitorInfo createMonitorInfo() 112 { 113 return new GaugeMonitorInfo(); 114 } 115 116 protected int compare(Number left, Number right) 117 { 118 if (left instanceof BigDecimal && right instanceof BigDecimal ) return ((BigDecimal )left).compareTo((BigDecimal )right); 119 if (left instanceof BigInteger && right instanceof BigInteger ) return ((BigInteger )left).compareTo((BigInteger )right); 120 return new Double (left.doubleValue()).compareTo(new Double (right.doubleValue())); 121 } 122 123 protected Number sub(Number left, Number right) 124 { 125 if (left instanceof BigDecimal && right instanceof BigDecimal ) return ((BigDecimal )left).subtract((BigDecimal )right); 126 if (left instanceof BigDecimal ) return ((BigDecimal )left).subtract(new BigDecimal (right.doubleValue())); 127 if (left instanceof BigInteger && right instanceof BigInteger ) return ((BigInteger )left).subtract((BigInteger )right); 128 if (left instanceof BigInteger ) return ((BigInteger )left).subtract(BigInteger.valueOf(right.longValue())); 129 if (left instanceof Double || right instanceof Double ) return new Double (left.doubleValue() - right.doubleValue()); 130 if (left instanceof Float || right instanceof Float ) return new Float (left.floatValue() - right.floatValue()); 131 if (left instanceof Long || right instanceof Long ) return new Long (left.longValue() - right.longValue()); 132 if (left instanceof Integer || right instanceof Integer ) return new Integer (left.intValue() - right.intValue()); 133 if (left instanceof Short || right instanceof Short ) return new Short ((short)(left.shortValue() - right.shortValue())); 134 if (left instanceof Byte || right instanceof Byte ) return new Byte ((byte)(left.byteValue() - right.byteValue())); 135 return null; 136 } 137 138 protected void monitor(ObjectName name, String attribute, Object value, MonitorInfo monitorInfo) 139 { 140 if (!(value instanceof Number )) 141 { 142 sendErrorNotification(monitorInfo, MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR, "Attribute type must be a Number, not " + value.getClass(), name, attribute); 143 return; 144 } 145 146 Number gauge = (Number )value; 147 148 Number high = null; 150 Number low = null; 151 synchronized (this) 152 { 153 high = getHighThreshold(); 154 low = getLowThreshold(); 155 } 156 Class gaugeClass = gauge.getClass(); 157 if (high != ZERO && high.getClass() != gaugeClass) 158 { 159 sendErrorNotification(monitorInfo, MonitorNotification.THRESHOLD_ERROR, "Threshold type " + high.getClass() + " must be of same type of the attribute " + gaugeClass, name, attribute); 160 return; 161 } 162 if (low != ZERO && low.getClass() != gaugeClass) 163 { 164 sendErrorNotification(monitorInfo, MonitorNotification.THRESHOLD_ERROR, "Offset type " + low.getClass() + " must be of same type of the attribute " + gaugeClass, name, attribute); 165 return; 166 } 167 168 Logger logger = getLogger(); 169 170 GaugeMonitorInfo info = (GaugeMonitorInfo)monitorInfo; 172 if (logger.isEnabledFor(Logger.DEBUG)) 173 { 174 logger.debug("Computing gauge, previous values are: " + info); 175 logger.debug("Current values are: gauge=" + gauge + ", highThreshold=" + high + ", lowThreshold=" + low); 176 } 177 178 if (getDifferenceMode()) 179 { 180 Number diffGauge = sub(gauge, info.getGauge()); 181 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("CounterMonitor in difference mode, difference gauge=" + diffGauge); 182 compareAndSendNotification(diffGauge, low, high, info, name, attribute); 183 } 184 else 185 { 186 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("CounterMonitor in absolute mode, gauge=" + gauge); 187 compareAndSendNotification(gauge, low, high, info, name, attribute); 188 } 189 190 info.setGauge(gauge); 191 info.setTimestamp(System.currentTimeMillis()); 192 } 193 194 private void compareAndSendNotification(Number gauge, Number low, Number high, GaugeMonitorInfo info, ObjectName name, String attribute) 195 { 196 Logger logger = getLogger(); 197 198 if (info.isHighNotified() && compare(gauge, low) > 0) 199 { 200 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("High threshold " + high + " already notified, gauge " + gauge + " not below low threshold " + low); 201 return; 202 } 203 if (info.isLowNotified() && compare(gauge, high) < 0) 204 { 205 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Low threshold " + low + " already notified, gauge " + gauge + " not above high threshold " + high); 206 return; 207 } 208 209 if (compare(gauge, high) >= 0) 210 { 211 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Gauge above high threshold: gauge=" + gauge + ", high threshold=" + high + ", low threshold=" + low); 212 info.setLowNotified(false); 213 if (getNotifyHigh()) 214 { 215 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Sending high threshold exceeded notification"); 216 info.setHighNotified(true); 217 sendNotification(MonitorNotification.THRESHOLD_HIGH_VALUE_EXCEEDED, "High threshold " + high + " exceeded: " + gauge, name, attribute, gauge, high); 218 } 219 else 220 { 221 info.setHighNotified(false); 222 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("GaugeMonitor is configured in non-high-notification mode"); 223 } 224 } 225 else if (compare(gauge, low) <= 0) 226 { 227 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Gauge below low threshold: gauge=" + gauge + ", low threshold=" + low + ", high threshold=" + high); 228 info.setHighNotified(false); 229 if (getNotifyLow()) 230 { 231 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Sending low threshold exceeded notification"); 232 info.setLowNotified(true); 233 sendNotification(MonitorNotification.THRESHOLD_LOW_VALUE_EXCEEDED, "Low threshold " + low + " exceeded: " + gauge, name, attribute, gauge, low); 234 } 235 else 236 { 237 info.setLowNotified(false); 238 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("GaugeMonitor is configured in non-low-notification mode"); 239 } 240 } 241 else 242 { 243 info.setHighNotified(false); 244 info.setLowNotified(false); 245 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Gauge between thresholds: gauge=" + gauge + ", low threshold=" + low + ", high threshold=" + high); 246 } 247 } 248 249 protected class GaugeMonitorInfo extends MonitorInfo 250 { 251 private Number gauge = ZERO; 252 private long timestamp; 253 private boolean highNotified; 254 private boolean lowNotified; 255 256 public Number getGauge() 257 { 258 return gauge; 259 } 260 261 public void setGauge(Number gauge) 262 { 263 this.gauge = gauge; 264 } 265 266 public long getTimestamp() 267 { 268 return timestamp; 269 } 270 271 public void setTimestamp(long timestamp) 272 { 273 this.timestamp = timestamp; 274 } 275 276 public boolean isHighNotified() 277 { 278 return highNotified; 279 } 280 281 public void setHighNotified(boolean highNotified) 282 { 283 this.highNotified = highNotified; 284 } 285 286 public boolean isLowNotified() 287 { 288 return lowNotified; 289 } 290 291 public void setLowNotified(boolean lowNotified) 292 { 293 this.lowNotified = lowNotified; 294 } 295 296 public void clearNotificationStatus() { 297 super.clearNotificationStatus(); 298 highNotified = false; 299 lowNotified = false; 300 } 301 302 public String toString() 303 { 304 StringBuffer buffer = new StringBuffer (super.toString()); 305 buffer.append(", gauge=").append(getGauge()); 306 buffer.append(", lowNotified=").append(isLowNotified()); 307 buffer.append(", highNotified=").append(isHighNotified()); 308 return buffer.toString(); 309 } 310 } 311 } 312 | Popular Tags |