diff --git a/.circleci/config.yml b/.circleci/config.yml index 1fb2fcb13d..2e4051365c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ jobs: j8_jvm_upgrade_dtests: docker: - image: spod/cassandra-testing-ubuntu1810-java11-w-dependencies:20190306 - resource_class: medium + resource_class: xlarge working_directory: ~/ shell: /bin/bash -eo pipefail -l parallelism: 1 @@ -88,8 +88,8 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 build: @@ -169,17 +169,17 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 j8_dtests-no-vnodes: docker: - image: spod/cassandra-testing-ubuntu1810-java11-w-dependencies:20190306 - resource_class: medium + resource_class: xlarge working_directory: ~/ shell: /bin/bash -eo pipefail -l - parallelism: 4 + parallelism: 100 steps: - attach_workspace: at: /home/cassandra @@ -196,7 +196,7 @@ jobs: # rebuild the docker image! (it automatically pulls the latest requirements.txt on build) source ~/env/bin/activate export PATH=$JAVA_HOME/bin:$PATH - pip3 install --exists-action w --upgrade -r ~/cassandra-dtest/requirements.txt + pip3 install --upgrade -r ~/cassandra-dtest/requirements.txt pip3 freeze - run: name: Determine Tests to Run (j8_without_vnodes) @@ -227,17 +227,17 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 j8_upgradetests-no-vnodes: docker: - image: spod/cassandra-testing-ubuntu1810-java11-w-dependencies:20190306 - resource_class: medium + resource_class: xlarge working_directory: ~/ shell: /bin/bash -eo pipefail -l - parallelism: 4 + parallelism: 100 steps: - attach_workspace: at: /home/cassandra @@ -254,7 +254,7 @@ jobs: # rebuild the docker image! (it automatically pulls the latest requirements.txt on build) source ~/env/bin/activate export PATH=$JAVA_HOME/bin:$PATH - pip3 install --exists-action w --upgrade -r ~/cassandra-dtest/requirements.txt + pip3 install --upgrade -r ~/cassandra-dtest/requirements.txt pip3 freeze - run: name: Determine Tests to Run (j8_upgradetests_without_vnodes) @@ -326,17 +326,17 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 j8_unit_tests: docker: - image: spod/cassandra-testing-ubuntu1810-java11-w-dependencies:20190306 - resource_class: medium + resource_class: xlarge working_directory: ~/ shell: /bin/bash -eo pipefail -l - parallelism: 4 + parallelism: 100 steps: - attach_workspace: at: /home/cassandra @@ -418,17 +418,17 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 j8_dtests-with-vnodes: docker: - image: spod/cassandra-testing-ubuntu1810-java11-w-dependencies:20190306 - resource_class: medium + resource_class: xlarge working_directory: ~/ shell: /bin/bash -eo pipefail -l - parallelism: 4 + parallelism: 100 steps: - attach_workspace: at: /home/cassandra @@ -445,7 +445,7 @@ jobs: # rebuild the docker image! (it automatically pulls the latest requirements.txt on build) source ~/env/bin/activate export PATH=$JAVA_HOME/bin:$PATH - pip3 install --exists-action w --upgrade -r ~/cassandra-dtest/requirements.txt + pip3 install --upgrade -r ~/cassandra-dtest/requirements.txt pip3 freeze - run: name: Determine Tests to Run (j8_with_vnodes) @@ -476,14 +476,14 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 j8_jvm_dtests: docker: - image: spod/cassandra-testing-ubuntu1810-java11-w-dependencies:20190306 - resource_class: medium + resource_class: xlarge working_directory: ~/ shell: /bin/bash -eo pipefail -l parallelism: 1 @@ -568,14 +568,14 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 utests_long: docker: - image: spod/cassandra-testing-ubuntu1810-java11-w-dependencies:20190306 - resource_class: medium + resource_class: xlarge working_directory: ~/ shell: /bin/bash -eo pipefail -l parallelism: 1 @@ -614,17 +614,17 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 utests_compression: docker: - image: spod/cassandra-testing-ubuntu1810-java11-w-dependencies:20190306 - resource_class: medium + resource_class: xlarge working_directory: ~/ shell: /bin/bash -eo pipefail -l - parallelism: 4 + parallelism: 100 steps: - attach_workspace: at: /home/cassandra @@ -706,8 +706,8 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 j8_dtest_jars_build: @@ -781,8 +781,8 @@ jobs: - CASSANDRA_SKIP_SYNC: true - DTEST_REPO: git://github.com/apache/cassandra-dtest.git - DTEST_BRANCH: master - - CCM_MAX_HEAP_SIZE: 1024M - - CCM_HEAP_NEWSIZE: 256M + - CCM_MAX_HEAP_SIZE: 2048M + - CCM_HEAP_NEWSIZE: 512M - JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 - JDK_HOME: /usr/lib/jvm/java-8-openjdk-amd64 workflows: diff --git a/src/java/org/apache/cassandra/tools/NodeProbe.java b/src/java/org/apache/cassandra/tools/NodeProbe.java index 24258218cb..caba806bd3 100644 --- a/src/java/org/apache/cassandra/tools/NodeProbe.java +++ b/src/java/org/apache/cassandra/tools/NodeProbe.java @@ -120,6 +120,7 @@ public class NodeProbe implements AutoCloseable protected StorageProxyMBean spProxy; protected HintedHandOffManagerMBean hhProxy; protected BatchlogManagerMBean bmProxy; + protected Output output; private boolean failed; /** @@ -138,6 +139,7 @@ public class NodeProbe implements AutoCloseable this.port = port; this.username = username; this.password = password; + this.output = Output.CONSOLE; connect(); } @@ -152,6 +154,7 @@ public class NodeProbe implements AutoCloseable { this.host = host; this.port = port; + this.output = Output.CONSOLE; connect(); } @@ -165,6 +168,7 @@ public class NodeProbe implements AutoCloseable { this.host = host; this.port = defaultPort; + this.output = Output.CONSOLE; connect(); } @@ -173,6 +177,7 @@ public class NodeProbe implements AutoCloseable // this constructor is only used for extensions to rewrite their own connect method this.host = ""; this.port = 0; + this.output = Output.CONSOLE; } /** @@ -253,6 +258,16 @@ public class NodeProbe implements AutoCloseable } } + public void setOutput(Output output) + { + this.output = output; + } + + public Output output() + { + return output; + } + public int forceKeyspaceCleanup(int jobs, String keyspaceName, String... tables) throws IOException, ExecutionException, InterruptedException { return ssProxy.forceKeyspaceCleanup(jobs, keyspaceName, tables); diff --git a/src/java/org/apache/cassandra/tools/NodeTool.java b/src/java/org/apache/cassandra/tools/NodeTool.java index dbff241bd9..a195aa7987 100644 --- a/src/java/org/apache/cassandra/tools/NodeTool.java +++ b/src/java/org/apache/cassandra/tools/NodeTool.java @@ -23,7 +23,8 @@ import java.net.UnknownHostException; import java.text.SimpleDateFormat; import java.util.*; import java.util.Map.Entry; -import java.util.function.Consumer; +import java.util.Scanner; +import java.util.SortedMap; import com.google.common.base.Joiner; import com.google.common.base.Throwables; @@ -48,20 +49,22 @@ public class NodeTool private static final String HISTORYFILE = "nodetool.history"; private final INodeProbeFactory nodeProbeFactory; + private final Output output; public static void main(String... args) { - System.exit(new NodeTool(new NodeProbeFactory()).execute(args)); + System.exit(new NodeTool(new NodeProbeFactory(), Output.CONSOLE).execute(args)); } - public NodeTool(INodeProbeFactory nodeProbeFactory) + public NodeTool(INodeProbeFactory nodeProbeFactory, Output output) { this.nodeProbeFactory = nodeProbeFactory; + this.output = output; } public int execute(String... args) { - List>> commands = newArrayList( + List> commands = newArrayList( CassHelp.class, Info.class, Ring.class, @@ -153,7 +156,7 @@ public class NodeTool RefreshSizeEstimates.class ); - Cli.CliBuilder> builder = Cli.builder("nodetool"); + Cli.CliBuilder builder = Cli.builder("nodetool"); builder.withDescription("Manage your Cassandra cluster") .withDefaultCommand(CassHelp.class) @@ -165,14 +168,14 @@ public class NodeTool .withDefaultCommand(CassHelp.class) .withCommand(BootstrapResume.class); - Cli> parser = builder.build(); + Cli parser = builder.build(); int status = 0; try { - Consumer parse = parser.parse(args); + NodeToolCmdRunnable parse = parser.parse(args); printHistory(args); - parse.accept(nodeProbeFactory); + parse.run(nodeProbeFactory, output); } catch (IllegalArgumentException | IllegalStateException | ParseArgumentsMissingException | @@ -216,26 +219,31 @@ public class NodeTool protected void badUse(Exception e) { - System.out.println("nodetool: " + e.getMessage()); - System.out.println("See 'nodetool help' or 'nodetool help '."); + output.out.println("nodetool: " + e.getMessage()); + output.out.println("See 'nodetool help' or 'nodetool help '."); } protected void err(Throwable e) { - System.err.println("error: " + e.getMessage()); - System.err.println("-- StackTrace --"); - System.err.println(getStackTraceAsString(e)); + output.err.println("error: " + e.getMessage()); + output.err.println("-- StackTrace --"); + output.err.println(getStackTraceAsString(e)); } - public static class CassHelp extends Help implements Consumer + public static class CassHelp extends Help implements NodeToolCmdRunnable { - public void accept(INodeProbeFactory nodeProbeFactory) + public void run(INodeProbeFactory nodeProbeFactory, Output output) { run(); } } - public static abstract class NodeToolCmd implements Consumer + interface NodeToolCmdRunnable + { + void run(INodeProbeFactory nodeProbeFactory, Output output); + } + + public static abstract class NodeToolCmd implements NodeToolCmdRunnable { @Option(type = OptionType.GLOBAL, name = {"-h", "--host"}, description = "Node hostname or ip address") @@ -254,14 +262,17 @@ public class NodeTool private String passwordFilePath = EMPTY; private INodeProbeFactory nodeProbeFactory; + protected Output output; - public void accept(INodeProbeFactory nodeProbeFactory) + @Override + public void run(INodeProbeFactory nodeProbeFactory, Output output) { this.nodeProbeFactory = nodeProbeFactory; - run(); + this.output = output; + runInternal(); } - public void run() + public void runInternal() { if (isNotEmpty(username)) { if (isNotEmpty(passwordFilePath)) @@ -334,10 +345,11 @@ public class NodeTool nodeClient = nodeProbeFactory.create(host, parseInt(port)); else nodeClient = nodeProbeFactory.create(host, parseInt(port), username, password); + nodeClient.setOutput(output); } catch (IOException e) { Throwable rootCause = Throwables.getRootCause(e); - System.err.println(format("nodetool: Failed to connect to '%s:%s' - %s: '%s'.", host, port, rootCause.getClass().getSimpleName(), rootCause.getMessage())); + output.err.println(format("nodetool: Failed to connect to '%s:%s' - %s: '%s'.", host, port, rootCause.getClass().getSimpleName(), rootCause.getMessage())); System.exit(1); } diff --git a/src/java/org/apache/cassandra/tools/Output.java b/src/java/org/apache/cassandra/tools/Output.java new file mode 100644 index 0000000000..1d2fcb3a63 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/Output.java @@ -0,0 +1,35 @@ +/* + * 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.tools; + +import java.io.PrintStream; + +public class Output +{ + public final static Output CONSOLE = new Output(System.out, System.err); + + public final PrintStream out; + public final PrintStream err; + + public Output(PrintStream out, PrintStream err) + { + this.out = out; + this.err = err; + } +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/BootstrapResume.java b/src/java/org/apache/cassandra/tools/nodetool/BootstrapResume.java index bb47e10c04..3f121217ef 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/BootstrapResume.java +++ b/src/java/org/apache/cassandra/tools/nodetool/BootstrapResume.java @@ -33,11 +33,11 @@ public class BootstrapResume extends NodeToolCmd { try { - probe.resumeBootstrap(System.out); + probe.resumeBootstrap(probe.output().out); } catch (IOException e) { throw new IOError(e); } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/Cleanup.java b/src/java/org/apache/cassandra/tools/nodetool/Cleanup.java index 47c65c8fe5..e60d87efa7 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Cleanup.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Cleanup.java @@ -52,7 +52,7 @@ public class Cleanup extends NodeToolCmd try { - probe.forceKeyspaceCleanup(System.out, jobs, keyspace, tableNames); + probe.forceKeyspaceCleanup(probe.output().out, jobs, keyspace, tableNames); } catch (Exception e) { @@ -60,4 +60,4 @@ public class Cleanup extends NodeToolCmd } } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/ClearSnapshot.java b/src/java/org/apache/cassandra/tools/nodetool/ClearSnapshot.java index 7167bd90ea..3016716582 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/ClearSnapshot.java +++ b/src/java/org/apache/cassandra/tools/nodetool/ClearSnapshot.java @@ -55,7 +55,7 @@ public class ClearSnapshot extends NodeToolCmd if (!snapshotName.isEmpty()) sb.append(" with snapshot name [").append(snapshotName).append("]"); - System.out.println(sb.toString()); + probe.output().out.println(sb.toString()); try { @@ -65,4 +65,4 @@ public class ClearSnapshot extends NodeToolCmd throw new RuntimeException("Error during clearing snapshots", e); } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/CompactionHistory.java b/src/java/org/apache/cassandra/tools/nodetool/CompactionHistory.java index cbb054a68d..55f7fc5348 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/CompactionHistory.java +++ b/src/java/org/apache/cassandra/tools/nodetool/CompactionHistory.java @@ -20,6 +20,7 @@ package org.apache.cassandra.tools.nodetool; import static com.google.common.collect.Iterables.toArray; import io.airlift.command.Command; +import java.io.PrintStream; import java.util.List; import java.util.Set; @@ -34,24 +35,25 @@ public class CompactionHistory extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println("Compaction History: "); + PrintStream out = probe.output().out; + out.println("Compaction History: "); TabularData tabularData = probe.getCompactionHistory(); if (tabularData.isEmpty()) { - System.out.printf("There is no compaction history"); + out.printf("There is no compaction history"); return; } String format = "%-41s%-19s%-29s%-26s%-15s%-15s%s%n"; List indexNames = tabularData.getTabularType().getIndexNames(); - System.out.printf(format, toArray(indexNames, Object.class)); + out.printf(format, toArray(indexNames, Object.class)); Set values = tabularData.keySet(); for (Object eachValue : values) { List value = (List) eachValue; - System.out.printf(format, toArray(value, Object.class)); + out.printf(format, toArray(value, Object.class)); } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/CompactionStats.java b/src/java/org/apache/cassandra/tools/nodetool/CompactionStats.java index 36b5733609..30830dd19c 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/CompactionStats.java +++ b/src/java/org/apache/cassandra/tools/nodetool/CompactionStats.java @@ -21,6 +21,7 @@ import static java.lang.String.format; import io.airlift.command.Command; import io.airlift.command.Option; +import java.io.PrintStream; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -45,8 +46,9 @@ public class CompactionStats extends NodeToolCmd @Override public void execute(NodeProbe probe) { + PrintStream out = probe.output().out; CompactionManagerMBean cm = probe.getCompactionManagerProxy(); - System.out.println("pending tasks: " + probe.getCompactionMetric("PendingTasks")); + out.println("pending tasks: " + probe.getCompactionMetric("PendingTasks")); long remainingBytes = 0; List> compactions = cm.getCompactions(); if (!compactions.isEmpty()) @@ -85,7 +87,7 @@ public class CompactionStats extends NodeToolCmd for (String[] line : lines) { - System.out.printf(format, line[0], line[1], line[2], line[3], line[4], line[5], line[6], line[7]); + out.printf(format, line[0], line[1], line[2], line[3], line[4], line[5], line[6], line[7]); } String remainingTime = "n/a"; @@ -94,7 +96,7 @@ public class CompactionStats extends NodeToolCmd long remainingTimeInSecs = remainingBytes / (1024L * 1024L * compactionThroughput); remainingTime = format("%dh%02dm%02ds", remainingTimeInSecs / 3600, (remainingTimeInSecs % 3600) / 60, (remainingTimeInSecs % 60)); } - System.out.printf("%25s%10s%n", "Active compaction remaining time : ", remainingTime); + out.printf("%25s%10s%n", "Active compaction remaining time : ", remainingTime); } } diff --git a/src/java/org/apache/cassandra/tools/nodetool/DescribeCluster.java b/src/java/org/apache/cassandra/tools/nodetool/DescribeCluster.java index 81dee203a5..8cab62e435 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/DescribeCluster.java +++ b/src/java/org/apache/cassandra/tools/nodetool/DescribeCluster.java @@ -20,6 +20,7 @@ package org.apache.cassandra.tools.nodetool; import static java.lang.String.format; import io.airlift.command.Command; +import java.io.PrintStream; import java.util.List; import java.util.Map; @@ -32,18 +33,19 @@ public class DescribeCluster extends NodeToolCmd @Override public void execute(NodeProbe probe) { + PrintStream out = probe.output().out; // display cluster name, snitch and partitioner - System.out.println("Cluster Information:"); - System.out.println("\tName: " + probe.getClusterName()); - System.out.println("\tSnitch: " + probe.getEndpointSnitchInfoProxy().getSnitchName()); - System.out.println("\tPartitioner: " + probe.getPartitioner()); + out.println("Cluster Information:"); + out.println("\tName: " + probe.getClusterName()); + out.println("\tSnitch: " + probe.getEndpointSnitchInfoProxy().getSnitchName()); + out.println("\tPartitioner: " + probe.getPartitioner()); // display schema version for each node - System.out.println("\tSchema versions:"); + out.println("\tSchema versions:"); Map> schemaVersions = probe.getSpProxy().getSchemaVersions(); for (String version : schemaVersions.keySet()) { - System.out.println(format("\t\t%s: %s%n", version, schemaVersions.get(version))); + out.println(format("\t\t%s: %s%n", version, schemaVersions.get(version))); } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/DescribeRing.java b/src/java/org/apache/cassandra/tools/nodetool/DescribeRing.java index a120ffea8b..30f488aa8b 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/DescribeRing.java +++ b/src/java/org/apache/cassandra/tools/nodetool/DescribeRing.java @@ -22,6 +22,7 @@ import io.airlift.command.Arguments; import io.airlift.command.Command; import java.io.IOException; +import java.io.PrintStream; import org.apache.cassandra.tools.NodeProbe; import org.apache.cassandra.tools.NodeTool.NodeToolCmd; @@ -35,13 +36,14 @@ public class DescribeRing extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println("Schema Version:" + probe.getSchemaVersion()); - System.out.println("TokenRange: "); + PrintStream out = probe.output().out; + out.println("Schema Version:" + probe.getSchemaVersion()); + out.println("TokenRange: "); try { for (String tokenRangeString : probe.describeRing(keyspace)) { - System.out.println("\t" + tokenRangeString); + out.println("\t" + tokenRangeString); } } catch (IOException e) { diff --git a/src/java/org/apache/cassandra/tools/nodetool/FailureDetectorInfo.java b/src/java/org/apache/cassandra/tools/nodetool/FailureDetectorInfo.java index 3c0303d6cb..d3153a72bd 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/FailureDetectorInfo.java +++ b/src/java/org/apache/cassandra/tools/nodetool/FailureDetectorInfo.java @@ -34,12 +34,12 @@ public class FailureDetectorInfo extends NodeToolCmd public void execute(NodeProbe probe) { TabularData data = probe.getFailureDetectorPhilValues(); - System.out.printf("%10s,%16s%n", "Endpoint", "Phi"); + probe.output().out.printf("%10s,%16s%n", "Endpoint", "Phi"); for (Object o : data.keySet()) { @SuppressWarnings({ "rawtypes", "unchecked" }) CompositeData datum = data.get(((List) o).toArray(new Object[((List) o).size()])); - System.out.printf("%10s,%16.8f%n",datum.get("Endpoint"), datum.get("PHI")); + probe.output().out.printf("%10s,%16.8f%n", datum.get("Endpoint"), datum.get("PHI")); } } } diff --git a/src/java/org/apache/cassandra/tools/nodetool/GcStats.java b/src/java/org/apache/cassandra/tools/nodetool/GcStats.java index dd38fe7b2d..513f74c9ea 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GcStats.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GcStats.java @@ -31,7 +31,7 @@ public class GcStats extends NodeToolCmd double[] stats = probe.getAndResetGCStats(); double mean = stats[2] / stats[5]; double stdev = Math.sqrt((stats[3] / stats[5]) - (mean * mean)); - System.out.printf("%20s%20s%20s%20s%20s%20s%25s%n", "Interval (ms)", "Max GC Elapsed (ms)", "Total GC Elapsed (ms)", "Stdev GC Elapsed (ms)", "GC Reclaimed (MB)", "Collections", "Direct Memory Bytes"); - System.out.printf("%20.0f%20.0f%20.0f%20.0f%20.0f%20.0f%25d%n", stats[0], stats[1], stats[2], stdev, stats[4], stats[5], (long)stats[6]); + probe.output().out.printf("%20s%20s%20s%20s%20s%20s%25s%n", "Interval (ms)", "Max GC Elapsed (ms)", "Total GC Elapsed (ms)", "Stdev GC Elapsed (ms)", "GC Reclaimed (MB)", "Collections", "Direct Memory Bytes"); + probe.output().out.printf("%20.0f%20.0f%20.0f%20.0f%20.0f%20.0f%25d%n", stats[0], stats[1], stats[2], stdev, stats[4], stats[5], (long)stats[6]); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetCompactionThreshold.java b/src/java/org/apache/cassandra/tools/nodetool/GetCompactionThreshold.java index 6c629ded5e..1f1d3b4515 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GetCompactionThreshold.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GetCompactionThreshold.java @@ -42,8 +42,8 @@ public class GetCompactionThreshold extends NodeToolCmd String cf = args.get(1); ColumnFamilyStoreMBean cfsProxy = probe.getCfsProxy(ks, cf); - System.out.println("Current compaction thresholds for " + ks + "/" + cf + ": \n" + - " min = " + cfsProxy.getMinimumCompactionThreshold() + ", " + - " max = " + cfsProxy.getMaximumCompactionThreshold()); + probe.output().out.println("Current compaction thresholds for " + ks + "/" + cf + ": \n" + + " min = " + cfsProxy.getMinimumCompactionThreshold() + ", " + + " max = " + cfsProxy.getMaximumCompactionThreshold()); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetCompactionThroughput.java b/src/java/org/apache/cassandra/tools/nodetool/GetCompactionThroughput.java index c3af18460e..90e9355bbf 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GetCompactionThroughput.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GetCompactionThroughput.java @@ -28,6 +28,6 @@ public class GetCompactionThroughput extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println("Current compaction throughput: " + probe.getCompactionThroughput() + " MB/s"); + probe.output().out.println("Current compaction throughput: " + probe.getCompactionThroughput() + " MB/s"); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetEndpoints.java b/src/java/org/apache/cassandra/tools/nodetool/GetEndpoints.java index 49d2148e7d..8ad7c60784 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GetEndpoints.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GetEndpoints.java @@ -45,7 +45,7 @@ public class GetEndpoints extends NodeToolCmd List endpoints = probe.getEndpoints(ks, table, key); for (InetAddress endpoint : endpoints) { - System.out.println(endpoint.getHostAddress()); + probe.output().out.println(endpoint.getHostAddress()); } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetInterDCStreamThroughput.java b/src/java/org/apache/cassandra/tools/nodetool/GetInterDCStreamThroughput.java index 4c354c03ff..34c90c3f09 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GetInterDCStreamThroughput.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GetInterDCStreamThroughput.java @@ -28,6 +28,6 @@ public class GetInterDCStreamThroughput extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println("Current inter-datacenter stream throughput: " + probe.getInterDCStreamThroughput() + " Mb/s"); + probe.output().out.println("Current inter-datacenter stream throughput: " + probe.getInterDCStreamThroughput() + " Mb/s"); } } diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java b/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java index 7ce0017cd1..0482bdcb5b 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java @@ -31,8 +31,8 @@ public class GetLoggingLevels extends NodeToolCmd public void execute(NodeProbe probe) { // what if some one set a very long logger name? 50 space may not be enough... - System.out.printf("%n%-50s%10s%n", "Logger Name", "Log Level"); + probe.output().out.printf("%n%-50s%10s%n", "Logger Name", "Log Level"); for (Map.Entry entry : probe.getLoggingLevels().entrySet()) - System.out.printf("%-50s%10s%n", entry.getKey(), entry.getValue()); + probe.output().out.printf("%-50s%10s%n", entry.getKey(), entry.getValue()); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java b/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java index 2c5d46b8da..361909a7ca 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java @@ -44,7 +44,7 @@ public class GetSSTables extends NodeToolCmd List sstables = probe.getSSTables(ks, cf, key); for (String sstable : sstables) { - System.out.println(sstable); + probe.output().out.println(sstable); } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java b/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java index 437eb5430e..149889d05d 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java @@ -28,6 +28,6 @@ public class GetStreamThroughput extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println("Current stream throughput: " + probe.getStreamThroughput() + " Mb/s"); + probe.output().out.println("Current stream throughput: " + probe.getStreamThroughput() + " Mb/s"); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetTraceProbability.java b/src/java/org/apache/cassandra/tools/nodetool/GetTraceProbability.java index 394079040d..7222da6c55 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GetTraceProbability.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GetTraceProbability.java @@ -28,6 +28,6 @@ public class GetTraceProbability extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println("Current trace probability: " + probe.getTraceProbability()); + probe.output().out.println("Current trace probability: " + probe.getTraceProbability()); } } diff --git a/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java b/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java index 2acfcf1e4a..cdc2cd81c5 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java +++ b/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java @@ -28,6 +28,6 @@ public class GossipInfo extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println(probe.getGossipInfo()); + probe.output().out.println(probe.getGossipInfo()); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/Info.java b/src/java/org/apache/cassandra/tools/nodetool/Info.java index 0d9bd7330e..c2e0ff9fd2 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Info.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Info.java @@ -20,6 +20,7 @@ package org.apache.cassandra.tools.nodetool; import io.airlift.command.Command; import io.airlift.command.Option; +import java.io.PrintStream; import java.lang.management.MemoryUsage; import java.util.Iterator; import java.util.List; @@ -45,28 +46,30 @@ public class Info extends NodeToolCmd { boolean gossipInitialized = probe.isInitialized(); - System.out.printf("%-23s: %s%n", "ID", probe.getLocalHostId()); - System.out.printf("%-23s: %s%n", "Gossip active", gossipInitialized); - System.out.printf("%-23s: %s%n", "Thrift active", probe.isThriftServerRunning()); - System.out.printf("%-23s: %s%n", "Native Transport active", probe.isNativeTransportRunning()); - System.out.printf("%-23s: %s%n", "Load", probe.getLoadString()); + PrintStream out = probe.output().out; + out.printf("%-23s: %s%n", "ID", probe.getLocalHostId()); + out.printf("%-23s: %s%n", "Gossip active", gossipInitialized); + out.printf("%-23s: %s%n", "Thrift active", probe.isThriftServerRunning()); + out.printf("%-23s: %s%n", "Native Transport active", probe.isNativeTransportRunning()); + out.printf("%-23s: %s%n", "Load", probe.getLoadString()); + if (gossipInitialized) - System.out.printf("%-23s: %s%n", "Generation No", probe.getCurrentGenerationNumber()); + out.printf("%-23s: %s%n", "Generation No", probe.getCurrentGenerationNumber()); else - System.out.printf("%-23s: %s%n", "Generation No", 0); + out.printf("%-23s: %s%n", "Generation No", 0); // Uptime long secondsUp = probe.getUptime() / 1000; - System.out.printf("%-23s: %d%n", "Uptime (seconds)", secondsUp); + out.printf("%-23s: %d%n", "Uptime (seconds)", secondsUp); // Memory usage MemoryUsage heapUsage = probe.getHeapMemoryUsage(); double memUsed = (double) heapUsage.getUsed() / (1024 * 1024); double memMax = (double) heapUsage.getMax() / (1024 * 1024); - System.out.printf("%-23s: %.2f / %.2f%n", "Heap Memory (MB)", memUsed, memMax); + out.printf("%-23s: %.2f / %.2f%n", "Heap Memory (MB)", memUsed, memMax); try { - System.out.printf("%-23s: %.2f%n", "Off Heap Memory (MB)", getOffHeapMemoryUsed(probe)); + out.printf("%-23s: %.2f%n", "Off Heap Memory (MB)", getOffHeapMemoryUsed(probe)); } catch (RuntimeException e) { @@ -76,16 +79,16 @@ public class Info extends NodeToolCmd } // Data Center/Rack - System.out.printf("%-23s: %s%n", "Data Center", probe.getDataCenter()); - System.out.printf("%-23s: %s%n", "Rack", probe.getRack()); + out.printf("%-23s: %s%n", "Data Center", probe.getDataCenter()); + out.printf("%-23s: %s%n", "Rack", probe.getRack()); // Exceptions - System.out.printf("%-23s: %s%n", "Exceptions", probe.getStorageMetric("Exceptions")); + out.printf("%-23s: %s%n", "Exceptions", probe.getStorageMetric("Exceptions")); CacheServiceMBean cacheService = probe.getCacheServiceMBean(); // Key Cache: Hits, Requests, RecentHitRate, SavePeriodInSeconds - System.out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n", + out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n", "Key Cache", probe.getCacheMetric("KeyCache", "Entries"), FileUtils.stringifyFileSize((long) probe.getCacheMetric("KeyCache", "Size")), @@ -96,7 +99,7 @@ public class Info extends NodeToolCmd cacheService.getKeyCacheSavePeriodInSeconds()); // Row Cache: Hits, Requests, RecentHitRate, SavePeriodInSeconds - System.out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n", + out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n", "Row Cache", probe.getCacheMetric("RowCache", "Entries"), FileUtils.stringifyFileSize((long) probe.getCacheMetric("RowCache", "Size")), @@ -107,7 +110,7 @@ public class Info extends NodeToolCmd cacheService.getRowCacheSavePeriodInSeconds()); // Counter Cache: Hits, Requests, RecentHitRate, SavePeriodInSeconds - System.out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n", + out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n", "Counter Cache", probe.getCacheMetric("CounterCache", "Entries"), FileUtils.stringifyFileSize((long) probe.getCacheMetric("CounterCache", "Size")), @@ -124,14 +127,14 @@ public class Info extends NodeToolCmd List tokens = probe.getTokens(); if (tokens.size() == 1 || this.tokens) for (String token : tokens) - System.out.printf("%-23s: %s%n", "Token", token); + out.printf("%-23s: %s%n", "Token", token); else - System.out.printf("%-23s: (invoke with -T/--tokens to see all %d tokens)%n", "Token", + out.printf("%-23s: (invoke with -T/--tokens to see all %d tokens)%n", "Token", tokens.size()); } else { - System.out.printf("%-23s: (node is not joined to the cluster)%n", "Token"); + out.printf("%-23s: (node is not joined to the cluster)%n", "Token"); } } diff --git a/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java b/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java index 344d9dc5e0..18d8053c7c 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java +++ b/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java @@ -19,6 +19,7 @@ package org.apache.cassandra.tools.nodetool; import io.airlift.command.Command; +import java.io.PrintStream; import java.util.List; import java.util.Map; import java.util.Set; @@ -35,14 +36,15 @@ public class ListSnapshots extends NodeToolCmd @Override public void execute(NodeProbe probe) { + PrintStream out = probe.output().out; try { - System.out.println("Snapshot Details: "); + out.println("Snapshot Details: "); final Map snapshotDetails = probe.getSnapshotDetails(); if (snapshotDetails.isEmpty()) { - System.out.println("There are no snapshots"); + out.println("There are no snapshots"); return; } @@ -50,7 +52,7 @@ public class ListSnapshots extends NodeToolCmd final String format = "%-40s %-29s %-29s %-19s %-19s%n"; // display column names only once final List indexNames = snapshotDetails.entrySet().iterator().next().getValue().getTabularType().getIndexNames(); - System.out.printf(format, (Object[]) indexNames.toArray(new String[indexNames.size()])); + out.printf(format, (Object[]) indexNames.toArray(new String[indexNames.size()])); for (final Map.Entry snapshotDetail : snapshotDetails.entrySet()) { @@ -58,11 +60,11 @@ public class ListSnapshots extends NodeToolCmd for (Object eachValue : values) { final List value = (List) eachValue; - System.out.printf(format, value.toArray(new Object[value.size()])); + out.printf(format, value.toArray(new Object[value.size()])); } } - System.out.println("\nTotal TrueDiskSpaceUsed: " + FileUtils.stringifyFileSize(trueSnapshotsSize) + "\n"); + out.println("\nTotal TrueDiskSpaceUsed: " + FileUtils.stringifyFileSize(trueSnapshotsSize) + "\n"); } catch (Exception e) { diff --git a/src/java/org/apache/cassandra/tools/nodetool/NetStats.java b/src/java/org/apache/cassandra/tools/nodetool/NetStats.java index 025d754780..61db036e15 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/NetStats.java +++ b/src/java/org/apache/cassandra/tools/nodetool/NetStats.java @@ -20,6 +20,7 @@ package org.apache.cassandra.tools.nodetool; import io.airlift.command.Command; import io.airlift.command.Option; +import java.io.PrintStream; import java.util.Set; import org.apache.cassandra.io.util.FileUtils; @@ -41,42 +42,43 @@ public class NetStats extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.printf("Mode: %s%n", probe.getOperationMode()); + PrintStream out = probe.output().out; + out.printf("Mode: %s%n", probe.getOperationMode()); Set statuses = probe.getStreamStatus(); if (statuses.isEmpty()) - System.out.println("Not sending any streams."); + out.println("Not sending any streams."); for (StreamState status : statuses) { - System.out.printf("%s %s%n", status.description, status.planId.toString()); + out.printf("%s %s%n", status.description, status.planId.toString()); for (SessionInfo info : status.sessions) { - System.out.printf(" %s", info.peer.toString()); + out.printf(" %s", info.peer.toString()); // print private IP when it is used if (!info.peer.equals(info.connecting)) { - System.out.printf(" (using %s)", info.connecting.toString()); + out.printf(" (using %s)", info.connecting.toString()); } - System.out.printf("%n"); + out.printf("%n"); if (!info.receivingSummaries.isEmpty()) { if (humanReadable) - System.out.printf(" Receiving %d files, %s total. Already received %d files, %s total%n", info.getTotalFilesToReceive(), FileUtils.stringifyFileSize(info.getTotalSizeToReceive()), info.getTotalFilesReceived(), FileUtils.stringifyFileSize(info.getTotalSizeReceived())); + out.printf(" Receiving %d files, %s total. Already received %d files, %s total%n", info.getTotalFilesToReceive(), FileUtils.stringifyFileSize(info.getTotalSizeToReceive()), info.getTotalFilesReceived(), FileUtils.stringifyFileSize(info.getTotalSizeReceived())); else - System.out.printf(" Receiving %d files, %d bytes total. Already received %d files, %d bytes total%n", info.getTotalFilesToReceive(), info.getTotalSizeToReceive(), info.getTotalFilesReceived(), info.getTotalSizeReceived()); + out.printf(" Receiving %d files, %d bytes total. Already received %d files, %d bytes total%n", info.getTotalFilesToReceive(), info.getTotalSizeToReceive(), info.getTotalFilesReceived(), info.getTotalSizeReceived()); for (ProgressInfo progress : info.getReceivingFiles()) { - System.out.printf(" %s%n", progress.toString()); + out.printf(" %s%n", progress.toString()); } } if (!info.sendingSummaries.isEmpty()) { if (humanReadable) - System.out.printf(" Sending %d files, %s total. Already sent %d files, %s total%n", info.getTotalFilesToSend(), FileUtils.stringifyFileSize(info.getTotalSizeToSend()), info.getTotalFilesSent(), FileUtils.stringifyFileSize(info.getTotalSizeSent())); + out.printf(" Sending %d files, %s total. Already sent %d files, %s total%n", info.getTotalFilesToSend(), FileUtils.stringifyFileSize(info.getTotalSizeToSend()), info.getTotalFilesSent(), FileUtils.stringifyFileSize(info.getTotalSizeSent())); else - System.out.printf(" Sending %d files, %d bytes total. Already sent %d files, %d bytes total%n", info.getTotalFilesToSend(), info.getTotalSizeToSend(), info.getTotalFilesSent(), info.getTotalSizeSent()); + out.printf(" Sending %d files, %d bytes total. Already sent %d files, %d bytes total%n", info.getTotalFilesToSend(), info.getTotalSizeToSend(), info.getTotalFilesSent(), info.getTotalSizeSent()); for (ProgressInfo progress : info.getSendingFiles()) { - System.out.printf(" %s%n", progress.toString()); + out.printf(" %s%n", progress.toString()); } } } @@ -84,14 +86,14 @@ public class NetStats extends NodeToolCmd if (!probe.isStarting()) { - System.out.printf("Read Repair Statistics:%nAttempted: %d%nMismatch (Blocking): %d%nMismatch (Background): %d%n", probe.getReadRepairAttempted(), probe.getReadRepairRepairedBlocking(), probe.getReadRepairRepairedBackground()); + out.printf("Read Repair Statistics:%nAttempted: %d%nMismatch (Blocking): %d%nMismatch (Background): %d%n", probe.getReadRepairAttempted(), probe.getReadRepairRepairedBlocking(), probe.getReadRepairRepairedBackground()); MessagingServiceMBean ms = probe.getMessagingServiceProxy(); - System.out.printf("%-25s", "Pool Name"); - System.out.printf("%10s", "Active"); - System.out.printf("%10s", "Pending"); - System.out.printf("%15s", "Completed"); - System.out.printf("%10s%n", "Dropped"); + out.printf("%-25s", "Pool Name"); + out.printf("%10s", "Active"); + out.printf("%10s", "Pending"); + out.printf("%15s", "Completed"); + out.printf("%10s%n", "Dropped"); int pending; long completed; @@ -106,7 +108,7 @@ public class NetStats extends NodeToolCmd dropped = 0; for (long n : ms.getLargeMessageDroppedTasks().values()) dropped += n; - System.out.printf("%-25s%10s%10s%15s%10s%n", "Large messages", "n/a", pending, completed, dropped); + out.printf("%-25s%10s%10s%15s%10s%n", "Large messages", "n/a", pending, completed, dropped); pending = 0; for (int n : ms.getSmallMessagePendingTasks().values()) @@ -117,7 +119,7 @@ public class NetStats extends NodeToolCmd dropped = 0; for (long n : ms.getSmallMessageDroppedTasks().values()) dropped += n; - System.out.printf("%-25s%10s%10s%15s%10s%n", "Small messages", "n/a", pending, completed, dropped); + out.printf("%-25s%10s%10s%15s%10s%n", "Small messages", "n/a", pending, completed, dropped); pending = 0; for (int n : ms.getGossipMessagePendingTasks().values()) @@ -128,7 +130,7 @@ public class NetStats extends NodeToolCmd dropped = 0; for (long n : ms.getGossipMessageDroppedTasks().values()) dropped += n; - System.out.printf("%-25s%10s%10s%15s%10s%n", "Gossip messages", "n/a", pending, completed, dropped); + out.printf("%-25s%10s%10s%15s%10s%n", "Gossip messages", "n/a", pending, completed, dropped); } } } diff --git a/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java b/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java index 2a2851da9c..1a3fc4216a 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java +++ b/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java @@ -17,6 +17,8 @@ */ package org.apache.cassandra.tools.nodetool; +import java.io.PrintStream; + import static java.lang.String.format; import io.airlift.command.Command; @@ -33,20 +35,21 @@ public class ProxyHistograms extends NodeToolCmd double[] readLatency = probe.metricPercentilesAsArray(probe.getProxyMetric("Read")); double[] writeLatency = probe.metricPercentilesAsArray(probe.getProxyMetric("Write")); double[] rangeLatency = probe.metricPercentilesAsArray(probe.getProxyMetric("RangeSlice")); + PrintStream out = probe.output().out; - System.out.println("proxy histograms"); - System.out.println(format("%-10s%18s%18s%18s", + out.println("proxy histograms"); + out.println(format("%-10s%18s%18s%18s", "Percentile", "Read Latency", "Write Latency", "Range Latency")); - System.out.println(format("%-10s%18s%18s%18s", + out.println(format("%-10s%18s%18s%18s", "", "(micros)", "(micros)", "(micros)")); for (int i = 0; i < percentiles.length; i++) { - System.out.println(format("%-10s%18.2f%18.2f%18.2f", + out.println(format("%-10s%18.2f%18.2f%18.2f", percentiles[i], readLatency[i], writeLatency[i], rangeLatency[i])); } - System.out.println(); + out.println(); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java b/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java index e079a4b81c..02a91b598a 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java +++ b/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java @@ -30,11 +30,11 @@ public class RangeKeySample extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println("RangeKeySample: "); + probe.output().out.println("RangeKeySample: "); List tokenStrings = probe.sampleKeyRange(); for (String tokenString : tokenStrings) { - System.out.println("\t" + tokenString); + probe.output().out.println("\t" + tokenString); } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/Refresh.java b/src/java/org/apache/cassandra/tools/nodetool/Refresh.java index 153255c15d..d2fea93721 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Refresh.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Refresh.java @@ -39,4 +39,4 @@ public class Refresh extends NodeToolCmd checkArgument(args.size() == 2, "refresh requires ks and cf args"); probe.loadNewSSTables(args.get(0), args.get(1)); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java b/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java index 848049ee8b..b257019cc1 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java +++ b/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java @@ -36,10 +36,10 @@ public class RemoveNode extends NodeToolCmd switch (removeOperation) { case "status": - System.out.println("RemovalStatus: " + probe.getRemovalStatus()); + probe.output().out.println("RemovalStatus: " + probe.getRemovalStatus()); break; case "force": - System.out.println("RemovalStatus: " + probe.getRemovalStatus()); + probe.output().out.println("RemovalStatus: " + probe.getRemovalStatus()); probe.forceRemoveCompletion(); break; default: @@ -47,4 +47,4 @@ public class RemoveNode extends NodeToolCmd break; } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/Repair.java b/src/java/org/apache/cassandra/tools/nodetool/Repair.java index 928cae8eec..df1cb94334 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Repair.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Repair.java @@ -128,7 +128,7 @@ public class Repair extends NodeToolCmd options.put(RepairOption.HOSTS_KEY, StringUtils.join(specificHosts, ",")); try { - probe.repairAsync(System.out, keyspace, options); + probe.repairAsync(probe.output().out, keyspace, options); } catch (Exception e) { throw new RuntimeException("Error occurred during repair", e); diff --git a/src/java/org/apache/cassandra/tools/nodetool/Ring.java b/src/java/org/apache/cassandra/tools/nodetool/Ring.java index 03d9449d58..dca87797c6 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Ring.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Ring.java @@ -22,6 +22,7 @@ import io.airlift.command.Arguments; import io.airlift.command.Command; import io.airlift.command.Option; +import java.io.PrintStream; import java.net.InetAddress; import java.net.UnknownHostException; import java.text.DecimalFormat; @@ -51,6 +52,7 @@ public class Ring extends NodeToolCmd @Override public void execute(NodeProbe probe) { + PrintStream out = probe.output().out; Map tokensToEndpoints = probe.getTokenToEndpointMap(); LinkedHashMultimap endpointsToTokens = LinkedHashMultimap.create(); boolean haveVnodes = false; @@ -88,22 +90,22 @@ public class Ring extends NodeToolCmd } catch (IllegalArgumentException ex) { - System.out.printf("%nError: " + ex.getMessage() + "%n"); + out.printf("%nError: " + ex.getMessage() + "%n"); return; } - System.out.println(); + out.println(); for (Entry entry : NodeTool.getOwnershipByDc(probe, resolveIp, tokensToEndpoints, ownerships).entrySet()) printDc(probe, format, entry.getKey(), endpointsToTokens, entry.getValue(),showEffectiveOwnership); if (haveVnodes) { - System.out.println(" Warning: \"nodetool ring\" is used to output all the tokens of a node."); - System.out.println(" To view status related info of a node use \"nodetool status\" instead.\n"); + out.println(" Warning: \"nodetool ring\" is used to output all the tokens of a node."); + out.println(" To view status related info of a node use \"nodetool status\" instead.\n"); } - System.out.printf("%n " + errors.toString()); + out.printf("%n " + errors.toString()); } private void printDc(NodeProbe probe, String format, @@ -111,6 +113,7 @@ public class Ring extends NodeToolCmd LinkedHashMultimap endpointsToTokens, SetHostStat hoststats,boolean showEffectiveOwnership) { + PrintStream out = probe.output().out; Collection liveNodes = probe.getLiveNodes(); Collection deadNodes = probe.getUnreachableNodes(); Collection joiningNodes = probe.getJoiningNodes(); @@ -118,8 +121,8 @@ public class Ring extends NodeToolCmd Collection movingNodes = probe.getMovingNodes(); Map loadMap = probe.getLoadMap(); - System.out.println("Datacenter: " + dc); - System.out.println("=========="); + out.println("Datacenter: " + dc); + out.println("=========="); // get the total amount of replicas for this dc and the last token in this dc's ring List tokens = new ArrayList<>(); @@ -131,12 +134,12 @@ public class Ring extends NodeToolCmd lastToken = tokens.get(tokens.size() - 1); } - System.out.printf(format, "Address", "Rack", "Status", "State", "Load", "Owns", "Token"); + out.printf(format, "Address", "Rack", "Status", "State", "Load", "Owns", "Token"); if (hoststats.size() > 1) - System.out.printf(format, "", "", "", "", "", "", lastToken); + out.printf(format, "", "", "", "", "", "", lastToken); else - System.out.println(); + out.println(); for (HostStat stat : hoststats) { @@ -170,8 +173,8 @@ public class Ring extends NodeToolCmd ? loadMap.get(endpoint) : "?"; String owns = stat.owns != null && showEffectiveOwnership? new DecimalFormat("##0.00%").format(stat.owns) : "?"; - System.out.printf(format, stat.ipOrDns(), rack, status, state, load, owns, stat.token); + out.printf(format, stat.ipOrDns(), rack, status, state, load, owns, stat.token); } - System.out.println(); + out.println(); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/Scrub.java b/src/java/org/apache/cassandra/tools/nodetool/Scrub.java index 263291d964..2b73756305 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Scrub.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Scrub.java @@ -69,9 +69,8 @@ public class Scrub extends NodeToolCmd { try { - probe.scrub(System.out, disableSnapshot, skipCorrupted, !noValidation, reinsertOverflowedTTL, jobs, keyspace, tableNames); - } - catch (IllegalArgumentException e) + probe.scrub(probe.output().out, disableSnapshot, skipCorrupted, !noValidation, reinsertOverflowedTTL, jobs, keyspace, tableNames); + } catch (IllegalArgumentException e) { throw e; } diff --git a/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java b/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java index 4f549e5a96..c2dd097fd3 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java @@ -24,6 +24,7 @@ import io.airlift.command.Command; import io.airlift.command.Option; import java.io.IOException; +import java.io.PrintStream; import java.util.ArrayList; import java.util.List; @@ -48,6 +49,7 @@ public class Snapshot extends NodeToolCmd @Override public void execute(NodeProbe probe) { + PrintStream out = probe.output().out; try { StringBuilder sb = new StringBuilder(); @@ -67,9 +69,9 @@ public class Snapshot extends NodeToolCmd } if (!snapshotName.isEmpty()) sb.append(" with snapshot name [").append(snapshotName).append("]"); - System.out.println(sb.toString()); + out.println(sb.toString()); probe.takeMultipleTableSnapshot(snapshotName, ktList.split(",")); - System.out.println("Snapshot directory: " + snapshotName); + out.println("Snapshot directory: " + snapshotName); } else { @@ -81,10 +83,10 @@ public class Snapshot extends NodeToolCmd if (!snapshotName.isEmpty()) sb.append(" with snapshot name [").append(snapshotName).append("]"); - System.out.println(sb.toString()); + out.println(sb.toString()); probe.takeSnapshot(snapshotName, table, toArray(keyspaces, String.class)); - System.out.println("Snapshot directory: " + snapshotName); + out.println("Snapshot directory: " + snapshotName); } } catch (IOException e) @@ -92,4 +94,4 @@ public class Snapshot extends NodeToolCmd throw new RuntimeException("Error during taking a snapshot", e); } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/Status.java b/src/java/org/apache/cassandra/tools/nodetool/Status.java index 091040b5a6..299608edcc 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Status.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Status.java @@ -21,6 +21,7 @@ import io.airlift.command.Arguments; import io.airlift.command.Command; import io.airlift.command.Option; +import java.io.PrintStream; import java.net.InetAddress; import java.net.UnknownHostException; import java.text.DecimalFormat; @@ -56,6 +57,7 @@ public class Status extends NodeToolCmd @Override public void execute(NodeProbe probe) { + PrintStream out = probe.output().out; joiningNodes = probe.getJoiningNodes(); leavingNodes = probe.getLeavingNodes(); movingNodes = probe.getMovingNodes(); @@ -82,7 +84,7 @@ public class Status extends NodeToolCmd } catch (IllegalArgumentException ex) { - System.out.printf("%nError: " + ex.getMessage() + "%n"); + out.printf("%nError: " + ex.getMessage() + "%n"); System.exit(1); } @@ -98,15 +100,15 @@ public class Status extends NodeToolCmd for (Map.Entry dc : dcs.entrySet()) { String dcHeader = String.format("Datacenter: %s%n", dc.getKey()); - System.out.print(dcHeader); - for (int i = 0; i < (dcHeader.length() - 1); i++) System.out.print('='); - System.out.println(); + out.print(dcHeader); + for (int i = 0; i < (dcHeader.length() - 1); i++) out.print('='); + out.println(); // Legend - System.out.println("Status=Up/Down"); - System.out.println("|/ State=Normal/Leaving/Joining/Moving"); + out.println("Status=Up/Down"); + out.println("|/ State=Normal/Leaving/Joining/Moving"); - printNodesHeader(hasEffectiveOwns, isTokenPerNode, maxAddressLength); + printNodesHeader(hasEffectiveOwns, isTokenPerNode, maxAddressLength, out); ArrayListMultimap hostToTokens = ArrayListMultimap.create(); for (HostStat stat : dc.getValue()) @@ -116,11 +118,11 @@ public class Status extends NodeToolCmd { Float owns = ownerships.get(endpoint); List tokens = hostToTokens.get(endpoint); - printNode(endpoint.getHostAddress(), owns, tokens, hasEffectiveOwns, isTokenPerNode, maxAddressLength); + printNode(endpoint.getHostAddress(), owns, tokens, hasEffectiveOwns, isTokenPerNode, maxAddressLength, out); } } - System.out.printf("%n" + errors); + out.printf("%n" + errors); } @@ -137,19 +139,19 @@ public class Status extends NodeToolCmd return maxAddressLength; } - private void printNodesHeader(boolean hasEffectiveOwns, boolean isTokenPerNode, int maxAddressLength) + private void printNodesHeader(boolean hasEffectiveOwns, boolean isTokenPerNode, int maxAddressLength, PrintStream out) { String fmt = getFormat(hasEffectiveOwns, isTokenPerNode, maxAddressLength); String owns = hasEffectiveOwns ? "Owns (effective)" : "Owns"; if (isTokenPerNode) - System.out.printf(fmt, "-", "-", "Address", "Load", owns, "Host ID", "Token", "Rack"); + out.printf(fmt, "-", "-", "Address", "Load", owns, "Host ID", "Token", "Rack"); else - System.out.printf(fmt, "-", "-", "Address", "Load", "Tokens", owns, "Host ID", "Rack"); + out.printf(fmt, "-", "-", "Address", "Load", "Tokens", owns, "Host ID", "Rack"); } private void printNode(String endpoint, Float owns, List tokens, boolean hasEffectiveOwns, - boolean isTokenPerNode, int maxAddressLength) + boolean isTokenPerNode, int maxAddressLength, PrintStream out) { String status, state, load, strOwns, hostID, rack, fmt; fmt = getFormat(hasEffectiveOwns, isTokenPerNode, maxAddressLength); @@ -175,9 +177,9 @@ public class Status extends NodeToolCmd String endpointDns = tokens.get(0).ipOrDns(); if (isTokenPerNode) - System.out.printf(fmt, status, state, endpointDns, load, strOwns, hostID, tokens.get(0).token, rack); + out.printf(fmt, status, state, endpointDns, load, strOwns, hostID, tokens.get(0).token, rack); else - System.out.printf(fmt, status, state, endpointDns, load, tokens.size(), strOwns, hostID, rack); + out.printf(fmt, status, state, endpointDns, load, tokens.size(), strOwns, hostID, rack); } private String getFormat(boolean hasEffectiveOwns, boolean isTokenPerNode, int maxAddressLength) @@ -205,4 +207,4 @@ public class Status extends NodeToolCmd return format; } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusBackup.java b/src/java/org/apache/cassandra/tools/nodetool/StatusBackup.java index 49a6750c62..0ab3c3ff25 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/StatusBackup.java +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusBackup.java @@ -28,9 +28,9 @@ public class StatusBackup extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println( + probe.output().out.println( probe.isIncrementalBackupsEnabled() ? "running" : "not running"); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusBinary.java b/src/java/org/apache/cassandra/tools/nodetool/StatusBinary.java index d4fae14fa2..f373a7472a 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/StatusBinary.java +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusBinary.java @@ -28,9 +28,9 @@ public class StatusBinary extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println( + probe.output().out.println( probe.isNativeTransportRunning() ? "running" : "not running"); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusGossip.java b/src/java/org/apache/cassandra/tools/nodetool/StatusGossip.java index e40df8d6d1..9cddaa9d1d 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/StatusGossip.java +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusGossip.java @@ -28,9 +28,9 @@ public class StatusGossip extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println( + probe.output().out.println( probe.isGossipRunning() ? "running" : "not running"); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusHandoff.java b/src/java/org/apache/cassandra/tools/nodetool/StatusHandoff.java index 65f6729758..8dca732452 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/StatusHandoff.java +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusHandoff.java @@ -17,6 +17,8 @@ */ package org.apache.cassandra.tools.nodetool; +import java.io.PrintStream; + import io.airlift.command.Command; import org.apache.cassandra.tools.NodeProbe; @@ -28,12 +30,13 @@ public class StatusHandoff extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println(String.format("Hinted handoff is %s", + PrintStream out = probe.output().out; + out.println(String.format("Hinted handoff is %s", probe.isHandoffEnabled() ? "running" : "not running")); for (String dc : probe.getHintedHandoffDisabledDCs()) - System.out.println(String.format("Data center %s is disabled", dc)); + out.println(String.format("Data center %s is disabled", dc)); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusThrift.java b/src/java/org/apache/cassandra/tools/nodetool/StatusThrift.java index 0cb17d21b5..272be1a02e 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/StatusThrift.java +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusThrift.java @@ -28,9 +28,9 @@ public class StatusThrift extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println( + probe.output().out.println( probe.isThriftServerRunning() ? "running" : "not running"); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/TableHistograms.java b/src/java/org/apache/cassandra/tools/nodetool/TableHistograms.java index be3f799cbc..04a0c97ffc 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/TableHistograms.java +++ b/src/java/org/apache/cassandra/tools/nodetool/TableHistograms.java @@ -22,6 +22,7 @@ import static java.lang.String.format; import io.airlift.command.Arguments; import io.airlift.command.Command; +import java.io.PrintStream; import java.util.ArrayList; import java.util.List; @@ -42,6 +43,9 @@ public class TableHistograms extends NodeToolCmd { checkArgument(args.size() == 2, "tablehistograms requires keyspace and table name arguments"); + PrintStream out = probe.output().out; + PrintStream err = probe.output().err; + String keyspace = args.get(0); String table = args.get(1); @@ -56,7 +60,7 @@ public class TableHistograms extends NodeToolCmd if (ArrayUtils.isEmpty(estimatedPartitionSize) || ArrayUtils.isEmpty(estimatedColumnCount)) { - System.err.println("No SSTables exists, unable to calculate 'Partition Size' and 'Cell Count' percentiles"); + err.println("No SSTables exists, unable to calculate 'Partition Size' and 'Cell Count' percentiles"); for (int i = 0; i < 7; i++) { @@ -71,7 +75,7 @@ public class TableHistograms extends NodeToolCmd if (partitionSizeHist.isOverflowed()) { - System.err.println(String.format("Row sizes are larger than %s, unable to calculate percentiles", partitionSizeHist.getLargestBucketOffset())); + err.println(String.format("Row sizes are larger than %s, unable to calculate percentiles", partitionSizeHist.getLargestBucketOffset())); for (int i = 0; i < offsetPercentiles.length; i++) estimatedRowSizePercentiles[i] = Double.NaN; } @@ -83,7 +87,7 @@ public class TableHistograms extends NodeToolCmd if (columnCountHist.isOverflowed()) { - System.err.println(String.format("Column counts are larger than %s, unable to calculate percentiles", columnCountHist.getLargestBucketOffset())); + err.println(String.format("Column counts are larger than %s, unable to calculate percentiles", columnCountHist.getLargestBucketOffset())); for (int i = 0; i < estimatedColumnCountPercentiles.length; i++) estimatedColumnCountPercentiles[i] = Double.NaN; } @@ -106,15 +110,15 @@ public class TableHistograms extends NodeToolCmd double[] writeLatency = probe.metricPercentilesAsArray((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspace, table, "WriteLatency")); double[] sstablesPerRead = probe.metricPercentilesAsArray((CassandraMetricsRegistry.JmxHistogramMBean) probe.getColumnFamilyMetric(keyspace, table, "SSTablesPerReadHistogram")); - System.out.println(format("%s/%s histograms", keyspace, table)); - System.out.println(format("%-10s%10s%18s%18s%18s%18s", + out.println(format("%s/%s histograms", keyspace, table)); + out.println(format("%-10s%10s%18s%18s%18s%18s", "Percentile", "SSTables", "Write Latency", "Read Latency", "Partition Size", "Cell Count")); - System.out.println(format("%-10s%10s%18s%18s%18s%18s", + out.println(format("%-10s%10s%18s%18s%18s%18s", "", "", "(micros)", "(micros)", "(bytes)", "")); for (int i = 0; i < percentiles.length; i++) { - System.out.println(format("%-10s%10.2f%18.2f%18.2f%18.0f%18.0f", + out.println(format("%-10s%10.2f%18.2f%18.2f%18.0f%18.0f", percentiles[i], sstablesPerRead[i], writeLatency[i], @@ -122,6 +126,6 @@ public class TableHistograms extends NodeToolCmd estimatedRowSizePercentiles[i], estimatedColumnCountPercentiles[i])); } - System.out.println(); + out.println(); } } diff --git a/src/java/org/apache/cassandra/tools/nodetool/TableStats.java b/src/java/org/apache/cassandra/tools/nodetool/TableStats.java index c7d0d301a6..ea46d6e2aa 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/TableStats.java +++ b/src/java/org/apache/cassandra/tools/nodetool/TableStats.java @@ -21,6 +21,7 @@ import io.airlift.command.Arguments; import io.airlift.command.Command; import io.airlift.command.Option; +import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -52,6 +53,7 @@ public class TableStats extends NodeToolCmd @Override public void execute(NodeProbe probe) { + PrintStream out = probe.output().out; TableStats.OptionFilter filter = new OptionFilter(ignore, tableNames); Map> tableStoreMap = new HashMap<>(); @@ -90,7 +92,7 @@ public class TableStats extends NodeToolCmd double keyspaceTotalReadTime = 0.0f; double keyspaceTotalWriteTime = 0.0f; - System.out.println("Keyspace: " + keyspaceName); + out.println("Keyspace: " + keyspaceName); for (ColumnFamilyStoreMBean table : columnFamilies) { String tableName = table.getColumnFamilyName(); @@ -117,42 +119,42 @@ public class TableStats extends NodeToolCmd ? keyspaceTotalWriteTime / keyspaceWriteCount / 1000 : Double.NaN; - System.out.println("\tRead Count: " + keyspaceReadCount); - System.out.println("\tRead Latency: " + String.format("%s", keyspaceReadLatency) + " ms."); - System.out.println("\tWrite Count: " + keyspaceWriteCount); - System.out.println("\tWrite Latency: " + String.format("%s", keyspaceWriteLatency) + " ms."); - System.out.println("\tPending Flushes: " + keyspacePendingFlushes); + out.println("\tRead Count: " + keyspaceReadCount); + out.println("\tRead Latency: " + String.format("%s", keyspaceReadLatency) + " ms."); + out.println("\tWrite Count: " + keyspaceWriteCount); + out.println("\tWrite Latency: " + String.format("%s", keyspaceWriteLatency) + " ms."); + out.println("\tPending Flushes: " + keyspacePendingFlushes); // print out column family statistics for this keyspace for (ColumnFamilyStoreMBean table : columnFamilies) { String tableName = table.getColumnFamilyName(); if (tableName.contains(".")) - System.out.println("\t\tTable (index): " + tableName); + out.println("\t\tTable (index): " + tableName); else - System.out.println("\t\tTable: " + tableName); + out.println("\t\tTable: " + tableName); - System.out.println("\t\tSSTable count: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "LiveSSTableCount")); + out.println("\t\tSSTable count: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "LiveSSTableCount")); int[] leveledSStables = table.getSSTableCountPerLevel(); if (leveledSStables != null) { - System.out.print("\t\tSSTables in each level: ["); + out.print("\t\tSSTables in each level: ["); for (int level = 0; level < leveledSStables.length; level++) { int count = leveledSStables[level]; - System.out.print(count); + out.print(count); long maxCount = 4L; // for L0 if (level > 0) maxCount = (long) Math.pow(10, level); // show max threshold for level when exceeded if (count > maxCount) - System.out.print("/" + maxCount); + out.print("/" + maxCount); if (level < leveledSStables.length - 1) - System.out.print(", "); + out.print(", "); else - System.out.println("]"); + out.println("]"); } } @@ -179,57 +181,57 @@ public class TableStats extends NodeToolCmd throw e; } - System.out.println("\t\tSpace used (live): " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "LiveDiskSpaceUsed"), humanReadable)); - System.out.println("\t\tSpace used (total): " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "TotalDiskSpaceUsed"), humanReadable)); - System.out.println("\t\tSpace used by snapshots (total): " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "SnapshotsSize"), humanReadable)); + out.println("\t\tSpace used (live): " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "LiveDiskSpaceUsed"), humanReadable)); + out.println("\t\tSpace used (total): " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "TotalDiskSpaceUsed"), humanReadable)); + out.println("\t\tSpace used by snapshots (total): " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "SnapshotsSize"), humanReadable)); if (offHeapSize != null) - System.out.println("\t\tOff heap memory used (total): " + format(offHeapSize, humanReadable)); - System.out.println("\t\tSSTable Compression Ratio: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "CompressionRatio")); + out.println("\t\tOff heap memory used (total): " + format(offHeapSize, humanReadable)); + out.println("\t\tSSTable Compression Ratio: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "CompressionRatio")); Object estimatedPartitionCount = probe.getColumnFamilyMetric(keyspaceName, tableName, "EstimatedPartitionCount"); if (Long.valueOf(-1L).equals(estimatedPartitionCount)) { estimatedPartitionCount = 0L; } - System.out.println("\t\tNumber of partitions (estimate): " + estimatedPartitionCount); + out.println("\t\tNumber of partitions (estimate): " + estimatedPartitionCount); - System.out.println("\t\tMemtable cell count: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "MemtableColumnsCount")); - System.out.println("\t\tMemtable data size: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MemtableLiveDataSize"), humanReadable)); + out.println("\t\tMemtable cell count: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "MemtableColumnsCount")); + out.println("\t\tMemtable data size: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MemtableLiveDataSize"), humanReadable)); if (memtableOffHeapSize != null) - System.out.println("\t\tMemtable off heap memory used: " + format(memtableOffHeapSize, humanReadable)); - System.out.println("\t\tMemtable switch count: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "MemtableSwitchCount")); - System.out.println("\t\tLocal read count: " + ((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspaceName, tableName, "ReadLatency")).getCount()); + out.println("\t\tMemtable off heap memory used: " + format(memtableOffHeapSize, humanReadable)); + out.println("\t\tMemtable switch count: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "MemtableSwitchCount")); + out.println("\t\tLocal read count: " + ((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspaceName, tableName, "ReadLatency")).getCount()); double localReadLatency = ((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspaceName, tableName, "ReadLatency")).getMean() / 1000; double localRLatency = localReadLatency > 0 ? localReadLatency : Double.NaN; - System.out.printf("\t\tLocal read latency: %01.3f ms%n", localRLatency); - System.out.println("\t\tLocal write count: " + ((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspaceName, tableName, "WriteLatency")).getCount()); + out.printf("\t\tLocal read latency: %01.3f ms%n", localRLatency); + out.println("\t\tLocal write count: " + ((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspaceName, tableName, "WriteLatency")).getCount()); double localWriteLatency = ((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspaceName, tableName, "WriteLatency")).getMean() / 1000; double localWLatency = localWriteLatency > 0 ? localWriteLatency : Double.NaN; - System.out.printf("\t\tLocal write latency: %01.3f ms%n", localWLatency); - System.out.println("\t\tPending flushes: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "PendingFlushes")); - System.out.println("\t\tBloom filter false positives: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "BloomFilterFalsePositives")); - System.out.printf("\t\tBloom filter false ratio: %s%n", String.format("%01.5f", probe.getColumnFamilyMetric(keyspaceName, tableName, "RecentBloomFilterFalseRatio"))); - System.out.println("\t\tBloom filter space used: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "BloomFilterDiskSpaceUsed"), humanReadable)); + out.printf("\t\tLocal write latency: %01.3f ms%n", localWLatency); + out.println("\t\tPending flushes: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "PendingFlushes")); + out.println("\t\tBloom filter false positives: " + probe.getColumnFamilyMetric(keyspaceName, tableName, "BloomFilterFalsePositives")); + out.printf("\t\tBloom filter false ratio: %s%n", String.format("%01.5f", probe.getColumnFamilyMetric(keyspaceName, tableName, "RecentBloomFilterFalseRatio"))); + out.println("\t\tBloom filter space used: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "BloomFilterDiskSpaceUsed"), humanReadable)); if (bloomFilterOffHeapSize != null) - System.out.println("\t\tBloom filter off heap memory used: " + format(bloomFilterOffHeapSize, humanReadable)); + out.println("\t\tBloom filter off heap memory used: " + format(bloomFilterOffHeapSize, humanReadable)); if (indexSummaryOffHeapSize != null) - System.out.println("\t\tIndex summary off heap memory used: " + format(indexSummaryOffHeapSize, humanReadable)); + out.println("\t\tIndex summary off heap memory used: " + format(indexSummaryOffHeapSize, humanReadable)); if (compressionMetadataOffHeapSize != null) - System.out.println("\t\tCompression metadata off heap memory used: " + format(compressionMetadataOffHeapSize, humanReadable)); + out.println("\t\tCompression metadata off heap memory used: " + format(compressionMetadataOffHeapSize, humanReadable)); - System.out.println("\t\tCompacted partition minimum bytes: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MinPartitionSize"), humanReadable)); - System.out.println("\t\tCompacted partition maximum bytes: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MaxPartitionSize"), humanReadable)); - System.out.println("\t\tCompacted partition mean bytes: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MeanPartitionSize"), humanReadable)); + out.println("\t\tCompacted partition minimum bytes: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MinPartitionSize"), humanReadable)); + out.println("\t\tCompacted partition maximum bytes: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MaxPartitionSize"), humanReadable)); + out.println("\t\tCompacted partition mean bytes: " + format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MeanPartitionSize"), humanReadable)); CassandraMetricsRegistry.JmxHistogramMBean histogram = (CassandraMetricsRegistry.JmxHistogramMBean) probe.getColumnFamilyMetric(keyspaceName, tableName, "LiveScannedHistogram"); - System.out.println("\t\tAverage live cells per slice (last five minutes): " + histogram.getMean()); - System.out.println("\t\tMaximum live cells per slice (last five minutes): " + histogram.getMax()); + out.println("\t\tAverage live cells per slice (last five minutes): " + histogram.getMean()); + out.println("\t\tMaximum live cells per slice (last five minutes): " + histogram.getMax()); histogram = (CassandraMetricsRegistry.JmxHistogramMBean) probe.getColumnFamilyMetric(keyspaceName, tableName, "TombstoneScannedHistogram"); - System.out.println("\t\tAverage tombstones per slice (last five minutes): " + histogram.getMean()); - System.out.println("\t\tMaximum tombstones per slice (last five minutes): " + histogram.getMax()); + out.println("\t\tAverage tombstones per slice (last five minutes): " + histogram.getMean()); + out.println("\t\tMaximum tombstones per slice (last five minutes): " + histogram.getMax()); - System.out.println(""); + out.println(""); } - System.out.println("----------------"); + out.println("----------------"); } } diff --git a/src/java/org/apache/cassandra/tools/nodetool/TopPartitions.java b/src/java/org/apache/cassandra/tools/nodetool/TopPartitions.java index b473a8de3b..dda42e1c0e 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/TopPartitions.java +++ b/src/java/org/apache/cassandra/tools/nodetool/TopPartitions.java @@ -23,6 +23,7 @@ import io.airlift.command.Arguments; import io.airlift.command.Command; import io.airlift.command.Option; +import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -57,6 +58,7 @@ public class TopPartitions extends NodeToolCmd { checkArgument(args.size() == 3, "toppartitions requires keyspace, column family name, and duration"); checkArgument(topCount < size, "TopK count (-k) option must be smaller then the summary capacity (-s)"); + PrintStream out = probe.output().out; String keyspace = args.get(0); String cfname = args.get(1); Integer duration = Integer.parseInt(args.get(2)); @@ -95,23 +97,23 @@ public class TopPartitions extends NodeToolCmd } }); if(!first) - System.out.println(); - System.out.println(result.getKey().toString()+ " Sampler:"); - System.out.printf(" Cardinality: ~%d (%d capacity)%n", (long) sampling.get("cardinality"), size); - System.out.printf(" Top %d partitions:%n", topCount); + out.println(); + out.println(result.getKey().toString()+ " Sampler:"); + out.printf(" Cardinality: ~%d (%d capacity)%n", (long) sampling.get("cardinality"), size); + out.printf(" Top %d partitions:%n", topCount); if (topk.size() == 0) { - System.out.println("\tNothing recorded during sampling period..."); + out.println("\tNothing recorded during sampling period..."); } else { int offset = 0; for (CompositeData entry : topk) offset = Math.max(offset, entry.get("string").toString().length()); - System.out.printf("\t%-" + offset + "s%10s%10s%n", "Partition", "Count", "+/-"); + out.printf("\t%-" + offset + "s%10s%10s%n", "Partition", "Count", "+/-"); for (CompositeData entry : topk) - System.out.printf("\t%-" + offset + "s%10d%10d%n", entry.get("string").toString(), entry.get("count"), entry.get("error")); + out.printf("\t%-" + offset + "s%10d%10d%n", entry.get("string").toString(), entry.get("count"), entry.get("error")); } first = false; } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/TpStats.java b/src/java/org/apache/cassandra/tools/nodetool/TpStats.java index 5d3eab7ca9..c0e909aba8 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/TpStats.java +++ b/src/java/org/apache/cassandra/tools/nodetool/TpStats.java @@ -19,6 +19,7 @@ package org.apache.cassandra.tools.nodetool; import io.airlift.command.Command; +import java.io.PrintStream; import java.util.Map; import com.google.common.collect.Multimap; @@ -32,13 +33,14 @@ public class TpStats extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.printf("%-25s%10s%10s%15s%10s%18s%n", "Pool Name", "Active", "Pending", "Completed", "Blocked", "All time blocked"); + PrintStream out = probe.output().out; + out.printf("%-25s%10s%10s%15s%10s%18s%n", "Pool Name", "Active", "Pending", "Completed", "Blocked", "All time blocked"); Multimap threadPools = probe.getThreadPools(); for (Map.Entry tpool : threadPools.entries()) { - System.out.printf("%-25s%10s%10s%15s%10s%18s%n", + out.printf("%-25s%10s%10s%15s%10s%18s%n", tpool.getValue(), probe.getThreadPoolMetric(tpool.getKey(), tpool.getValue(), "ActiveTasks"), probe.getThreadPoolMetric(tpool.getKey(), tpool.getValue(), "PendingTasks"), @@ -47,8 +49,8 @@ public class TpStats extends NodeToolCmd probe.getThreadPoolMetric(tpool.getKey(), tpool.getValue(), "TotalBlockedTasks")); } - System.out.printf("%n%-20s%10s%n", "Message type", "Dropped"); + out.printf("%n%-20s%10s%n", "Message type", "Dropped"); for (Map.Entry entry : probe.getDroppedMessages().entrySet()) - System.out.printf("%-20s%10s%n", entry.getKey(), entry.getValue()); + out.printf("%-20s%10s%n", entry.getKey(), entry.getValue()); } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/UpgradeSSTable.java b/src/java/org/apache/cassandra/tools/nodetool/UpgradeSSTable.java index 82866e07c5..4d8ed94327 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/UpgradeSSTable.java +++ b/src/java/org/apache/cassandra/tools/nodetool/UpgradeSSTable.java @@ -51,7 +51,7 @@ public class UpgradeSSTable extends NodeToolCmd { try { - probe.upgradeSSTables(System.out, keyspace, !includeAll, jobs, tableNames); + probe.upgradeSSTables(probe.output().out, keyspace, !includeAll, jobs, tableNames); } catch (Exception e) { @@ -59,4 +59,4 @@ public class UpgradeSSTable extends NodeToolCmd } } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/Verify.java b/src/java/org/apache/cassandra/tools/nodetool/Verify.java index c449366a57..2a6789a647 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Verify.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Verify.java @@ -48,11 +48,11 @@ public class Verify extends NodeToolCmd { try { - probe.verify(System.out, extendedVerify, keyspace, tableNames); + probe.verify(probe.output().out, extendedVerify, keyspace, tableNames); } catch (Exception e) { throw new RuntimeException("Error occurred during verifying", e); } } } -} \ No newline at end of file +} diff --git a/src/java/org/apache/cassandra/tools/nodetool/Version.java b/src/java/org/apache/cassandra/tools/nodetool/Version.java index 2495508f7e..ffd4b06473 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Version.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Version.java @@ -28,6 +28,6 @@ public class Version extends NodeToolCmd @Override public void execute(NodeProbe probe) { - System.out.println("ReleaseVersion: " + probe.getReleaseVersion()); + probe.output().out.println("ReleaseVersion: " + probe.getReleaseVersion()); } -} \ No newline at end of file +} diff --git a/test/distributed/org/apache/cassandra/distributed/impl/Instance.java b/test/distributed/org/apache/cassandra/distributed/impl/Instance.java index b9b6337d53..37df8ee2f6 100644 --- a/test/distributed/org/apache/cassandra/distributed/impl/Instance.java +++ b/test/distributed/org/apache/cassandra/distributed/impl/Instance.java @@ -21,6 +21,9 @@ package org.apache.cassandra.distributed.impl; import java.io.File; import java.io.IOException; import java.net.InetAddress; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.PrintStream; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -98,6 +101,7 @@ import org.apache.cassandra.service.QueryState; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.service.StorageServiceMBean; import org.apache.cassandra.streaming.StreamCoordinator; +import org.apache.cassandra.tools.Output; import org.apache.cassandra.tools.NodeTool; import org.apache.cassandra.tracing.TraceState; import org.apache.cassandra.tracing.Tracing; @@ -769,20 +773,66 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance public NodeToolResult nodetoolResult(boolean withNotifications, String... commandAndArgs) { return sync(() -> { - DTestNodeTool nodetool = new DTestNodeTool(withNotifications); - int rc = nodetool.execute(commandAndArgs); - return new NodeToolResult(commandAndArgs, rc, new ArrayList<>(nodetool.notifications.notifications), nodetool.latestError); + try (CapturingOutput output = new CapturingOutput()) + { + DTestNodeTool nodetool = new DTestNodeTool(withNotifications, output.delegate); + int rc = nodetool.execute(commandAndArgs); + return new NodeToolResult(commandAndArgs, rc, + new ArrayList<>(nodetool.notifications.notifications), + nodetool.latestError, + output.getOutString(), + output.getErrString()); + } }).call(); } - private static class DTestNodeTool extends NodeTool { + private static class CapturingOutput implements Closeable + { + @SuppressWarnings("resource") + private final ByteArrayOutputStream outBase = new ByteArrayOutputStream(); + @SuppressWarnings("resource") + private final ByteArrayOutputStream errBase = new ByteArrayOutputStream(); + + public final PrintStream out; + public final PrintStream err; + private final Output delegate; + + public CapturingOutput() + { + PrintStream out = new PrintStream(outBase, true); + PrintStream err = new PrintStream(errBase, true); + this.delegate = new Output(out, err); + this.out = out; + this.err = err; + } + + public String getOutString() + { + out.flush(); + return outBase.toString(); + } + + public String getErrString() + { + err.flush(); + return errBase.toString(); + } + + public void close() + { + out.close(); + err.close(); + } + } + + public static class DTestNodeTool extends NodeTool { private final StorageServiceMBean storageProxy; private final CollectingNotificationListener notifications = new CollectingNotificationListener(); private Throwable latestError; - DTestNodeTool(boolean withNotifications) { - super(new InternalNodeProbeFactory(withNotifications)); + public DTestNodeTool(boolean withNotifications, Output output) { + super(new InternalNodeProbeFactory(withNotifications), output); storageProxy = new InternalNodeProbe(withNotifications).getStorageService(); storageProxy.addNotificationListener(notifications, null, null); } diff --git a/test/distributed/org/apache/cassandra/distributed/test/ClientNetworkStopStartTest.java b/test/distributed/org/apache/cassandra/distributed/test/ClientNetworkStopStartTest.java index 1d23ac7f8e..da0731ef7e 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/ClientNetworkStopStartTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/ClientNetworkStopStartTest.java @@ -18,14 +18,11 @@ package org.apache.cassandra.distributed.test; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.PrintStream; import java.util.Arrays; import java.util.Collections; import java.util.Objects; -import org.junit.Assert; import org.junit.Test; import com.datastax.driver.core.Session; @@ -34,6 +31,7 @@ import org.apache.cassandra.distributed.Cluster; import org.apache.cassandra.distributed.api.ConsistencyLevel; import org.apache.cassandra.distributed.api.Feature; import org.apache.cassandra.distributed.api.IInvokableInstance; +import org.apache.cassandra.distributed.api.NodeToolResult; import org.apache.cassandra.distributed.api.QueryResults; import org.apache.cassandra.distributed.api.SimpleQueryResult; import org.apache.cassandra.distributed.shared.AssertUtils; @@ -128,26 +126,10 @@ public class ClientNetworkStopStartTest extends TestBaseImpl private static void assertNodetoolStdout(IInvokableInstance node, String expectedStatus, String notExpected, String... nodetool) { - // without CASSANDRA-16057 need this hack - PrintStream previousStdout = System.out; - try - { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrintStream stdout = new PrintStream(out, true); - System.setOut(stdout); - - node.nodetoolResult(nodetool).asserts().success(); - - stdout.flush(); - String output = out.toString(); - Assert.assertThat(output, new StringContains(expectedStatus)); - if (notExpected != null) - Assert.assertThat(output, new StringNotContains(notExpected)); - } - finally - { - System.setOut(previousStdout); - } + NodeToolResult.Asserts asserts = node.nodetoolResult(nodetool).asserts(); + asserts.stdoutContains(expectedStatus); + if (notExpected != null) + asserts.stdoutNotContains(notExpected); } private static final class StringContains extends BaseMatcher diff --git a/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java b/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java index 1d78152954..d8b9ce7fba 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java @@ -21,13 +21,15 @@ package org.apache.cassandra.distributed.test; import org.junit.Test; import org.apache.cassandra.distributed.Cluster; +import org.apache.cassandra.distributed.api.ICluster; +import org.apache.cassandra.distributed.api.NodeToolResult; import static org.junit.Assert.assertEquals; public class NodeToolTest extends TestBaseImpl { @Test - public void test() throws Throwable + public void testCommands() throws Throwable { try (Cluster cluster = init(Cluster.create(1))) { @@ -36,4 +38,16 @@ public class NodeToolTest extends TestBaseImpl assertEquals(1, cluster.get(1).nodetool("not_a_legal_command")); } } + + @Test + public void testCaptureConsoleOutput() throws Throwable + { + try (ICluster cluster = init(builder().withNodes(1).start())) + { + NodeToolResult ringResult = cluster.get(1).nodetoolResult("ring"); + ringResult.asserts().stdoutContains("Datacenter: datacenter0"); + ringResult.asserts().stdoutContains("127.0.0.1 rack0 Up Normal"); + assertEquals("Non-empty error output", "", ringResult.getStderr()); + } + } }