1 32 33 package com.jeantessier.metrics; 34 35 import java.io.*; 36 import java.text.*; 37 import java.util.*; 38 39 import org.apache.log4j.*; 40 41 78 public class StatisticalMeasurement extends MeasurementBase { 79 private static final NumberFormat valueFormat = new DecimalFormat("#.##"); 80 81 82 public static final int DISPOSE_IGNORE = 0; 83 84 85 public static final int DISPOSE_MINIMUM = 1; 86 87 88 public static final int DISPOSE_MEDIAN = 2; 89 90 91 public static final int DISPOSE_AVERAGE = 3; 92 93 94 public static final int DISPOSE_STANDARD_DEVIATION = 4; 95 96 97 public static final int DISPOSE_MAXIMUM = 5; 98 99 100 public static final int DISPOSE_SUM = 6; 101 102 103 public static final int DISPOSE_NB_DATA_POINTS = 7; 104 105 public static String getDisposeLabel(int dispose) { 106 String result = ""; 107 108 switch (dispose) { 109 case DISPOSE_MINIMUM: 110 result = "minimum"; 111 break; 112 113 case DISPOSE_MEDIAN: 114 result = "median"; 115 break; 116 117 case DISPOSE_AVERAGE: 118 result = "average"; 119 break; 120 121 case DISPOSE_STANDARD_DEVIATION: 122 result = "standard deviation"; 123 break; 124 125 case DISPOSE_MAXIMUM: 126 result = "maximum"; 127 break; 128 129 case DISPOSE_SUM: 130 result = "sum"; 131 break; 132 133 case DISPOSE_NB_DATA_POINTS: 134 result = "number of data points"; 135 break; 136 137 case DISPOSE_IGNORE: 138 default: 139 break; 140 } 141 142 return result; 143 } 144 145 public static String getDisposeAbbreviation(int dispose) { 146 String result = ""; 147 148 switch (dispose) { 149 case DISPOSE_MINIMUM: 150 result = "min"; 151 break; 152 153 case DISPOSE_MEDIAN: 154 result = "med"; 155 break; 156 157 case DISPOSE_AVERAGE: 158 result = "avg"; 159 break; 160 161 case DISPOSE_STANDARD_DEVIATION: 162 result = "sdv"; 163 break; 164 165 case DISPOSE_MAXIMUM: 166 result = "max"; 167 break; 168 169 case DISPOSE_SUM: 170 result = "sum"; 171 break; 172 173 case DISPOSE_NB_DATA_POINTS: 174 result = "nb"; 175 break; 176 177 case DISPOSE_IGNORE: 178 default: 179 break; 180 } 181 182 return result; 183 } 184 185 private String monitoredMeasurement; 186 private int dispose; 187 private int selfDispose; 188 189 private List data = new LinkedList(); 190 191 private double minimum = 0.0; 192 private double median = 0.0; 193 private double average = 0.0; 194 private double standardDeviation = 0.0; 195 private double maximum = 0.0; 196 private double sum = 0.0; 197 private int nbDataPoints = 0; 198 199 private int nbSubmetrics = -1; 200 201 public StatisticalMeasurement(MeasurementDescriptor descriptor, Metrics context, String initText) { 202 super(descriptor, context, initText); 203 204 try { 205 BufferedReader in = new BufferedReader(new StringReader(initText)); 206 monitoredMeasurement = in.readLine().trim(); 207 208 synchronized (perl()) { 209 if (perl().match("/(.*)\\s+(dispose_\\w+)$/i", monitoredMeasurement)) { 210 monitoredMeasurement = perl().group(1); 211 212 String disposeText = perl().group(2); 213 214 if (disposeText.equalsIgnoreCase("DISPOSE_IGNORE")) { 215 dispose = DISPOSE_IGNORE; 216 } else if (disposeText.equalsIgnoreCase("DISPOSE_MINIMUM")) { 217 dispose = DISPOSE_MINIMUM; 218 } else if (disposeText.equalsIgnoreCase("DISPOSE_MEDIAN")) { 219 dispose = DISPOSE_MEDIAN; 220 } else if (disposeText.equalsIgnoreCase("DISPOSE_AVERAGE")) { 221 dispose = DISPOSE_AVERAGE; 222 } else if (disposeText.equalsIgnoreCase("DISPOSE_STANDARD_DEVIATION")) { 223 dispose = DISPOSE_STANDARD_DEVIATION; 224 } else if (disposeText.equalsIgnoreCase("DISPOSE_MAXIMUM")) { 225 dispose = DISPOSE_MAXIMUM; 226 } else if (disposeText.equalsIgnoreCase("DISPOSE_SUM")) { 227 dispose = DISPOSE_SUM; 228 } else if (disposeText.equalsIgnoreCase("DISPOSE_NB_DATA_POINTS")) { 229 dispose = DISPOSE_NB_DATA_POINTS; 230 } else { 231 dispose = DISPOSE_IGNORE; 232 } 233 } else { 234 dispose = DISPOSE_IGNORE; 235 } 236 } 237 238 String selfDisposeText = in.readLine(); 239 if (selfDisposeText != null) { 240 selfDisposeText = selfDisposeText.trim(); 241 242 if (selfDisposeText.equalsIgnoreCase("DISPOSE_IGNORE")) { 243 selfDispose = DISPOSE_IGNORE; 244 } else if (selfDisposeText.equalsIgnoreCase("DISPOSE_MINIMUM")) { 245 selfDispose = DISPOSE_MINIMUM; 246 } else if (selfDisposeText.equalsIgnoreCase("DISPOSE_MEDIAN")) { 247 selfDispose = DISPOSE_MEDIAN; 248 } else if (selfDisposeText.equalsIgnoreCase("DISPOSE_AVERAGE")) { 249 selfDispose = DISPOSE_AVERAGE; 250 } else if (selfDisposeText.equalsIgnoreCase("DISPOSE_STANDARD_DEVIATION")) { 251 selfDispose = DISPOSE_STANDARD_DEVIATION; 252 } else if (selfDisposeText.equalsIgnoreCase("DISPOSE_MAXIMUM")) { 253 selfDispose = DISPOSE_MAXIMUM; 254 } else if (selfDisposeText.equalsIgnoreCase("DISPOSE_SUM")) { 255 selfDispose = DISPOSE_SUM; 256 } else if (selfDisposeText.equalsIgnoreCase("DISPOSE_NB_DATA_POINTS")) { 257 selfDispose = DISPOSE_NB_DATA_POINTS; 258 } else { 259 selfDispose = DISPOSE_AVERAGE; 260 } 261 } else { 262 selfDispose = DISPOSE_AVERAGE; 263 } 264 265 in.close(); 266 } catch (Exception ex) { 267 Logger.getLogger(getClass()).debug("Cannot initialize with \"" + initText + "\"", ex); 268 monitoredMeasurement = null; 269 } 270 } 271 272 public double getMinimum() { 273 collectData(); 274 return minimum; 275 } 276 277 public double getMedian() { 278 collectData(); 279 return median; 280 } 281 282 public double getAverage() { 283 collectData(); 284 return average; 285 } 286 287 291 public double getStandardDeviation() { 292 collectData(); 293 return standardDeviation; 294 } 295 296 public double getMaximum() { 297 collectData(); 298 return maximum; 299 } 300 301 public double getSum() { 302 collectData(); 303 return sum; 304 } 305 306 public int getNbDataPoints() { 307 collectData(); 308 return nbDataPoints; 309 } 310 311 private void collectData() { 312 if (getContext().getSubMetrics().size() != nbSubmetrics) { 313 synchronized (this) { 314 if (getContext().getSubMetrics().size() != nbSubmetrics) { 315 data = new LinkedList(); 316 setEmpty(true); 317 318 Iterator i = getContext().getSubMetrics().iterator(); 319 while (i.hasNext()) { 320 visitMetrics((Metrics) i.next()); 321 } 322 323 if (!data.isEmpty()) { 324 Collections.sort(data); 325 326 minimum = ((Number ) data.get(0)).doubleValue(); 327 median = ((Number ) data.get(data.size() / 2)).doubleValue(); 328 maximum = ((Number ) data.get(data.size() - 1)).doubleValue(); 329 nbDataPoints = data.size(); 330 331 sum = 0.0; 332 Iterator j = data.iterator(); 333 while (j.hasNext()) { 334 sum += ((Number ) j.next()).doubleValue(); 335 } 336 } else { 337 minimum = Double.NaN; 338 median = Double.NaN; 339 maximum = Double.NaN; 340 nbDataPoints = 0; 341 sum = 0.0; 342 } 343 344 average = sum / nbDataPoints; 345 346 if (!data.isEmpty()) { 347 double temp = 0.0; 348 349 Iterator j = data.iterator(); 350 while (j.hasNext()) { 351 temp += Math.pow(((Number ) j.next()).doubleValue() - average, 2); 352 } 353 354 standardDeviation = Math.sqrt(temp / nbDataPoints); 355 } else { 356 standardDeviation = Double.NaN; 357 } 358 359 nbSubmetrics = getContext().getSubMetrics().size(); 360 } 361 } 362 } 363 } 364 365 private void visitMetrics(Metrics metrics) { 366 Logger.getLogger(getClass()).debug("VisitMetrics: " + metrics.getName()); 367 368 Measurement measurement = metrics.getMeasurement(monitoredMeasurement); 369 370 Logger.getLogger(getClass()).debug("measurement for " + monitoredMeasurement + " is " + measurement.getClass()); 371 372 if (measurement instanceof StatisticalMeasurement) { 373 StatisticalMeasurement stats = (StatisticalMeasurement) measurement; 374 375 Logger.getLogger(getClass()).debug("dispose of StatisticalMeasurements is " + dispose); 376 377 switch (dispose) { 378 case DISPOSE_MINIMUM: 379 Logger.getLogger(getClass()).debug("using Minimum(): " + stats.getMinimum()); 380 data.add(new Double (stats.getMinimum())); 381 break; 382 383 case DISPOSE_MEDIAN: 384 Logger.getLogger(getClass()).debug("using Median(): " + stats.getMedian()); 385 data.add(new Double (stats.getMedian())); 386 break; 387 388 case DISPOSE_AVERAGE: 389 Logger.getLogger(getClass()).debug("using Average(): " + stats.getAverage()); 390 data.add(new Double (stats.getAverage())); 391 break; 392 393 case DISPOSE_STANDARD_DEVIATION: 394 Logger.getLogger(getClass()).debug("using StandardDeviation(): " + stats.getStandardDeviation()); 395 data.add(new Double (stats.getStandardDeviation())); 396 break; 397 398 case DISPOSE_MAXIMUM: 399 Logger.getLogger(getClass()).debug("using Maximum(): " + stats.getMaximum()); 400 data.add(new Double (stats.getMaximum())); 401 break; 402 403 case DISPOSE_SUM: 404 Logger.getLogger(getClass()).debug("using Sum(): " + stats.getSum()); 405 data.add(new Double (stats.getSum())); 406 break; 407 408 case DISPOSE_NB_DATA_POINTS: 409 Logger.getLogger(getClass()).debug("using NbDataPoints(): " + stats.getNbDataPoints()); 410 data.add(new Integer (stats.getNbDataPoints())); 411 break; 412 413 case DISPOSE_IGNORE: 414 default: 415 Logger.getLogger(getClass()).debug("Skipping to next level ..."); 416 Iterator i = metrics.getSubMetrics().iterator(); 417 while (i.hasNext()) { 418 visitMetrics((Metrics) i.next()); 419 } 420 break; 421 } 422 } else if (measurement instanceof NullMeasurement) { 423 Logger.getLogger(getClass()).debug("Skipping to next level ..."); 424 Iterator i = metrics.getSubMetrics().iterator(); 425 while (i.hasNext()) { 426 visitMetrics((Metrics) i.next()); 427 } 428 } else { 429 Number value = measurement.getValue(); 430 431 Logger.getLogger(getClass()).debug(monitoredMeasurement + " on " + metrics.getName() + " is " + value); 432 433 if (value != null) { 434 data.add(value); 435 } 436 } 437 438 if (super.isEmpty()) { 439 setEmpty(measurement.isEmpty()); 440 } 441 } 442 443 public boolean isEmpty() { 444 collectData(); 445 446 return super.isEmpty(); 447 } 448 449 public void accept(MeasurementVisitor visitor) { 450 visitor.visitStatisticalMeasurement(this); 451 } 452 453 protected double compute() { 454 double result = Double.NaN; 455 456 switch (selfDispose) { 457 case DISPOSE_MINIMUM: 458 result = getMinimum(); 459 break; 460 461 case DISPOSE_MEDIAN: 462 result = getMedian(); 463 break; 464 465 case DISPOSE_AVERAGE: 466 result = getAverage(); 467 break; 468 469 case DISPOSE_STANDARD_DEVIATION: 470 result = getStandardDeviation(); 471 break; 472 473 case DISPOSE_MAXIMUM: 474 result = getMaximum(); 475 break; 476 477 case DISPOSE_SUM: 478 result = getSum(); 479 break; 480 481 case DISPOSE_NB_DATA_POINTS: 482 result = getNbDataPoints(); 483 break; 484 485 case DISPOSE_IGNORE: 486 default: 487 break; 488 } 489 490 return result; 491 } 492 493 public String toString() { 494 StringBuffer result = new StringBuffer (); 495 496 result.append("[").append(valueFormat.format(getMinimum())); 497 result.append(" ").append(valueFormat.format(getMedian())); 498 result.append("/").append(valueFormat.format(getAverage())); 499 result.append(" ").append(valueFormat.format(getStandardDeviation())); 500 result.append(" ").append(valueFormat.format(getMaximum())); 501 result.append(" ").append(valueFormat.format(getSum())); 502 result.append(" (").append(valueFormat.format(getNbDataPoints())).append(")]"); 503 504 return result.toString(); 505 } 506 } 507 | Popular Tags |