1 8 9 package mx4j.monitor; 10 11 import java.math.BigInteger ; 12 import javax.management.MBeanNotificationInfo ; 13 import javax.management.NotCompliantMBeanException ; 14 import javax.management.ObjectName ; 15 import javax.management.monitor.MonitorNotification ; 16 17 import mx4j.log.Logger; 18 19 22 public class MX4JCounterMonitor extends MX4JMonitor implements MX4JCounterMonitorMBean 23 { 24 private static Integer ZERO = new Integer (0); 25 26 private Number threshold = ZERO; 27 private Number offset = ZERO; 28 private Number modulus = ZERO; 29 private boolean notify; 30 private boolean differenceMode; 31 32 public MX4JCounterMonitor() throws NotCompliantMBeanException 33 { 34 super(MX4JCounterMonitorMBean.class); 35 } 36 37 protected MX4JCounterMonitor(Class management) throws NotCompliantMBeanException 38 { 39 super(management); 40 } 41 42 public MBeanNotificationInfo [] getNotificationInfo() 43 { 44 return new MBeanNotificationInfo [0]; 46 } 47 48 public synchronized Number getInitThreshold() 49 { 50 return threshold; 51 } 52 53 public void setInitThreshold(Number threshold) throws IllegalArgumentException 54 { 55 if (threshold == null || compare(threshold, ZERO) < 0) throw new IllegalArgumentException ("Threshold cannot be " + threshold); 56 this.threshold = threshold; 57 } 58 59 public synchronized Number getOffset() 60 { 61 return offset; 62 } 63 64 public void setOffset(Number offset) throws IllegalArgumentException 65 { 66 if (offset == null || compare(offset, ZERO) < 0) throw new IllegalArgumentException ("Offset cannot be " + offset); 67 this.offset = offset; 68 } 69 70 public Number getModulus() 71 { 72 return modulus; 73 } 74 75 public void setModulus(Number modulus) throws IllegalArgumentException 76 { 77 if (modulus == null || compare(modulus, ZERO) < 0) throw new IllegalArgumentException ("Modulus cannot be " + modulus); 78 this.modulus = modulus; 79 } 80 81 public boolean getNotify() 82 { 83 return notify; 84 } 85 86 public void setNotify(boolean notify) 87 { 88 this.notify = notify; 89 } 90 91 public boolean getDifferenceMode() 92 { 93 return differenceMode; 94 } 95 96 public void setDifferenceMode(boolean mode) 97 { 98 this.differenceMode = mode; 99 } 100 101 public Number getDerivedGauge(ObjectName name) 102 { 103 CounterMonitorInfo info = (CounterMonitorInfo)getMonitorInfo(name); 104 return info.getGauge(); 105 } 106 107 public long getDerivedGaugeTimeStamp(ObjectName name) 108 { 109 CounterMonitorInfo info = (CounterMonitorInfo)getMonitorInfo(name); 110 return info.getTimestamp(); 111 } 112 113 public Number getThreshold(ObjectName name) 114 { 115 CounterMonitorInfo info = (CounterMonitorInfo)getMonitorInfo(name); 116 return info.getThreshold(); 117 } 118 119 protected int compare(Number left, Number right) 120 { 121 if (left instanceof BigInteger && right instanceof BigInteger ) return ((BigInteger )left).compareTo((BigInteger )right); 122 if (left.longValue() == right.longValue()) return 0; 123 return left.longValue() > right.longValue() ? 1 : -1; 124 } 125 126 protected Number sum(Number left, Number right) 127 { 128 if (left instanceof BigInteger && right instanceof BigInteger ) return ((BigInteger )left).add((BigInteger )right); 129 if (left instanceof BigInteger ) return ((BigInteger )left).add(BigInteger.valueOf(right.longValue())); 130 if (right instanceof BigInteger ) return ((BigInteger )right).add(BigInteger.valueOf(left.longValue())); 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 Number sub(Number left, Number right) 139 { 140 if (left instanceof BigInteger && right instanceof BigInteger ) return ((BigInteger )left).subtract((BigInteger )right); 141 if (left instanceof BigInteger ) return ((BigInteger )left).subtract(BigInteger.valueOf(right.longValue())); 142 if (left instanceof Long || right instanceof Long ) return new Long (left.longValue() - right.longValue()); 143 if (left instanceof Integer || right instanceof Integer ) return new Integer (left.intValue() - right.intValue()); 144 if (left instanceof Short || right instanceof Short ) return new Short ((short)(left.shortValue() - right.shortValue())); 145 if (left instanceof Byte || right instanceof Byte ) return new Byte ((byte)(left.byteValue() - right.byteValue())); 146 return null; 147 } 148 149 protected void monitor(ObjectName name, String attribute, Object value, MonitorInfo monitorInfo) 150 { 151 if (!(value instanceof Number )) 152 { 153 sendErrorNotification(monitorInfo, MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR, "Attribute type must be a Number, not " + value.getClass(), name, attribute); 154 return; 155 } 156 157 Number threshold = null; 159 Number offset = null; 160 Number modulus = null; 161 synchronized (this) 162 { 163 threshold = getThreshold(name); 164 offset = getOffset(); 165 modulus = getModulus(); 166 } 167 Number counter = (Number )value; 168 Class gaugeClass = counter.getClass(); 169 if (threshold != ZERO && threshold.getClass() != gaugeClass) 170 { 171 sendErrorNotification(monitorInfo, MonitorNotification.THRESHOLD_ERROR, "Threshold type " + threshold.getClass() + " must be of same type of the attribute " + gaugeClass, name, attribute); 172 return; 173 } 174 if (offset != ZERO && offset.getClass() != gaugeClass) 175 { 176 sendErrorNotification(monitorInfo, MonitorNotification.THRESHOLD_ERROR, "Offset type " + offset.getClass() + " must be of same type of the attribute " + gaugeClass, name, attribute); 177 return; 178 } 179 if (modulus != ZERO && modulus.getClass() != gaugeClass) 180 { 181 sendErrorNotification(monitorInfo, MonitorNotification.THRESHOLD_ERROR, "Modulus type " + modulus.getClass() + " must be of same type of the attribute " + gaugeClass, name, attribute); 182 return; 183 } 184 185 Logger logger = getLogger(); 186 187 CounterMonitorInfo info = (CounterMonitorInfo)monitorInfo; 189 190 Number lastCounter = info.getCounter(); 192 boolean rolledOver = (lastCounter != null) ? compare(counter, lastCounter) < 0 : false; 193 194 Number vt; 196 if (getDifferenceMode()) 197 { 198 if (lastCounter == null) 199 { 200 vt = ZERO; 202 } 203 else 204 { 205 vt = sub(counter, lastCounter); 206 if (rolledOver) 207 { 208 vt = sum(vt, modulus); 210 } 211 212 if (rolledOver) 214 { 215 threshold = getInitThreshold(); 216 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Threshold has been rolled over, new value = " + threshold); 217 } 218 } 219 } 220 else 221 { 222 vt = counter; 223 224 if (rolledOver && compare(modulus, ZERO) > 0 && compare(threshold, modulus) > 0) 226 { 227 threshold = getInitThreshold(); 228 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Threshold has been rolled over, new value = " + threshold); 229 } 230 } 231 232 if (logger.isEnabledFor(Logger.DEBUG)) 233 { 234 logger.debug("Computing gauge, previous values are: " + info); 235 logger.debug("Current values are: threshold=" + threshold + ", offset=" + offset + ", modulus=" + modulus); 236 logger.debug("V[t] = " + vt + ", rolledOver = " + rolledOver); 237 } 238 239 info.setGauge(vt); 240 241 242 boolean notified; 243 if (compare(vt, threshold) >= 0) 244 { 245 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Threshold exceeded: V[t]=" + vt + ", threshold=" + threshold); 246 247 if (getNotify()) 249 { 250 if (info.isThresholdNotified()) 251 { 252 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Threshold exceeded already notified"); 253 } 254 else 255 { 256 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Sending threshold exceeded notification"); 257 sendNotification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, "Threshold " + threshold + " exceeded: " + vt, name, attribute, counter, threshold); 258 } 259 notified = true; 260 } 261 else 262 { 263 notified = false; 264 } 265 266 if (compare(offset, ZERO) > 0) 268 { 269 do 270 { 271 threshold = sum(threshold, offset); 272 } while (compare(vt, threshold) >= 0); 273 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Threshold has been offset, new value = " + threshold); 274 275 } 276 } 277 else 278 { 279 notified = false; 281 } 282 283 CounterMonitorInfo newInfo = (CounterMonitorInfo)createMonitorInfo(); 284 newInfo.setThresholdNotified(notified); 285 newInfo.setCounter(counter); 286 newInfo.setGauge(vt); 287 newInfo.setTimestamp(System.currentTimeMillis()); 288 newInfo.setThreshold(threshold); 289 putMonitorInfo(name, newInfo); 290 } 291 292 protected MonitorInfo createMonitorInfo() 293 { 294 return new CounterMonitorInfo(); 295 } 296 297 protected class CounterMonitorInfo extends MonitorInfo 298 { 299 private boolean thresholdNotified; 300 private Number counter = null; 301 private Number gauge = ZERO; 302 private long timestamp; 303 private Number threshold = ZERO; 304 305 public void setThreshold(Number threshold) 306 { 307 this.threshold = threshold; 308 } 309 310 public Number getThreshold() 311 { 312 if (threshold == ZERO) return getInitThreshold(); 313 return threshold; 314 } 315 316 public void setThresholdNotified(boolean thresholdNotified) 317 { 318 this.thresholdNotified = thresholdNotified; 319 } 320 321 public boolean isThresholdNotified() 322 { 323 return thresholdNotified; 324 } 325 326 public void setCounter(Number counter) 327 { 328 this.counter = counter; 329 } 330 331 public Number getCounter() 332 { 333 return counter; 334 } 335 336 public void setGauge(Number gauge) 337 { 338 this.gauge = gauge; 339 } 340 341 public Number getGauge() 342 { 343 return gauge; 344 } 345 346 public void setTimestamp(long timestamp) 347 { 348 this.timestamp = timestamp; 349 } 350 351 public long getTimestamp() 352 { 353 return timestamp; 354 } 355 356 public void clearNotificationStatus() 357 { 358 super.clearNotificationStatus(); 359 thresholdNotified = false; 360 } 361 362 public String toString() 363 { 364 StringBuffer buffer = new StringBuffer (super.toString()); 365 buffer.append(", thresholdNotified=").append(isThresholdNotified()); 366 buffer.append(", gauge=").append(getGauge()); 367 buffer.append(", counter=").append(getCounter()); 368 buffer.append(", threshold=").append(threshold); 369 return buffer.toString(); 370 } 371 } 372 } 373 | Popular Tags |