diff --git a/CHANGES.txt b/CHANGES.txt index 312713f60a..8e39d95d6d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -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) diff --git a/tools/stress/src/org/apache/cassandra/stress/Stress.java b/tools/stress/src/org/apache/cassandra/stress/Stress.java index 638290444c..925f7098a8 100644 --- a/tools/stress/src/org/apache/cassandra/stress/Stress.java +++ b/tools/stress/src/org/apache/cassandra/stress/Stress.java @@ -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) { diff --git a/tools/stress/src/org/apache/cassandra/stress/StressAction.java b/tools/stress/src/org/apache/cassandra/stress/StressAction.java index f3d9cbd1c8..eaee752318 100644 --- a/tools/stress/src/org/apache/cassandra/stress/StressAction.java +++ b/tools/stress/src/org/apache/cassandra/stress/StressAction.java @@ -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(); diff --git a/tools/stress/src/org/apache/cassandra/stress/StressGraph.java b/tools/stress/src/org/apache/cassandra/stress/StressGraph.java index 196964c30d..17b718d183 100644 --- a/tools/stress/src/org/apache/cassandra/stress/StressGraph.java +++ b/tools/stress/src/org/apache/cassandra/stress/StressGraph.java @@ -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; } diff --git a/tools/stress/src/org/apache/cassandra/stress/StressProfile.java b/tools/stress/src/org/apache/cassandra/stress/StressProfile.java index 4fb70c6544..011b7d773d 100644 --- a/tools/stress/src/org/apache/cassandra/stress/StressProfile.java +++ b/tools/stress/src/org/apache/cassandra/stress/StressProfile.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/StressServer.java b/tools/stress/src/org/apache/cassandra/stress/StressServer.java index a6dfaf4501..793f8f0eba 100644 --- a/tools/stress/src/org/apache/cassandra/stress/StressServer.java +++ b/tools/stress/src/org/apache/cassandra/stress/StressServer.java @@ -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(); diff --git a/tools/stress/src/org/apache/cassandra/stress/report/StressMetrics.java b/tools/stress/src/org/apache/cassandra/stress/report/StressMetrics.java index a5965471a2..52e90e2bcb 100644 --- a/tools/stress/src/org/apache/cassandra/stress/report/StressMetrics.java +++ b/tools/stress/src/org/apache/cassandra/stress/report/StressMetrics.java @@ -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 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() - { - 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 ids, List summarise, PrintStream out) + public static void summarise(List ids, List summarise, ResultLogger out) { int idLen = 0; for (String id : ids) diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsColumn.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsColumn.java index d39e11b0cf..79d8d25312 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsColumn.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsColumn.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommand.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommand.java index f1f6831fa1..c3a171e7a6 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommand.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommand.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java index b7f87e95a6..88755765db 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefinedMixed.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefinedMixed.java index 9c58c5b7a8..72f6c8684d 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefinedMixed.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefinedMixed.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandUser.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandUser.java index 66e6df3046..4c7ad91e93 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandUser.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandUser.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsErrors.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsErrors.java index 118312f440..aae4dd9010 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsErrors.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsErrors.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsGraph.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsGraph.java index 7b3491b83b..90bb99a7be 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsGraph.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsGraph.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsInsert.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsInsert.java index d6927ec2a2..59edf77f29 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsInsert.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsInsert.java @@ -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) diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsLog.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsLog.java index dcc220f1fb..ae77e0a780 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsLog.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsLog.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMode.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMode.java index 127b938e3a..bebfa5febc 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMode.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsMode.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsNode.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsNode.java index 1a6a243bbe..95339e3f88 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsNode.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsNode.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPopulation.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPopulation.java index 0d7b056566..66984edb35 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPopulation.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPopulation.java @@ -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) { diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPort.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPort.java index 39259a8862..e6d3838784 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPort.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsPort.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsRate.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsRate.java index 211a301e44..c7d322a7f6 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsRate.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsRate.java @@ -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; } } diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsSchema.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsSchema.java index 4c5c99ed98..fc65c9aa8d 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsSchema.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsSchema.java @@ -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); - } diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTokenRange.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTokenRange.java index 648823bab9..d8b6701eca 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTokenRange.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTokenRange.java @@ -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); diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTransport.java b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTransport.java index e12b645bd3..75b29b31af 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTransport.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsTransport.java @@ -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()); } diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java b/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java index 8f5e69aad1..136c8d0177 100644 --- a/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java +++ b/tools/stress/src/org/apache/cassandra/stress/settings/StressSettings.java @@ -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 diff --git a/tools/stress/src/org/apache/cassandra/stress/util/MultiPrintStream.java b/tools/stress/src/org/apache/cassandra/stress/util/MultiPrintStream.java deleted file mode 100644 index d299013234..0000000000 --- a/tools/stress/src/org/apache/cassandra/stress/util/MultiPrintStream.java +++ /dev/null @@ -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 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); - } - -} diff --git a/tools/stress/src/org/apache/cassandra/stress/util/MultiResultLogger.java b/tools/stress/src/org/apache/cassandra/stress/util/MultiResultLogger.java new file mode 100644 index 0000000000..3d2103c929 --- /dev/null +++ b/tools/stress/src/org/apache/cassandra/stress/util/MultiResultLogger.java @@ -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 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); + } +} diff --git a/tools/stress/src/org/apache/cassandra/stress/util/NoopResultLogger.java b/tools/stress/src/org/apache/cassandra/stress/util/NoopResultLogger.java new file mode 100644 index 0000000000..f1b2d8c38a --- /dev/null +++ b/tools/stress/src/org/apache/cassandra/stress/util/NoopResultLogger.java @@ -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) + { + } +} diff --git a/tools/stress/src/org/apache/cassandra/stress/util/ResultLogger.java b/tools/stress/src/org/apache/cassandra/stress/util/ResultLogger.java new file mode 100644 index 0000000000..4097417380 --- /dev/null +++ b/tools/stress/src/org/apache/cassandra/stress/util/ResultLogger.java @@ -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); +} diff --git a/tools/stress/src/resources/org/apache/cassandra/stress/graph/graph.html b/tools/stress/src/resources/org/apache/cassandra/stress/graph/graph.html index 54cd469230..86bedfc07b 100644 --- a/tools/stress/src/resources/org/apache/cassandra/stress/graph/graph.html +++ b/tools/stress/src/resources/org/apache/cassandra/stress/graph/graph.html @@ -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("
"); 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) { diff --git a/tools/stress/test/unit/org/apache/cassandra/stress/util/MultiResultLoggerTest.java b/tools/stress/test/unit/org/apache/cassandra/stress/util/MultiResultLoggerTest.java new file mode 100644 index 0000000000..f0c99b8631 --- /dev/null +++ b/tools/stress/test/unit/org/apache/cassandra/stress/util/MultiResultLoggerTest.java @@ -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()); + } +} \ No newline at end of file