Fix cassandra-stress graph option

Patch by Christopher Batey; reviewed by Joel Knighton for CASSANDRA-12237
This commit is contained in:
Christopher Batey 2016-07-20 14:08:51 +01:00 committed by Sylvain Lebresne
parent cfedd4d0e1
commit f42e235b1e
31 changed files with 341 additions and 379 deletions

View File

@ -1,4 +1,5 @@
3.10
* Fix cassandra-stress graphing (CASSANDRA-12237)
* Allow filtering on partition key columns for queries without secondary indexes (CASSANDRA-11031)
* Fix Cassandra Stress reporting thread model and precision (CASSANDRA-12585)
* Add JMH benchmarks.jar (CASSANDRA-12586)

View File

@ -23,9 +23,9 @@ import java.net.SocketException;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.stress.settings.StressSettings;
import org.apache.cassandra.stress.util.MultiResultLogger;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.WindowsTimer;
import org.apache.cassandra.stress.util.MultiPrintStream;
public final class Stress
{
@ -88,7 +88,7 @@ public final class Stress
return 1;
}
MultiPrintStream logout = settings.log.getOutput();
MultiResultLogger logout = settings.log.getOutput();
if (! settings.log.noSettings)
{

View File

@ -17,9 +17,6 @@
*/
package org.apache.cassandra.stress;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
@ -35,6 +32,7 @@ import org.apache.cassandra.stress.settings.ConnectionAPI;
import org.apache.cassandra.stress.settings.SettingsCommand;
import org.apache.cassandra.stress.settings.StressSettings;
import org.apache.cassandra.stress.util.JavaDriverClient;
import org.apache.cassandra.stress.util.ResultLogger;
import org.apache.cassandra.stress.util.ThriftClient;
import org.apache.cassandra.transport.SimpleClient;
import org.jctools.queues.SpscArrayQueue;
@ -46,8 +44,8 @@ public class StressAction implements Runnable
{
private final StressSettings settings;
private final PrintStream output;
public StressAction(StressSettings settings, PrintStream out)
private final ResultLogger output;
public StressAction(StressSettings settings, ResultLogger out)
{
this.settings = settings;
output = out;
@ -67,6 +65,10 @@ public class StressAction implements Runnable
if (settings.command.truncate == SettingsCommand.TruncateWhen.ONCE)
settings.command.truncateTables(settings);
// Required for creating a graph from the output file
if (settings.rate.threadCount == -1)
output.println("Thread count was not specified");
// TODO : move this to a new queue wrapper that gates progress based on a poisson (or configurable) distribution
UniformRateLimiter rateLimiter = null;
if (settings.rate.opsPerSecond > 0)
@ -94,7 +96,6 @@ public class StressAction implements Runnable
@SuppressWarnings("resource") // warmupOutput doesn't need closing
private void warmup(OpDistributionFactory operations)
{
PrintStream warmupOutput = new PrintStream(new OutputStream() { @Override public void write(int b) throws IOException { } } );
// do 25% of iterations as warmup but no more than 50k (by default hotspot compiles methods after 10k invocations)
int iterations = (settings.command.count > 0
? Math.min(50000, (int)(settings.command.count * 0.25))
@ -111,7 +112,7 @@ public class StressAction implements Runnable
// we need to warm up all the nodes in the cluster ideally, but we may not be the only stress instance;
// so warm up all the nodes we're speaking to only.
output.println(String.format("Warming up %s with %d iterations...", single.desc(), iterations));
boolean success = null != run(single, threads, iterations, 0, null, null, warmupOutput, true);
boolean success = null != run(single, threads, iterations, 0, null, null, ResultLogger.NOOP, true);
if (!success)
throw new RuntimeException("Failed to execute warmup");
}
@ -200,7 +201,7 @@ public class StressAction implements Runnable
long duration,
UniformRateLimiter rateLimiter,
TimeUnit durationUnits,
PrintStream output,
ResultLogger output,
boolean isWarmup)
{
output.println(String.format("Running %s with %d threads %s",
@ -470,7 +471,7 @@ public class StressAction implements Runnable
if (output == null)
System.err.println(e.getMessage());
else
e.printStackTrace(output);
output.printException(e);
success = false;
opStream.abort();

View File

@ -201,7 +201,8 @@ public class StressGraph
{
continue;
}
json.put(parts[0].trim(), parts[1].trim());
// the graphing js expects lower case names
json.put(parts[0].trim().toLowerCase(), parts[1].trim());
}
else if (mode == ReadingMode.NEXTITERATION)
{
@ -227,7 +228,7 @@ public class StressGraph
{
throw new RuntimeException("Couldn't read from temporary stress log file");
}
stats.add(json);
if (json.size() != 0) stats.add(json);
return stats;
}

View File

@ -53,7 +53,7 @@ import org.apache.cassandra.stress.operations.userdefined.ValidatingSchemaQuery;
import org.apache.cassandra.stress.report.Timer;
import org.apache.cassandra.stress.settings.*;
import org.apache.cassandra.stress.util.JavaDriverClient;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
import org.apache.cassandra.stress.util.ThriftClient;
import org.apache.cassandra.thrift.Compression;
import org.apache.cassandra.thrift.ThriftConversion;
@ -99,7 +99,7 @@ public class StressProfile implements Serializable
private static final Pattern lowercaseAlphanumeric = Pattern.compile("[a-z0-9_]+");
public void printSettings(MultiPrintStream out, StressSettings stressSettings)
public void printSettings(ResultLogger out, StressSettings stressSettings)
{
out.printf(" Keyspace Name: %s%n", keyspaceName);
out.printf(" Keyspace CQL: %n***%n%s***%n%n", keyspaceCql);

View File

@ -27,6 +27,8 @@ import java.net.Socket;
import org.apache.commons.cli.*;
import org.apache.cassandra.stress.settings.StressSettings;
import org.apache.cassandra.stress.util.MultiResultLogger;
import org.apache.cassandra.stress.util.ResultLogger;
public class StressServer
{
@ -88,8 +90,9 @@ public class StressServer
{
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
PrintStream out = new PrintStream(socket.getOutputStream());
ResultLogger log = new MultiResultLogger(out);
StressAction action = new StressAction((StressSettings) in.readObject(), out);
StressAction action = new StressAction((StressSettings) in.readObject(), log);
Thread actionThread = new Thread(action);
actionThread.start();

View File

@ -24,7 +24,6 @@ package org.apache.cassandra.stress.report;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
@ -46,6 +45,7 @@ import org.apache.cassandra.stress.StressAction.OpMeasurement;
import org.apache.cassandra.stress.settings.SettingsLog.Level;
import org.apache.cassandra.stress.settings.StressSettings;
import org.apache.cassandra.stress.util.JmxCollector;
import org.apache.cassandra.stress.util.ResultLogger;
import org.apache.cassandra.stress.util.JmxCollector.GcStats;
import org.apache.cassandra.stress.util.Uncertainty;
import org.apache.cassandra.utils.FBUtilities;
@ -54,7 +54,7 @@ import org.apache.commons.lang3.time.DurationFormatUtils;
public class StressMetrics implements MeasurementSink
{
private final List<Consumer> consumers = new ArrayList<>();
private final PrintStream output;
private final ResultLogger output;
private final Thread thread;
private final Uncertainty rowRateUncertainty = new Uncertainty();
private final CountDownLatch stopped = new CountDownLatch(1);
@ -76,7 +76,7 @@ public class StressMetrics implements MeasurementSink
private final TimingInterval totalCurrentInterval;
private final TimingInterval totalSummaryInterval;
public StressMetrics(PrintStream output, final long logIntervalMillis, StressSettings settings)
public StressMetrics(ResultLogger output, final long logIntervalMillis, StressSettings settings)
{
this.output = output;
if(settings.log.hdrFile != null)
@ -114,13 +114,7 @@ public class StressMetrics implements MeasurementSink
t.printStackTrace();
}
System.err.println("Failed to connect over JMX; not collecting these stats");
gcStatsCollector = new Callable<JmxCollector.GcStats>()
{
public JmxCollector.GcStats call() throws Exception
{
return totalGcStats;
}
};
gcStatsCollector = () -> totalGcStats;
}
this.gcStatsCollector = gcStatsCollector;
this.totalCurrentInterval = new TimingInterval(settings.rate.isFixed);
@ -226,7 +220,7 @@ public class StressMetrics implements MeasurementSink
t.serviceTime().recordValue(sTime);
}
private void recordInterval(long intervalEnd, long parkIntervalNs) throws InterruptedException
private void recordInterval(long intervalEnd, long parkIntervalNs)
{
drainConsumerMeasurements(intervalEnd, parkIntervalNs);
@ -351,12 +345,13 @@ public class StressMetrics implements MeasurementSink
public static final String[] HEADMETRICS = new String[]{"type", "total ops","op/s","pk/s","row/s","mean","med",".95",".99",".999","max","time","stderr", "errors", "gc: #", "max ms", "sum ms", "sdv ms", "mb"};
public static final String HEAD = String.format(HEADFORMAT, (Object[]) HEADMETRICS);
private static void printHeader(String prefix, PrintStream output)
private static void printHeader(String prefix, ResultLogger output)
{
output.println(prefix + HEAD);
}
private static void printRow(String prefix, String type, TimingInterval interval, TimingInterval total, JmxCollector.GcStats gcStats, Uncertainty opRateUncertainty, PrintStream output)
private static void printRow(String prefix, String type, TimingInterval interval, TimingInterval total,
JmxCollector.GcStats gcStats, Uncertainty opRateUncertainty, ResultLogger output)
{
output.println(prefix + String.format(ROWFORMAT,
type + ",",
@ -409,7 +404,7 @@ public class StressMetrics implements MeasurementSink
output.println(""); // Newline is important here to separate the aggregates section from the END or the next stress iteration
}
public static void summarise(List<String> ids, List<StressMetrics> summarise, PrintStream out)
public static void summarise(List<String> ids, List<StressMetrics> summarise, ResultLogger out)
{
int idLen = 0;
for (String id : ids)

View File

@ -33,7 +33,7 @@ import org.apache.cassandra.db.marshal.*;
import org.apache.cassandra.stress.generate.Distribution;
import org.apache.cassandra.stress.generate.DistributionFactory;
import org.apache.cassandra.stress.generate.DistributionFixed;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
import org.apache.cassandra.utils.ByteBufferUtil;
/**
@ -178,7 +178,7 @@ public class SettingsColumn implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.printf(" Max Columns Per Key: %d%n",maxColumnsPerKey);
out.printf(" Column Names: %s%n",namestrs);

View File

@ -31,7 +31,7 @@ import com.google.common.util.concurrent.Uninterruptibles;
import org.apache.cassandra.stress.operations.OpDistributionFactory;
import org.apache.cassandra.stress.util.JavaDriverClient;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
import org.apache.cassandra.thrift.ConsistencyLevel;
// Generic command settings - common to read/write/etc
@ -173,7 +173,7 @@ public abstract class SettingsCommand implements Serializable
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.printf(" Type: %s%n", type.toString().toLowerCase());
out.printf(" Count: %,d%n", count);

View File

@ -39,7 +39,7 @@ import org.apache.cassandra.stress.operations.OpDistribution;
import org.apache.cassandra.stress.operations.OpDistributionFactory;
import org.apache.cassandra.stress.operations.predefined.PredefinedOperation;
import org.apache.cassandra.stress.report.Timer;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
// Settings unique to the mixed command type
public class SettingsCommandPreDefined extends SettingsCommand
@ -122,7 +122,7 @@ public class SettingsCommandPreDefined extends SettingsCommand
// CLI utility methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
super.printSettings(out);
out.printf(" Key Size (bytes): %d%n", keySize);

View File

@ -31,7 +31,7 @@ import org.apache.cassandra.stress.operations.OpDistributionFactory;
import org.apache.cassandra.stress.operations.SampledOpDistributionFactory;
import org.apache.cassandra.stress.operations.predefined.PredefinedOperation;
import org.apache.cassandra.stress.report.Timer;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
// Settings unique to the mixed command type
public class SettingsCommandPreDefinedMixed extends SettingsCommandPreDefined
@ -112,7 +112,7 @@ public class SettingsCommandPreDefinedMixed extends SettingsCommandPreDefined
}
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
super.printSettings(out);
out.printf(" Command Ratios: %s%n", ratios);

View File

@ -37,7 +37,7 @@ import org.apache.cassandra.stress.generate.TokenRangeIterator;
import org.apache.cassandra.stress.operations.OpDistributionFactory;
import org.apache.cassandra.stress.operations.SampledOpDistributionFactory;
import org.apache.cassandra.stress.report.Timer;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
// Settings unique to the mixed command type
public class SettingsCommandUser extends SettingsCommand
@ -125,7 +125,7 @@ public class SettingsCommandUser extends SettingsCommand
// CLI utility methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
super.printSettings(out);
out.printf(" Command Ratios: %s%n", ratios);

View File

@ -26,7 +26,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsErrors implements Serializable
{
@ -55,7 +55,7 @@ public class SettingsErrors implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.printf(" Ignore: %b%n", ignore);
out.printf(" Tries: %d%n", tries);

View File

@ -30,7 +30,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsGraph implements Serializable
{
@ -90,7 +90,7 @@ public class SettingsGraph implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.println(" File: " + file);
out.println(" Revision: " + revision);

View File

@ -29,7 +29,7 @@ import java.util.Map;
import com.datastax.driver.core.BatchStatement;
import org.apache.cassandra.stress.generate.DistributionFactory;
import org.apache.cassandra.stress.generate.RatioDistributionFactory;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsInsert implements Serializable
{
@ -73,7 +73,7 @@ public class SettingsInsert implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
if (revisit != null)

View File

@ -21,13 +21,14 @@ package org.apache.cassandra.stress.settings;
*/
import org.apache.cassandra.stress.util.MultiPrintStream;
import java.io.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.apache.cassandra.stress.util.MultiResultLogger;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsLog implements Serializable
{
public static enum Level
@ -68,10 +69,10 @@ public class SettingsLog implements Serializable
level = Level.valueOf(options.level.value().toUpperCase());
}
public MultiPrintStream getOutput() throws FileNotFoundException
public MultiResultLogger getOutput() throws FileNotFoundException
{
// Always print to stdout regardless of whether we're graphing or not
MultiPrintStream stream = new MultiPrintStream(new PrintStream(System.out));
MultiResultLogger stream = new MultiResultLogger(new PrintStream(System.out));
if (file != null)
stream.addStream(new PrintStream(file));
@ -98,7 +99,7 @@ public class SettingsLog implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.printf(" No Summary: %b%n", noSummary);
out.printf(" No Settings: %b%n", noSettings);

View File

@ -30,7 +30,7 @@ import com.datastax.driver.core.AuthProvider;
import com.datastax.driver.core.PlainTextAuthProvider;
import com.datastax.driver.core.ProtocolOptions;
import com.datastax.driver.core.ProtocolVersion;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsMode implements Serializable
{
@ -207,7 +207,7 @@ public class SettingsMode implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.printf(" API: %s%n", api);
out.printf(" Connection Style: %s%n", style);

View File

@ -28,7 +28,7 @@ import java.net.UnknownHostException;
import java.util.*;
import com.datastax.driver.core.Host;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsNode implements Serializable
{
@ -149,7 +149,7 @@ public class SettingsNode implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.println(" Nodes: " + nodes);
out.println(" Is White List: " + isWhiteList);

View File

@ -30,7 +30,7 @@ import com.google.common.collect.ImmutableList;
import org.apache.cassandra.stress.generate.DistributionFactory;
import org.apache.cassandra.stress.generate.PartitionGenerator;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsPopulation implements Serializable
{
@ -127,7 +127,7 @@ public class SettingsPopulation implements Serializable
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
if (distribution != null)
{

View File

@ -26,7 +26,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsPort implements Serializable
{
@ -58,7 +58,7 @@ public class SettingsPort implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.printf(" Native Port: %d%n", nativePort);
out.printf(" Thrift Port: %d%n", thriftPort);

View File

@ -26,7 +26,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsRate implements Serializable
{
@ -96,7 +96,7 @@ public class SettingsRate implements Serializable
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.printf(" Auto: %b%n", auto);
if (auto)
@ -151,14 +151,7 @@ public class SettingsRate implements Serializable
public static Runnable helpPrinter()
{
return new Runnable()
{
@Override
public void run()
{
printHelp();
}
};
return SettingsRate::printHelp;
}
}

View File

@ -27,7 +27,7 @@ import java.util.*;
import com.datastax.driver.core.exceptions.AlreadyExistsException;
import org.apache.cassandra.stress.util.JavaDriverClient;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
import org.apache.cassandra.thrift.*;
import org.apache.cassandra.utils.ByteBufferUtil;
@ -300,7 +300,7 @@ public class SettingsSchema implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.println(" Keyspace: " + keyspace);
out.println(" Replication Strategy: " + replicationStrategy);
@ -309,7 +309,6 @@ public class SettingsSchema implements Serializable
out.println(" Table Compression: " + compression);
out.println(" Table Compaction Strategy: " + compactionStrategy);
out.println(" Table Compaction Strategy Options: " + compactionStrategyOptions);
}

View File

@ -25,7 +25,7 @@ import java.util.Map;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Ints;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
public class SettingsTokenRange implements Serializable
{
@ -70,7 +70,7 @@ public class SettingsTokenRange implements Serializable
return new SettingsTokenRange(options);
}
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.printf(" Wrap: %b%n", wrap);
out.printf(" Split Factor: %d%n", splitFactor);

View File

@ -28,7 +28,7 @@ import java.util.List;
import java.util.Map;
import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.stress.util.MultiPrintStream;
import org.apache.cassandra.stress.util.ResultLogger;
import org.apache.cassandra.thrift.ITransportFactory;
import org.apache.cassandra.thrift.SSLTransportFactory;
import org.apache.cassandra.thrift.TFramedTransportFactory;
@ -146,7 +146,7 @@ public class SettingsTransport implements Serializable
}
// CLI Utility Methods
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.println(" " + options.getOptionAsString());
}

View File

@ -22,13 +22,13 @@ package org.apache.cassandra.stress.settings;
import java.io.Serializable;
import org.apache.cassandra.stress.util.MultiPrintStream;
import java.util.*;
import com.datastax.driver.core.Metadata;
import com.google.common.collect.ImmutableMap;
import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.stress.util.JavaDriverClient;
import org.apache.cassandra.stress.util.ResultLogger;
import org.apache.cassandra.stress.util.SimpleThriftClient;
import org.apache.cassandra.stress.util.SmartThriftClient;
import org.apache.cassandra.stress.util.ThriftClient;
@ -338,7 +338,7 @@ public class StressSettings implements Serializable
SettingsMisc.printHelp();
}
public void printSettings(MultiPrintStream out)
public void printSettings(ResultLogger out)
{
out.println("******************** Stress Settings ********************");
// done

View File

@ -1,288 +0,0 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.cassandra.stress.util;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/** PrintStream that multiplexes to multiple streams */
public class MultiPrintStream extends PrintStream
{
private List<PrintStream> newStreams;
public MultiPrintStream(PrintStream baseStream)
{
super(baseStream);
this.newStreams = new ArrayList();
}
public void addStream(PrintStream printStream)
{
newStreams.add(printStream);
}
@Override
public void flush()
{
super.flush();
for (PrintStream s : newStreams)
s.flush();
}
@Override
public void close()
{
super.close();
for (PrintStream s : newStreams)
s.close();
}
@Override
public boolean checkError()
{
boolean error = super.checkError();
for (PrintStream s : newStreams)
{
if (s.checkError())
error = true;
}
return error;
}
@Override
public void write(int b)
{
super.write(b);
for (PrintStream s: newStreams)
s.write(b);
}
@Override
public void write(byte[] buf, int off, int len)
{
super.write(buf, off, len);
for (PrintStream s: newStreams)
s.write(buf, off, len);
}
@Override
public void print(boolean b)
{
super.print(b);
for (PrintStream s: newStreams)
s.print(b);
}
@Override
public void print(char c)
{
super.print(c);
for (PrintStream s: newStreams)
s.print(c);
}
@Override
public void print(int i)
{
super.print(i);
for (PrintStream s: newStreams)
s.print(i);
}
@Override
public void print(long l)
{
super.print(l);
for (PrintStream s: newStreams)
s.print(l);
}
@Override
public void print(float f)
{
super.print(f);
for (PrintStream s: newStreams)
s.print(f);
}
@Override
public void print(double d)
{
super.print(d);
for (PrintStream s: newStreams)
s.print(d);
}
@Override
public void print(char[] s)
{
super.print(s);
for (PrintStream stream: newStreams)
stream.print(s);
}
@Override
public void print(String s)
{
super.print(s);
for (PrintStream stream: newStreams)
stream.print(s);
}
@Override
public void print(Object obj)
{
super.print(obj);
for (PrintStream s: newStreams)
s.print(obj);
}
@Override
public void println()
{
super.println();
for (PrintStream s: newStreams)
s.println();
}
@Override
public void println(boolean x)
{
super.println(x);
for (PrintStream s: newStreams)
s.println(x);
}
@Override
public void println(char x)
{
super.println(x);
for (PrintStream s: newStreams)
s.println(x);
}
@Override
public void println(int x)
{
super.println(x);
for (PrintStream s: newStreams)
s.println(x);
}
@Override
public void println(long x)
{
super.println(x);
for (PrintStream s: newStreams)
s.println(x);
}
@Override
public void println(float x)
{
super.println(x);
for (PrintStream s: newStreams)
s.println(x);
}
@Override
public void println(double x)
{
super.println(x);
for (PrintStream s: newStreams)
s.println(x);
}
@Override
public void println(char[] x)
{
super.println(x);
for (PrintStream s: newStreams)
s.println(x);
}
@Override
public void println(String x)
{
super.println(x);
for (PrintStream s: newStreams)
s.println(x);
}
@Override
public void println(Object x)
{
super.println(x);
for (PrintStream s: newStreams)
s.println(x);
}
@Override
public PrintStream printf(String format, Object... args)
{
for (PrintStream s: newStreams)
s.printf(format, args);
return super.printf(format, args);
}
@Override
public PrintStream printf(Locale l, String format, Object... args)
{
for (PrintStream s: newStreams)
s.printf(l, format, args);
return super.printf(l, format, args);
}
@Override
public PrintStream append(CharSequence csq)
{
for (PrintStream s: newStreams)
s.append(csq);
return super.append(csq);
}
@Override
public PrintStream append(CharSequence csq, int start, int end)
{
for (PrintStream s: newStreams)
s.append(csq, start, end);
return super.append(csq, start, end);
}
@Override
public PrintStream append(char c)
{
for (PrintStream s: newStreams)
s.append(c);
return super.append(c);
}
@Override
public void write(byte[] b) throws IOException
{
super.write(b);
for (PrintStream s: newStreams)
s.write(b);
}
}

View File

@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.cassandra.stress.util;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
public class MultiResultLogger implements ResultLogger
{
private final List<PrintStream> streams = new ArrayList<>();
public MultiResultLogger(PrintStream printStream)
{
streams.add(printStream);
}
public void println(String line)
{
for (PrintStream stream : streams)
{
stream.println(line);
}
}
public void println()
{
for (PrintStream stream : streams)
{
stream.println();
}
}
public void printException(Exception e)
{
for (PrintStream stream : streams)
{
e.printStackTrace(stream);
}
}
public void flush()
{
for (PrintStream stream : streams)
{
stream.flush();
}
}
public void printf(String s, Object... args)
{
for (PrintStream stream : streams)
{
stream.printf(s, args);
}
}
public void addStream(PrintStream additionalPrintStream)
{
streams.add(additionalPrintStream);
}
}

View File

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.cassandra.stress.util;
public class NoopResultLogger implements ResultLogger
{
NoopResultLogger() { }
public void println(String line)
{
}
public void println()
{
}
public void printException(Exception e)
{
}
public void flush()
{
}
public void printf(String s, Object... args)
{
}
}

View File

@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.cassandra.stress.util;
public interface ResultLogger
{
static final ResultLogger NOOP = new NoopResultLogger();
void println(String line);
void println();
void printException(Exception e);
void flush();
void printf(String s, Object... args);
}

View File

@ -89,7 +89,6 @@ var drawGraph = function() {
stress_metric_names[v] = stats['stats'][0]['metrics'][i];
});
//Replace names of shorthand metric names with longer ones:
//Replace names of shorthand metric names with longer ones:
$.extend(stress_metric_names, {
"mean": "latency mean",
"med" : "latency median",
@ -224,7 +223,7 @@ var drawGraph = function() {
if (metric == 'num_timeouts') {
return d[stress_metrics.indexOf('interval_op_rate')] - d[stress_metrics.indexOf('interval_key_rate')];
}
}
}
};
//Parse the dates:
@ -321,13 +320,13 @@ var drawGraph = function() {
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) {
.x(function(d) {
return x(d[time_index]); //time in seconds
})
.y(function(d) {
.y(function(d) {
return y(getMetricValue(d));
});
$("body").append("<div id='svg_container'>");
var redrawLines = function() {
@ -384,7 +383,7 @@ var drawGraph = function() {
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// x-axis label
// x-axis label
svg.append("text")
.attr("x", width / 2 )
.attr("y", height + 30 )
@ -432,7 +431,7 @@ var drawGraph = function() {
var y_offset = 425 + (i*25) + 70;
}
var x_offset = -550;
return "translate(" + x_offset + "," + y_offset + ")";
return "translate(" + x_offset + "," + y_offset + ")";
});
var renderLegendText = function(linenum, getTextCallback) {
@ -443,7 +442,7 @@ var drawGraph = function() {
.style("font-family", "monospace")
.style("font-size", "1.2em")
.style("text-anchor", "start")
.text(function(d) {
.text(function(d) {
return getTextCallback(d);
});
};
@ -511,23 +510,23 @@ var drawGraph = function() {
});
renderLegendText(13, function(title) {
return padTextEnd('total gc mb', 26) + ' : ' + data_by_title[title]['total gc mb'];
return padTextEnd('total gc memory', 26) + ' : ' + data_by_title[title]['total gc memory'];
});
renderLegendText(14, function(title) {
return padTextEnd('total gc time (s)', 26) + ' : ' + data_by_title[title]['total gc time (s)'];
return padTextEnd('total gc time', 26) + ' : ' + data_by_title[title]['total gc time'];
});
renderLegendText(15, function(title) {
return padTextEnd('avg gc time(ms)', 26) + ' : ' + data_by_title[title]['avg gc time(ms)'];
return padTextEnd('avg gc time', 26) + ' : ' + data_by_title[title]['avg gc time'];
});
renderLegendText(16, function(title) {
return padTextEnd('stdev gc time(ms)', 26) + ' : ' + data_by_title[title]['stdev gc time(ms)'];
return padTextEnd('stddev gc time', 26) + ' : ' + data_by_title[title]['stddev gc time'];
});
renderLegendText(17, function(title) {
return padTextEnd('Total operation time', 26) + ' : ' + data_by_title[title]['Total operation time'];
return padTextEnd('Total operation time', 26) + ' : ' + data_by_title[title]['total operation time'];
});
renderLegendText(18, function(title) {

View File

@ -0,0 +1,105 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.cassandra.stress.util;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.junit.Test;
import static org.junit.Assert.*;
public class MultiResultLoggerTest
{
public static final OutputStream NOOP = new OutputStream()
{
public void write(int b) throws IOException
{
}
};
@Test
public void delegatesToInitialPrintStream() throws Exception
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(output, true);
MultiResultLogger underTest = new MultiResultLogger(printStream);
underTest.println("Very important result");
assertEquals("Very important result\n", output.toString());
}
@Test
public void printingExceptions() throws Exception
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(output, true);
MultiResultLogger underTest = new MultiResultLogger(printStream);
underTest.printException(new RuntimeException("Bad things"));
String stackTrace = output.toString();
assertTrue("Expected strack trace to be printed but got: " + stackTrace, stackTrace.startsWith("java.lang.RuntimeException: Bad things\n" +
"\tat org.apache.cassandra.stress.util.MultiResultLoggerTest.printingExceptions"));
}
@Test
public void delegatesToAdditionalPrintStreams() throws Exception
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
PrintStream additionalPrintStream = new PrintStream(output, true);
MultiResultLogger underTest = new MultiResultLogger(new PrintStream(NOOP));
underTest.addStream(additionalPrintStream);
underTest.println("Very important result");
assertEquals("Very important result\n", output.toString());
}
@Test
public void delegatesPrintfToAdditionalPrintStreams() throws Exception
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
PrintStream additionalPrintStream = new PrintStream(output, true);
MultiResultLogger underTest = new MultiResultLogger(new PrintStream(NOOP));
underTest.addStream(additionalPrintStream);
underTest.printf("%s %s %s", "one", "two", "three");
assertEquals("one two three", output.toString());
}
@Test
public void delegatesPrintlnToAdditionalPrintStreams() throws Exception
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
PrintStream additionalPrintStream = new PrintStream(output, true);
MultiResultLogger underTest = new MultiResultLogger(new PrintStream(NOOP));
underTest.addStream(additionalPrintStream);
underTest.println();
assertEquals("\n", output.toString());
}
}