- Added a configurable report generator that could generate output either verbose or to an xml file.

- Using sysTest.reportType=[verbose|xml], default is xml.
- Xml output also displays a summary verbosely.
- TODO: Update the mojo to accomodate the additional option.

git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@413651 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Adrian T. Co 2006-06-12 13:33:04 +00:00
parent fcc9ae70b1
commit 77c889d19e
12 changed files with 903 additions and 278 deletions

View File

@ -18,6 +18,9 @@ package org.apache.activemq.tool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.activemq.tool.reports.VerbosePerfReportWriter;
import org.apache.activemq.tool.reports.PerformanceReportWriter;
import org.apache.activemq.tool.reports.XmlFilePerfReportWriter;
import java.util.Properties;
import java.util.Iterator;
@ -29,17 +32,20 @@ public abstract class JmsClientSystemSupport {
public static final String DEST_DISTRO_ALL = "all"; // Each client will send/receive to all destination;
public static final String DEST_DISTRO_EQUAL = "equal"; // Equally divide the number of destinations to the number of clients
public static final String DEST_DISTRO_DIVIDE = "divide"; // Divide the destination among the clients, even if some have more destination than others
protected static final String KEY_CLIENT_DEST_COUNT = "client.destCount";
protected static final String KEY_CLIENT_DEST_INDEX = "client.destIndex";
public static final String REPORT_VERBOSE = "verbose";
public static final String REPORT_XML_FILE = "xml";
protected Properties sysTestSettings = new Properties();
protected Properties samplerSettings = new Properties();
protected Properties jmsClientSettings = new Properties();
protected ThreadGroup clientThreadGroup;
protected PerfMeasurementTool performanceSampler;
protected String reportDirectory = "";
protected String reportType = REPORT_XML_FILE;
protected String reportDirectory = "./";
protected String reportName = null;
protected String clientName = null;
protected int numClients = 1;
protected int totalDests = 1;
protected String destDistro = DEST_DISTRO_ALL;
@ -49,12 +55,11 @@ public abstract class JmsClientSystemSupport {
performanceSampler = new PerfMeasurementTool();
performanceSampler.setSamplerSettings(samplerSettings);
PerfReportGenerator report = new PerfReportGenerator();
report.setReportName(this.getClass().getName());
report.setTestSettings(getSettings());
report.startGenerateReport();
PerformanceReportWriter writer = createPerfWriter();
performanceSampler.setPerfWriter(writer);
performanceSampler.setWriter(report.getWriter());
writer.openReportWriter();
writer.writeProperties("testProperties", getSettings());
clientThreadGroup = new ThreadGroup(getThreadGroupName());
for (int i=0; i<getNumClients(); i++) {
@ -75,66 +80,7 @@ public abstract class JmsClientSystemSupport {
performanceSampler.startSampler();
performanceSampler.waitForSamplerToFinish(0);
report.stopGenerateReport();
}
protected void distributeDestinations(String distroType, int clientIndex, int numClients, int numDests, Properties clientSettings) {
if (distroType.equalsIgnoreCase(DEST_DISTRO_ALL)) {
clientSettings.setProperty(KEY_CLIENT_DEST_COUNT, String.valueOf(numDests));
clientSettings.setProperty(KEY_CLIENT_DEST_INDEX, "0");
} else if (distroType.equalsIgnoreCase(DEST_DISTRO_EQUAL)) {
int destPerClient = (numDests / numClients);
// There are equal or more destinations per client
if (destPerClient > 0) {
clientSettings.setProperty(KEY_CLIENT_DEST_COUNT, String.valueOf(destPerClient));
clientSettings.setProperty(KEY_CLIENT_DEST_INDEX, String.valueOf(destPerClient * clientIndex));
// If there are more clients than destinations, share destinations per client
} else {
clientSettings.setProperty(KEY_CLIENT_DEST_COUNT, "1"); // At most one destination per client
clientSettings.setProperty(KEY_CLIENT_DEST_INDEX, String.valueOf(clientIndex % numDests));
}
} else if (distroType.equalsIgnoreCase(DEST_DISTRO_DIVIDE)) {
int destPerClient = (numDests / numClients);
// There are equal or more destinations per client
if (destPerClient > 0) {
int remain = numDests % numClients;
int nextIndex;
if (clientIndex < remain) {
destPerClient++;
nextIndex = clientIndex * destPerClient;
} else {
nextIndex = (clientIndex * destPerClient) + remain;
}
clientSettings.setProperty(KEY_CLIENT_DEST_COUNT, String.valueOf(destPerClient));
clientSettings.setProperty(KEY_CLIENT_DEST_INDEX, String.valueOf(nextIndex));
// If there are more clients than destinations, share destinations per client
} else {
clientSettings.setProperty(KEY_CLIENT_DEST_COUNT, "1"); // At most one destination per client
clientSettings.setProperty(KEY_CLIENT_DEST_INDEX, String.valueOf(clientIndex % numDests));
}
// Send to all for unknown behavior
} else {
clientSettings.setProperty(KEY_CLIENT_DEST_COUNT, String.valueOf(numDests));
clientSettings.setProperty(KEY_CLIENT_DEST_INDEX, "0");
}
}
public abstract void runJmsClient(String clientName, Properties clientSettings);
public String getClientName() {
return "JMS Client: ";
}
public String getThreadName() {
return "JMS Client Thread: ";
}
public String getThreadGroupName() {
return "JMS Clients Thread Group";
writer.closeReportWriter();
}
public PerfMeasurementTool getPerformanceSampler() {
@ -228,4 +174,102 @@ public abstract class JmsClientSystemSupport {
public void setTotalDests(int totalDests) {
this.totalDests = totalDests;
}
public String getReportName() {
if (reportName == null) {
return "clientPerformanceReport.xml";
} else {
return reportName;
}
}
public void setReportName(String reportName) {
this.reportName = reportName;
}
public String getClientName() {
if (clientName == null) {
return "JMS Client: ";
} else {
return clientName;
}
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
protected PerformanceReportWriter createPerfWriter() {
if (reportType.equalsIgnoreCase(REPORT_XML_FILE)) {
return new XmlFilePerfReportWriter(getReportDirectory(), getReportName());
} else if (reportType.equalsIgnoreCase(REPORT_VERBOSE)) {
return new VerbosePerfReportWriter();
} else {
// Use verbose if unknown report type
return new VerbosePerfReportWriter();
}
}
protected void distributeDestinations(String distroType, int clientIndex, int numClients, int numDests, Properties clientSettings) {
if (distroType.equalsIgnoreCase(DEST_DISTRO_ALL)) {
clientSettings.setProperty(getDestCountKey(), String.valueOf(numDests));
clientSettings.setProperty(getDestIndexKey(), "0");
} else if (distroType.equalsIgnoreCase(DEST_DISTRO_EQUAL)) {
int destPerClient = (numDests / numClients);
// There are equal or more destinations per client
if (destPerClient > 0) {
clientSettings.setProperty(getDestCountKey(), String.valueOf(destPerClient));
clientSettings.setProperty(getDestIndexKey(), String.valueOf(destPerClient * clientIndex));
// If there are more clients than destinations, share destinations per client
} else {
clientSettings.setProperty(getDestCountKey(), "1"); // At most one destination per client
clientSettings.setProperty(getDestIndexKey(), String.valueOf(clientIndex % numDests));
}
} else if (distroType.equalsIgnoreCase(DEST_DISTRO_DIVIDE)) {
int destPerClient = (numDests / numClients);
// There are equal or more destinations per client
if (destPerClient > 0) {
int remain = numDests % numClients;
int nextIndex;
if (clientIndex < remain) {
destPerClient++;
nextIndex = clientIndex * destPerClient;
} else {
nextIndex = (clientIndex * destPerClient) + remain;
}
clientSettings.setProperty(getDestCountKey(), String.valueOf(destPerClient));
clientSettings.setProperty(getDestIndexKey(), String.valueOf(nextIndex));
// If there are more clients than destinations, share destinations per client
} else {
clientSettings.setProperty(getDestCountKey(), "1"); // At most one destination per client
clientSettings.setProperty(getDestIndexKey(), String.valueOf(clientIndex % numDests));
}
// Send to all for unknown behavior
} else {
clientSettings.setProperty(getDestCountKey(), String.valueOf(numDests));
clientSettings.setProperty(getDestIndexKey(), "0");
}
}
protected abstract void runJmsClient(String clientName, Properties clientSettings);
protected String getThreadName() {
return "JMS Client Thread: ";
}
protected String getThreadGroupName() {
return "JMS Clients Thread Group";
}
protected String getDestCountKey() {
return "client.destCount";
}
protected String getDestIndexKey() {
return "client.destIndex";
}
}

View File

@ -20,12 +20,30 @@ import javax.jms.JMSException;
import java.util.Properties;
public class JmsConsumerSystem extends JmsClientSystemSupport {
public void runJmsClient(String clientName, Properties clientSettings) {
public String getReportName() {
if (reportName == null) {
return "JmsConsumer_ClientCount" + getNumClients() + "_DestCount" + getTotalDests() + "_" + getDestDistro() + ".xml";
} else {
return reportName;
}
}
public String getClientName() {
if (clientName == null) {
return "JmsConsumer";
} else {
return clientName;
}
}
protected void runJmsClient(String clientName, Properties clientSettings) {
PerfMeasurementTool sampler = getPerformanceSampler();
JmsConsumerClient consumer = new JmsConsumerClient();
consumer.setSettings(clientSettings);
consumer.setConsumerName(clientName); // For durable subscribers
consumer.setClientName(clientName);
if (sampler != null) {
sampler.registerClient(consumer);
@ -39,18 +57,22 @@ public class JmsConsumerSystem extends JmsClientSystemSupport {
}
}
public String getClientName() {
return "JMS Consumer: ";
}
public String getThreadName() {
protected String getThreadName() {
return "JMS Consumer Thread: ";
}
public String getThreadGroupName() {
protected String getThreadGroupName() {
return "JMS Consumer Thread Group";
}
protected String getDestCountKey() {
return "consumer.destCount";
}
protected String getDestIndexKey() {
return "consumer.destIndex";
}
public static void main(String[] args) throws JMSException {
Properties sysSettings = new Properties();
for (int i = 0; i < args.length; i++) {

View File

@ -18,33 +18,22 @@ package org.apache.activemq.tool;
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLong;
import javax.jms.JMSException;
public class JmsPerformanceSupport extends JmsClientSupport implements PerfMeasurable {
private static int clientCounter;
protected AtomicLong throughput = new AtomicLong(0);
protected PerfEventListener listener = null;
private int clientNumber;
protected String clientName = null;
public void reset() {
setThroughput(0);
}
public synchronized int getClientNumber() {
if (clientNumber == 0) {
clientNumber = incrementClientCounter();
}
return clientNumber;
public String getClientName() {
return clientName;
}
public String getClientName() {
try {
return getConnection().getClientID();
} catch (JMSException e) {
return "";
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public long getThroughput() {
@ -70,8 +59,4 @@ public class JmsPerformanceSupport extends JmsClientSupport implements PerfMeasu
public PerfEventListener getPerfEventListener() {
return listener;
}
protected static synchronized int incrementClientCounter() {
return ++clientCounter;
}
}

View File

@ -20,11 +20,29 @@ import javax.jms.JMSException;
import java.util.Properties;
public class JmsProducerSystem extends JmsClientSystemSupport {
public void runJmsClient(String clientName, Properties clientSettings) {
public String getReportName() {
if (reportName == null) {
return "JmsProducer_ClientCount" + getNumClients() + "_DestCount" + getTotalDests() + "_" + getDestDistro() + ".xml";
} else {
return reportName;
}
}
public String getClientName() {
if (clientName == null) {
return "JmsProducer";
} else {
return clientName;
}
}
protected void runJmsClient(String clientName, Properties clientSettings) {
PerfMeasurementTool sampler = getPerformanceSampler();
JmsProducerClient producer = new JmsProducerClient();
producer.setSettings(clientSettings);
producer.setClientName(clientName);
if (sampler != null) {
sampler.registerClient(producer);
@ -39,18 +57,22 @@ public class JmsProducerSystem extends JmsClientSystemSupport {
}
}
public String getClientName() {
return "JMS Producer: ";
}
public String getThreadName() {
protected String getThreadName() {
return "JMS Producer Thread: ";
}
public String getThreadGroupName() {
protected String getThreadGroupName() {
return "JMS Producer Thread Group";
}
protected String getDestCountKey() {
return "producer.destCount";
}
protected String getDestIndexKey() {
return "producer.destIndex";
}
public static void main(String[] args) {
Properties sysSettings = new Properties();

View File

@ -20,7 +20,6 @@ import java.util.Properties;
public interface PerfMeasurable {
public void reset();
public int getClientNumber();
public String getClientName();
public long getThroughput();
public Properties getSettings();

View File

@ -19,12 +19,13 @@ package org.apache.activemq.tool;
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
import javax.jms.JMSException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import org.apache.activemq.tool.reports.PerformanceReportWriter;
public class PerfMeasurementTool implements PerfEventListener, Runnable {
public static final String PREFIX_CONFIG_SYSTEM_TEST = "sampler.";
@ -37,7 +38,7 @@ public class PerfMeasurementTool implements PerfEventListener, Runnable {
private AtomicBoolean start = new AtomicBoolean(false);
private AtomicBoolean stop = new AtomicBoolean(false);
private AtomicBoolean isRunning = new AtomicBoolean(false);
private PrintWriter writer = null;
private PerformanceReportWriter perfWriter = null;
private Properties samplerSettings = new Properties();
private List perfClients = new ArrayList();
@ -62,12 +63,12 @@ public class PerfMeasurementTool implements PerfEventListener, Runnable {
ReflectionUtil.configureClass(this, samplerSettings);
}
public PrintWriter getWriter() {
return writer;
public PerformanceReportWriter getPerfWriter() {
return perfWriter;
}
public void setWriter(PrintWriter writer) {
this.writer = writer;
public void setPerfWriter(PerformanceReportWriter writer) {
this.perfWriter = writer;
}
public long getDuration() {
@ -169,8 +170,9 @@ public class PerfMeasurementTool implements PerfEventListener, Runnable {
public void sampleClients() {
for (Iterator i = perfClients.iterator(); i.hasNext();) {
PerfMeasurable client = (PerfMeasurable) i.next();
getWriter().println("<sample index='" + sampleIndex + "' clientNumber='" + client.getClientNumber()
+ "' name='" + client.getClientName() + "' throughput='" + client.getThroughput() + "'/>");
if (perfWriter != null) {
perfWriter.writePerfData("index=" + sampleIndex + ",clientName=" + client.getClientName() + ",throughput=" + client.getThroughput());
}
client.reset();
}
}

View File

@ -1,165 +0,0 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tool;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Properties;
public class PerfReportGenerator {
private String reportDirectory = null;
private String reportName = null;
private PrintWriter writer = null;
private Properties testSettings;
public PerfReportGenerator() {
}
public PerfReportGenerator(String reportDirectory, String reportName) {
this.setReportDirectory(reportDirectory);
this.setReportName(reportName);
}
public void startGenerateReport() {
setReportDirectory(this.getTestSettings().getProperty("sysTest.reportDirectory", ""));
File reportDir = new File(getReportDirectory());
// Create output directory if it doesn't exist.
if (!reportDir.exists()) {
reportDir.mkdirs();
}
File reportFile = null;
if (reportDir != null) {
String filename = (this.getReportName()).substring(this.getReportName().lastIndexOf(".") + 1) + "-" + createReportName(getTestSettings());
reportFile = new File(this.getReportDirectory() + File.separator + filename + ".xml");
}
try {
this.writer = new PrintWriter(new FileOutputStream(reportFile));
addTestInformation(getWriter());
} catch (IOException e1) {
e1.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public void stopGenerateReport() {
this.getWriter().println("</test-result>");
this.getWriter().println("</test-report>");
this.getWriter().flush();
this.getWriter().close();
}
protected void addTestInformation(PrintWriter writer) {
writer.println("<test-report>");
writer.println("<test-information>");
Enumeration keys;
String key;
// Add system property settings
writer.println("<system-settings>");
Properties sysProp = System.getProperties();
keys = sysProp.keys();
while (keys.hasMoreElements()) {
key = (String) keys.nextElement();
writer.println("<" + key + ">" + System.getProperty(key) + "</" + key + ">");
}
writer.println("</system-settings>");
// Add client property settings
writer.println("<client-settings>");
if (this.getTestSettings() != null) {
keys = getTestSettings().propertyNames();
while (keys.hasMoreElements()) {
key = (String) keys.nextElement();
writer.println("<" + key + ">" + getTestSettings().get(key) + "</" + key + ">");
}
}
writer.println("</client-settings>");
writer.println("</test-information>");
writer.println("<test-result>");
}
public PrintWriter getWriter() {
return this.writer;
}
public String getReportDirectory() {
return reportDirectory;
}
public void setReportDirectory(String reportDirectory) {
this.reportDirectory = reportDirectory;
}
public String getReportName() {
return reportName;
}
public String createReportName(Properties testSettings) {
if (testSettings != null) {
String[] keys = {"client.destCount", "client.asyncRecv", "client.durable",
"client.messageSize", "sysTest.numClients", "sysTest.totalDests"};
StringBuffer buffer = new StringBuffer();
String key;
String val;
String temp;
for (int i = 0; i < keys.length; i++) {
key = keys[i];
val = testSettings.getProperty(key);
if (val == null) continue;
temp = key.substring(key.indexOf(".") + 1);
buffer.append(temp + val);
}
return buffer.toString();
}
return null;
}
public void setReportName(String reportName) {
this.reportName = reportName;
}
public Properties getTestSettings() {
return testSettings;
}
public void setTestSettings(Properties testSettings) {
this.testSettings = testSettings;
}
}

View File

@ -0,0 +1,189 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tool.reports;
import org.apache.activemq.tool.ReflectionUtil;
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.Iterator;
public abstract class AbstractPerfReportWriter implements PerformanceReportWriter {
public static final String KEY_SYS_TOTAL_TP = "SystemTotalTP";
public static final String KEY_SYS_TOTAL_CLIENTS = "SystemTotalClients";
public static final String KEY_SYS_AVE_TP = "SystemAveTP";
public static final String KEY_SYS_AVE_EMM_TP = "SystemAveEMMTP";
public static final String KEY_MIN_CLIENT_TP = "MinClientTP";
public static final String KEY_MAX_CLIENT_TP = "MaxClientTP";
public static final String KEY_MIN_CLIENT_TOTAL_TP = "MinClientTotalTP";
public static final String KEY_MAX_CLIENT_TOTAL_TP = "MaxClientTotalTP";
public static final String KEY_MIN_CLIENT_AVE_TP = "MinClientAveTP";
public static final String KEY_MAX_CLIENT_AVE_TP = "MaxClientAveTP";
public static final String KEY_MIN_CLIENT_AVE_EMM_TP = "MinClientAveEMMTP";
public static final String KEY_MAX_CLIENT_AVE_EMM_TP = "MaxClientAveEMMTP";
protected Properties settings;
protected Map clientThroughputs = new HashMap();
public void setSettings(Properties settings) {
this.settings = settings;
ReflectionUtil.configureClass(this, settings);
}
public Properties getSettings() {
return settings;
}
protected void parsePerfCsvData(String csvData) {
StringTokenizer tokenizer = new StringTokenizer(csvData, ",");
String data, key, val, clientName = null;
Long throughput = null;
while (tokenizer.hasMoreTokens()) {
data = tokenizer.nextToken();
key = data.substring(0, data.indexOf("="));
val = data.substring(data.indexOf("=") + 1);
if (key.equalsIgnoreCase("clientName")) {
clientName = val;
} else if (key.equalsIgnoreCase("throughput")) {
throughput = Long.valueOf(val);
} else {
// Ignore unknown token
}
}
addToClientTPList(clientName, throughput);
}
protected void addToClientTPList(String clientName, Long throughput) {
// Write to client's throughput list
if (clientName == null || throughput == null) {
throw new IllegalArgumentException("Invalid Throughput CSV Data: clientName=" + clientName + ", throughput=" + throughput);
}
List clientTPList = (List)clientThroughputs.get(clientName);
if (clientTPList == null) {
clientTPList = new ArrayList();
clientThroughputs.put(clientName, clientTPList);
}
clientTPList.add(throughput);
}
protected Map createPerfSummary(Map clientTPMap) {
long minClientTP = Long.MAX_VALUE, // TP = throughput
maxClientTP = Long.MIN_VALUE,
minClientTotalTP = Long.MAX_VALUE,
maxClientTotalTP = Long.MIN_VALUE,
systemTotalTP = 0;
double minClientAveTP = Double.MAX_VALUE,
maxClientAveTP = Double.MIN_VALUE,
minClientAveEMMTP = Double.MAX_VALUE, // EMM = Excluding Min/Max
maxClientAveEMMTP = Double.MIN_VALUE,
systemAveTP = 0.0,
systemAveEMMTP = 0.0;
String nameMinClientTP = "",
nameMaxClientTP = "",
nameMinClientTotalTP = "",
nameMaxClientTotalTP = "",
nameMinClientAveTP = "",
nameMaxClientAveTP = "",
nameMinClientAveEMMTP = "",
nameMaxClientAveEMMTP = "";
Set clientNames = clientTPMap.keySet();
String clientName;
List clientTPList;
long tempLong;
double tempDouble;
int clientCount = 0;
for (Iterator i=clientNames.iterator(); i.hasNext();) {
clientName = (String)i.next();
clientTPList = (List)clientTPMap.get(clientName);
clientCount++;
tempLong = PerformanceStatisticsUtil.getMinThroughput(clientTPList);
if (tempLong < minClientTP) {
minClientTP = tempLong;
nameMinClientTP = clientName;
}
tempLong = PerformanceStatisticsUtil.getMaxThroughput(clientTPList);
if (tempLong > maxClientTP) {
maxClientTP = tempLong;
nameMaxClientTP = clientName;
}
tempLong = PerformanceStatisticsUtil.getTotalThroughput(clientTPList);
systemTotalTP += tempLong; // Accumulate total TP
if (tempLong < minClientTotalTP) {
minClientTotalTP = tempLong;
nameMinClientTotalTP = clientName;
}
if (tempLong > maxClientTotalTP) {
maxClientTotalTP = tempLong;
nameMaxClientTotalTP = clientName;
}
tempDouble = PerformanceStatisticsUtil.getAveThroughput(clientTPList);
systemAveTP += tempDouble; // Accumulate ave throughput
if (tempDouble < minClientAveTP) {
minClientAveTP = tempDouble;
nameMinClientAveTP = clientName;
}
if (tempDouble > maxClientAveTP) {
maxClientAveTP = tempDouble;
nameMaxClientAveTP = clientName;
}
tempDouble = PerformanceStatisticsUtil.getAveThroughputExcludingMinMax(clientTPList);
systemAveEMMTP += tempDouble; // Accumulate ave throughput excluding min/max
if (tempDouble < minClientAveEMMTP) {
minClientAveEMMTP = tempDouble;
nameMinClientAveEMMTP = clientName;
}
if (tempDouble > maxClientAveEMMTP) {
maxClientAveEMMTP = tempDouble;
nameMaxClientAveEMMTP = clientName;
}
}
Map summary = new HashMap();
summary.put(KEY_SYS_TOTAL_TP, String.valueOf(systemTotalTP));
summary.put(KEY_SYS_TOTAL_CLIENTS, String.valueOf(clientCount));
summary.put(KEY_SYS_AVE_TP, String.valueOf(systemAveTP));
summary.put(KEY_SYS_AVE_EMM_TP, String.valueOf(systemAveEMMTP));
summary.put(KEY_MIN_CLIENT_TP, nameMinClientTP + "=" + minClientTP);
summary.put(KEY_MAX_CLIENT_TP, nameMaxClientTP + "=" + maxClientTP);
summary.put(KEY_MIN_CLIENT_TOTAL_TP, nameMinClientTotalTP + "=" + minClientTotalTP);
summary.put(KEY_MAX_CLIENT_TOTAL_TP, nameMaxClientTotalTP + "=" + maxClientTotalTP);
summary.put(KEY_MIN_CLIENT_AVE_TP, nameMinClientAveTP + "=" + minClientAveTP);
summary.put(KEY_MAX_CLIENT_AVE_TP, nameMaxClientAveTP + "=" + maxClientAveTP);
summary.put(KEY_MIN_CLIENT_AVE_EMM_TP, nameMinClientAveEMMTP + "=" + minClientAveEMMTP);
summary.put(KEY_MAX_CLIENT_AVE_EMM_TP, nameMaxClientAveEMMTP + "=" + maxClientAveEMMTP);
return summary;
}
}

View File

@ -0,0 +1,30 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tool.reports;
import java.util.Properties;
public interface PerformanceReportWriter {
public void setSettings(Properties settings);
public Properties getSettings();
public void openReportWriter();
public void closeReportWriter();
public void writeInfo(String info);
public void writePerfData(String data);
public void writeProperties(String header, Properties props);
public void writeProperties(Properties props);
}

View File

@ -0,0 +1,100 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tool.reports;
import java.util.List;
import java.util.Iterator;
public final class PerformanceStatisticsUtil {
private PerformanceStatisticsUtil() {
}
public static long getTotalThroughput(List totalTPList) {
long totalTP = 0;
if (totalTPList != null) {
for (Iterator i=totalTPList.iterator(); i.hasNext();) {
totalTP += ((Long)i.next()).longValue();
}
} else {
totalTP = -1;
}
return totalTP;
}
public static long getMinThroughput(List totalTPList) {
long minTP = Long.MAX_VALUE;
if (totalTPList != null) {
for (Iterator i=totalTPList.iterator(); i.hasNext();) {
minTP = Math.min(((Long)i.next()).longValue(), minTP);
}
} else {
minTP = -1;
}
return minTP;
}
public static long getMaxThroughput(List totalTPList) {
long maxTP = Long.MIN_VALUE;
if (totalTPList != null) {
for (Iterator i=totalTPList.iterator(); i.hasNext();) {
maxTP = Math.max(((Long)i.next()).longValue(), maxTP);
}
} else {
maxTP = -1;
}
return maxTP;
}
public static double getAveThroughput(List totalTPList) {
double aveTP;
if (totalTPList != null) {
int sampleCount = 0;
long totalTP = 0;
for (Iterator i=totalTPList.iterator(); i.hasNext();) {
sampleCount++;
totalTP += ((Long)i.next()).longValue();
}
return (double)totalTP / (double)sampleCount;
} else {
aveTP = -1;
}
return aveTP;
}
public static double getAveThroughputExcludingMinMax(List totalTPList) {
double aveTP;
long minTP = getMinThroughput(totalTPList);
long maxTP = getMaxThroughput(totalTPList);
if (totalTPList != null) {
int sampleCount = 0;
long totalTP = 0;
long sampleTP;
for (Iterator i=totalTPList.iterator(); i.hasNext();) {
sampleCount++;
sampleTP = ((Long)i.next()).longValue();
if (sampleTP != minTP && sampleTP != maxTP) {
totalTP += sampleTP;
}
}
return (double)totalTP / (double)sampleCount;
} else {
aveTP = -1;
}
return aveTP;
}
}

View File

@ -0,0 +1,85 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tool.reports;
import java.util.Properties;
import java.util.Iterator;
import java.util.Map;
import java.util.Arrays;
public class VerbosePerfReportWriter extends AbstractPerfReportWriter {
public void openReportWriter() {
writeProperties("System Properties", System.getProperties());
}
public void closeReportWriter() {
writeHeader("Performance Summary");
writePerfSummary();
}
public void writeInfo(String info) {
System.out.println("[PERF-INFO]: " + info);
}
public void writeHeader(String header) {
char[] border = new char[header.length() + 8]; // +8 for spacing
Arrays.fill(border, '#');
String borderStr = new String(border);
System.out.println(borderStr);
System.out.println("# " + header + " #");
System.out.println(borderStr);
}
public void writePerfData(String data) {
System.out.println("[PERF-DATA]: " + data);
// Assume data is a CSV of key-value pair
parsePerfCsvData(data);
}
public void writeProperties(String header, Properties props) {
writeHeader(header);
writeProperties(props);
}
public void writeProperties(Properties props) {
for (Iterator i=props.keySet().iterator(); i.hasNext();) {
String key = (String)i.next();
String val = props.getProperty(key, "");
System.out.println("[PERF-PROP]: " + key + "=" + val);
}
}
public void writePerfSummary() {
Map summary = createPerfSummary(clientThroughputs);
System.out.println("[PERF-SUMMARY] System Total Throughput: " + summary.get(KEY_SYS_TOTAL_TP));
System.out.println("[PERF-SUMMARY] System Total Clients: " + summary.get(KEY_SYS_TOTAL_CLIENTS));
System.out.println("[PERF-SUMMARY] System Average Throughput: " + summary.get(KEY_SYS_AVE_TP));
System.out.println("[PERF-SUMMARY] System Average Throughput Excluding Min/Max: " + summary.get(KEY_SYS_AVE_EMM_TP));
System.out.println("[PERF-SUMMARY] Min Client Throughput Per Sample: " + summary.get(KEY_MIN_CLIENT_TP));
System.out.println("[PERF-SUMMARY] Max Client Throughput Per Sample: " + summary.get(KEY_MAX_CLIENT_TP));
System.out.println("[PERF-SUMMARY] Min Client Total Throughput: " + summary.get(KEY_MIN_CLIENT_TOTAL_TP));
System.out.println("[PERF-SUMMARY] Max Client Total Throughput: " + summary.get(KEY_MAX_CLIENT_TOTAL_TP));
System.out.println("[PERF-SUMMARY] Min Client Average Throughput: " + summary.get(KEY_MIN_CLIENT_AVE_TP));
System.out.println("[PERF-SUMMARY] Max Client Average Throughput: " + summary.get(KEY_MAX_CLIENT_AVE_TP));
System.out.println("[PERF-SUMMARY] Min Client Average Throughput Excluding Min/Max: " + summary.get(KEY_MIN_CLIENT_AVE_EMM_TP));
System.out.println("[PERF-SUMMARY] Max Client Average Throughput Excluding Min/Max: " + summary.get(KEY_MAX_CLIENT_AVE_EMM_TP));
}
}

View File

@ -0,0 +1,312 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tool.reports;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Properties;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.io.File;
import java.io.PrintWriter;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.IOException;
public class XmlFilePerfReportWriter extends AbstractPerfReportWriter {
private static final Log log = LogFactory.getLog(XmlFilePerfReportWriter.class);
private File tempLogFile;
private PrintWriter tempLogFileWriter;
private File xmlFile;
private PrintWriter xmlFileWriter;
private String reportDir;
private String reportName;
private Map testPropsMap;
private List testPropsList;
public XmlFilePerfReportWriter() {
this("", "PerformanceReport.xml");
}
public XmlFilePerfReportWriter(String reportDir, String reportName) {
this.testPropsMap = new HashMap();
this.testPropsList = new ArrayList();
this.reportDir = reportDir;
this.reportName = reportName;
}
public void openReportWriter() {
if (tempLogFile == null) {
tempLogFile = createTempLogFile();
}
try {
// Disable auto-flush and allocate 100kb of buffer
tempLogFileWriter = new PrintWriter(new BufferedOutputStream(new FileOutputStream(tempLogFile), 102400), false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void closeReportWriter() {
// Flush and close log file writer
tempLogFileWriter.flush();
tempLogFileWriter.close();
writeToXml();
}
public String getReportDir() {
return reportDir;
}
public void setReportDir(String reportDir) {
this.reportDir = reportDir;
}
public String getReportName() {
return reportName;
}
public void setReportName(String reportName) {
this.reportName = reportName;
}
public void writeInfo(String info) {
tempLogFileWriter.println("[INFO]" + info);
}
public void writePerfData(String data) {
tempLogFileWriter.println("[DATA]" + data);
}
public void writeProperties(String header, Properties props) {
testPropsMap.put(header, props);
}
public void writeProperties(Properties props) {
testPropsList.add(props);
}
protected File createTempLogFile() {
File f = null;
try {
f = File.createTempFile("tmpPL", null);
} catch (IOException e) {
f = new File("tmpPL" + System.currentTimeMillis() + ".tmp");
}
f.deleteOnExit();
return f;
}
protected File createXmlFile() {
String filename = (getReportName().endsWith(".xml") ? getReportName() : (getReportName() + ".xml"));
String path = (getReportDir() == null) ? "" : getReportDir();
File f = new File(path + filename);
return f;
}
protected void writeToXml() {
try {
xmlFile = createXmlFile();
xmlFileWriter = new PrintWriter(new FileOutputStream(xmlFile));
writeXmlHeader();
writeXmlTestSettings();
writeXmlLogFile();
writeXmlPerfSummary();
writeXmlFooter();
xmlFileWriter.close();
System.out.println("Created performance report: " + xmlFile.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
protected void writeXmlHeader() {
xmlFileWriter.println("<testResult>");
}
protected void writeXmlFooter() {
xmlFileWriter.println("</testResult>");
}
protected void writeXmlTestSettings() {
Properties props;
// Write system settings
writeMap("systemSettings", System.getProperties());
// Write test settings
for (Iterator i=testPropsMap.keySet().iterator(); i.hasNext();) {
String key = (String)i.next();
props = (Properties)testPropsMap.get(key);
writeMap(key, props);
}
int count = 1;
for (Iterator i=testPropsList.iterator(); i.hasNext();) {
props = (Properties)i.next();
writeMap("settings" + count++, props);
}
}
protected void writeXmlLogFile() throws IOException {
// Write throughput data
xmlFileWriter.println("<property name='performanceData'>");
xmlFileWriter.println("<list>");
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(tempLogFile)));
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("[DATA]")) {
parsePerfCsvData(line.substring("[DATA]".length()));
} else if (line.startsWith("[INFO]")) {
xmlFileWriter.println("<value>" + line + "</value>");
} else {
xmlFileWriter.println("<value>[ERROR]" + line + "</value>");
}
}
xmlFileWriter.println("</list>");
xmlFileWriter.println("</property>");
}
protected void writeXmlPerfSummary() {
Map summary = createPerfSummary(clientThroughputs);
xmlFileWriter.println("<property name='perfSummary'>");
xmlFileWriter.println("<props>");
String val, clientName, clientVal;
val = (String)summary.get(KEY_SYS_TOTAL_TP);
System.out.println("System Total Throughput: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_TOTAL_TP + "'>" + val + "</prop>");
val = (String)summary.get(KEY_SYS_TOTAL_CLIENTS);
System.out.println("System Total Clients: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_TOTAL_CLIENTS + "'>" + val + "</prop>");
val = (String)summary.get(KEY_SYS_AVE_TP);
System.out.println("System Average Throughput: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_AVE_TP + "'>" + val + "</prop>");
val = (String)summary.get(KEY_SYS_AVE_EMM_TP);
System.out.println("System Average Throughput Excluding Min/Max: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_AVE_EMM_TP + "'>" + val + "</prop>");
val = (String)summary.get(KEY_MIN_CLIENT_TP);
clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Min Client Throughput Per Sample: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MIN_CLIENT_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MAX_CLIENT_TP);
clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Max Client Throughput Per Sample: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MAX_CLIENT_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MIN_CLIENT_TOTAL_TP);
clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Min Client Total Throughput: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MIN_CLIENT_TOTAL_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MAX_CLIENT_TOTAL_TP);
clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Max Client Total Throughput: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MAX_CLIENT_TOTAL_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MIN_CLIENT_AVE_TP);
clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Min Average Client Throughput: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MIN_CLIENT_AVE_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MAX_CLIENT_AVE_TP);
clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Max Average Client Throughput: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MAX_CLIENT_AVE_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MIN_CLIENT_AVE_EMM_TP);
clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Min Average Client Throughput Excluding Min/Max: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MIN_CLIENT_AVE_EMM_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MAX_CLIENT_AVE_EMM_TP);
clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Max Average Client Throughput Excluding Min/Max: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MAX_CLIENT_AVE_EMM_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
xmlFileWriter.println("</props>");
xmlFileWriter.println("</property>");
}
protected void writeMap(String name, Map map) {
xmlFileWriter.println("<property name='" + name + "'>");
xmlFileWriter.println("<props>");
for (Iterator i=map.keySet().iterator(); i.hasNext();) {
String propKey = (String)i.next();
Object propVal = map.get(propKey);
xmlFileWriter.println("<prop key='" + propKey + "'>" + propVal.toString() + "</prop>");
}
xmlFileWriter.println("</props>");
xmlFileWriter.println("</property>");
}
protected void parsePerfCsvData(String csvData) {
StringTokenizer tokenizer = new StringTokenizer(csvData, ",");
String data, key, val, clientName = null;
Long throughput = null;
int index = -1;
while (tokenizer.hasMoreTokens()) {
data = tokenizer.nextToken();
key = data.substring(0, data.indexOf("="));
val = data.substring(data.indexOf("=") + 1);
if (key.equalsIgnoreCase("clientName")) {
clientName = val;
} else if (key.equalsIgnoreCase("throughput")) {
throughput = Long.valueOf(val);
} else if (key.equalsIgnoreCase("index")) {
index = Integer.parseInt(val);
}
}
addToClientTPList(clientName, throughput);
xmlFileWriter.println("<value index='" + index + "' clientName='" + clientName +
"'>" + throughput.longValue() + "</value>");
}
}