001: /*
002: * Copyright (c) xsocket.org, 2006 - 2008. All rights reserved.
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
019: * The latest copy of this software may be found on http://www.xsocket.org/
020: */
021: package org.xsocket;
022:
023: import java.text.SimpleDateFormat;
024: import java.util.ArrayList;
025: import java.util.Collections;
026: import java.util.Date;
027: import java.util.Timer;
028: import java.util.TimerTask;
029:
030: /**
031: * helper class to collect and print statistics
032: *
033: * @author grro
034: */
035: public final class Statistic {
036:
037: private static final int SECTION_TIMERANGE = 30 * 1000;
038:
039: private final ArrayList<Integer> times = new ArrayList<Integer>();
040: private ArrayList<Integer> tempTimes = new ArrayList<Integer>();
041: private long lastPrint = System.currentTimeMillis();
042:
043: private long lastSection = System.currentTimeMillis();
044:
045: private Timer timer = new Timer(true);
046: private SimpleDateFormat dateFormat = new SimpleDateFormat(
047: "yyyy.MM.dd HH:mm:ss");
048:
049: private boolean firstPrint = true;
050:
051: public Statistic(boolean autoprint) {
052:
053: if (autoprint) {
054: try {
055: TimerTask timerTask = new TimerTask() {
056: @Override
057: public void run() {
058: System.out.println(print());
059: }
060: };
061:
062: timer.schedule(timerTask, 5000, 5000);
063: } catch (Exception e) {
064: e.printStackTrace();
065: }
066: }
067: }
068:
069: private String printHeader() {
070: return "time; throughput; min; max; average; median; p90; p95; p99";
071: }
072:
073: public synchronized void addValue(int value) {
074: times.add(value);
075: tempTimes.add(value);
076: }
077:
078: @SuppressWarnings("unchecked")
079: public String print() {
080: StringBuilder sb = new StringBuilder();
081:
082: ArrayList<Integer> copy = null;
083: synchronized (this ) {
084: copy = (ArrayList<Integer>) times.clone();
085: }
086:
087: Collections.sort(copy);
088:
089: int sum = 0;
090: for (Integer i : copy) {
091: sum += i;
092: }
093:
094: if (firstPrint) {
095: firstPrint = false;
096: sb.append("\r\n" + printHeader() + "\r\n");
097: }
098:
099: sb.append(dateFormat.format(new Date()) + "; ");
100:
101: ArrayList<Integer> tempTimesCopy = tempTimes;
102: tempTimes = new ArrayList<Integer>();
103: long elapsed = System.currentTimeMillis() - lastPrint;
104: lastPrint = System.currentTimeMillis();
105: sb.append(((tempTimesCopy.size() * 1000) / elapsed) + "; ");
106:
107: if (copy.size() > 0) {
108: sb.append(copy.get(0) + "; ");
109: sb.append(copy.get(copy.size() - 1) + "; ");
110: sb.append((sum / copy.size()) + "; ");
111: sb.append(copy.get(copy.size() / 2) + "; ");
112: sb.append(copy.get((int) (copy.size() * 0.9)) + "; ");
113: sb.append(copy.get((int) (copy.size() * 0.95)) + "; ");
114: sb.append(copy.get((int) (copy.size() * 0.99)));
115: }
116:
117: if (System.currentTimeMillis() > (lastSection + SECTION_TIMERANGE)) {
118: lastSection = System.currentTimeMillis();
119: times.clear();
120: sb.append("\r\n\r\n");
121: sb.append(printHeader());
122: }
123:
124: return sb.toString();
125: }
126:
127: }
|