Repository: cassandra Updated Branches: refs/heads/trunk df0cd441e -> 768e717d7
json/yaml output format for nodetool compactionhistory patch by Masataka Yamaguchi; reviewed by yukim for CASSANDRA-12486 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/768e717d Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/768e717d Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/768e717d Branch: refs/heads/trunk Commit: 768e717d7ab8c629d7623c619aff1ef99ca8eaf8 Parents: df0cd44 Author: Masataka Yamaguchi <[email protected]> Authored: Tue Aug 23 11:27:20 2016 +0900 Committer: Yuki Morishita <[email protected]> Committed: Thu Aug 25 11:57:40 2016 -0500 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../tools/nodetool/CompactionHistory.java | 105 +++------------- .../nodetool/stats/CompactionHistoryHolder.java | 126 +++++++++++++++++++ .../stats/CompactionHistoryPrinter.java | 81 ++++++++++++ 4 files changed, 223 insertions(+), 90 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/768e717d/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 483db71..9d69dfe 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.10 + * json/yaml output format for nodetool compactionhistory (CASSANDRA-12486) * Retry all internode messages once after a connection is closed and reopened (CASSANDRA-12192) * Add support to rebuild from targeted replica (CASSANDRA-9875) http://git-wip-us.apache.org/repos/asf/cassandra/blob/768e717d/src/java/org/apache/cassandra/tools/nodetool/CompactionHistory.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/CompactionHistory.java b/src/java/org/apache/cassandra/tools/nodetool/CompactionHistory.java index 40c6887..8d24845 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/CompactionHistory.java +++ b/src/java/org/apache/cassandra/tools/nodetool/CompactionHistory.java @@ -17,107 +17,32 @@ */ package org.apache.cassandra.tools.nodetool; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import javax.management.openmbean.TabularData; - import io.airlift.command.Command; - +import io.airlift.command.Option; import org.apache.cassandra.tools.NodeProbe; import org.apache.cassandra.tools.NodeTool.NodeToolCmd; -import org.apache.cassandra.tools.nodetool.formatter.TableBuilder; - -import static com.google.common.collect.Iterables.toArray; +import org.apache.cassandra.tools.nodetool.stats.CompactionHistoryHolder; +import org.apache.cassandra.tools.nodetool.stats.CompactionHistoryPrinter; +import org.apache.cassandra.tools.nodetool.stats.StatsHolder; +import org.apache.cassandra.tools.nodetool.stats.StatsPrinter; @Command(name = "compactionhistory", description = "Print history of compaction") public class CompactionHistory extends NodeToolCmd { + @Option(title = "format", + name = {"-F", "--format"}, + description = "Output format (json, yaml)") + private String outputFormat = ""; + @Override public void execute(NodeProbe probe) { - System.out.println("Compaction History: "); - - TabularData tabularData = probe.getCompactionHistory(); - if (tabularData.isEmpty()) - { - System.out.printf("There is no compaction history"); - return; - } - - TableBuilder table = new TableBuilder(); - List<String> indexNames = tabularData.getTabularType().getIndexNames(); - table.add(toArray(indexNames, String.class)); - - Set<?> values = tabularData.keySet(); - List<CompactionHistoryRow> chr = new ArrayList<>(); - for (Object eachValue : values) - { - List<?> value = (List<?>) eachValue; - CompactionHistoryRow chc = new CompactionHistoryRow((String)value.get(0), - (String)value.get(1), - (String)value.get(2), - (Long)value.get(3), - (Long)value.get(4), - (Long)value.get(5), - (String)value.get(6)); - chr.add(chc); - } - Collections.sort(chr); - for (CompactionHistoryRow eachChc : chr) - { - table.add(eachChc.getAllAsArray()); - } - table.printTo(System.out); - } - - /** - * Allows the Compaction History output to be ordered by 'compactedAt' - that is the - * time at which compaction finished. - */ - private static class CompactionHistoryRow implements Comparable<CompactionHistoryRow> - { - private final String id; - private final String ksName; - private final String cfName; - private final long compactedAt; - private final long bytesIn; - private final long bytesOut; - private final String rowMerged; - - CompactionHistoryRow(String id, String ksName, String cfName, long compactedAt, long bytesIn, long bytesOut, String rowMerged) - { - this.id = id; - this.ksName = ksName; - this.cfName = cfName; - this.compactedAt = compactedAt; - this.bytesIn = bytesIn; - this.bytesOut = bytesOut; - this.rowMerged = rowMerged; - } - - public int compareTo(CompactionHistoryRow chc) - { - return Long.signum(chc.compactedAt - this.compactedAt); - } - - public String[] getAllAsArray() + if (!outputFormat.isEmpty() && !"json".equals(outputFormat) && !"yaml".equals(outputFormat)) { - String[] obj = new String[7]; - obj[0] = this.id; - obj[1] = this.ksName; - obj[2] = this.cfName; - Instant instant = Instant.ofEpochMilli(this.compactedAt); - LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); - obj[3] = ldt.toString(); - obj[4] = Long.toString(this.bytesIn); - obj[5] = Long.toString(this.bytesOut); - obj[6] = this.rowMerged; - return obj; + throw new IllegalArgumentException("arguments for -F are json,yaml only."); } + StatsHolder data = new CompactionHistoryHolder(probe); + StatsPrinter printer = CompactionHistoryPrinter.from(outputFormat); + printer.print(data, System.out); } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/768e717d/src/java/org/apache/cassandra/tools/nodetool/stats/CompactionHistoryHolder.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/stats/CompactionHistoryHolder.java b/src/java/org/apache/cassandra/tools/nodetool/stats/CompactionHistoryHolder.java new file mode 100644 index 0000000..8799ffb --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/stats/CompactionHistoryHolder.java @@ -0,0 +1,126 @@ +/* + * 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.nodetool.stats; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.management.openmbean.TabularData; + +import org.apache.cassandra.tools.NodeProbe; + +public class CompactionHistoryHolder implements StatsHolder +{ + public final NodeProbe probe; + public List<String> indexNames; + + public CompactionHistoryHolder(NodeProbe probe) + { + this.probe = probe; + } + + /** + * Allows the Compaction History output to be ordered by 'compactedAt' - that is the + * time at which compaction finished. + */ + private static class CompactionHistoryRow implements Comparable<CompactionHistoryHolder.CompactionHistoryRow> + { + private final String id; + private final String ksName; + private final String cfName; + private final long compactedAt; + private final long bytesIn; + private final long bytesOut; + private final String rowMerged; + + CompactionHistoryRow(String id, String ksName, String cfName, long compactedAt, long bytesIn, long bytesOut, String rowMerged) + { + this.id = id; + this.ksName = ksName; + this.cfName = cfName; + this.compactedAt = compactedAt; + this.bytesIn = bytesIn; + this.bytesOut = bytesOut; + this.rowMerged = rowMerged; + } + + public int compareTo(CompactionHistoryHolder.CompactionHistoryRow chr) + { + return Long.signum(chr.compactedAt - this.compactedAt); + } + + private HashMap<String, Object> getAllAsMap() + { + HashMap<String, Object> compaction = new HashMap<>(); + compaction.put("id", this.id); + compaction.put("keyspace_name", this.ksName); + compaction.put("columnfamily_name", this.cfName); + Instant instant = Instant.ofEpochMilli(this.compactedAt); + LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + compaction.put("compacted_at", ldt.toString()); + compaction.put("bytes_in", this.bytesIn); + compaction.put("bytes_out", this.bytesOut); + compaction.put("rows_merged", this.rowMerged); + return compaction; + } + } + + @Override + public Map<String, Object> convert2Map() + { + HashMap<String, Object> result = new HashMap<>(); + ArrayList<Map<String, Object>> compactions = new ArrayList<>(); + + TabularData tabularData = probe.getCompactionHistory(); + this.indexNames = tabularData.getTabularType().getIndexNames(); + + if (tabularData.isEmpty()) return result; + + List<CompactionHistoryHolder.CompactionHistoryRow> chrList = new ArrayList<>(); + Set<?> values = tabularData.keySet(); + for (Object eachValue : values) + { + List<?> value = (List<?>) eachValue; + CompactionHistoryHolder.CompactionHistoryRow chr = new CompactionHistoryHolder.CompactionHistoryRow( + (String)value.get(0), + (String)value.get(1), + (String)value.get(2), + (Long)value.get(3), + (Long)value.get(4), + (Long)value.get(5), + (String)value.get(6) + ); + chrList.add(chr); + } + + Collections.sort(chrList); + for (CompactionHistoryHolder.CompactionHistoryRow chr : chrList) + { + compactions.add(chr.getAllAsMap()); + } + result.put("CompactionHistory", compactions); + return result; + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/768e717d/src/java/org/apache/cassandra/tools/nodetool/stats/CompactionHistoryPrinter.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/stats/CompactionHistoryPrinter.java b/src/java/org/apache/cassandra/tools/nodetool/stats/CompactionHistoryPrinter.java new file mode 100644 index 0000000..97ed1c4 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/stats/CompactionHistoryPrinter.java @@ -0,0 +1,81 @@ +/* + * 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.nodetool.stats; + +import java.io.PrintStream; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.tools.nodetool.formatter.TableBuilder; + +import static com.google.common.collect.Iterables.toArray; + +public class CompactionHistoryPrinter +{ + public static StatsPrinter from(String format) + { + switch (format) + { + case "json": + return new StatsPrinter.JsonPrinter(); + case "yaml": + return new StatsPrinter.YamlPrinter(); + default: + return new DefaultPrinter(); + } + + } + + public static class DefaultPrinter implements StatsPrinter<CompactionHistoryHolder> + { + @Override + public void print(CompactionHistoryHolder data, PrintStream out) + { + + out.println("Compaction History: "); + Map<String, Object> convertData = data.convert2Map(); + List<Object> compactionHistories = convertData.get("CompactionHistory") instanceof List<?> ? (List)convertData.get("CompactionHistory") : Collections.emptyList(); + List<String> indexNames = data.indexNames; + + if (compactionHistories.size() == 0) { + out.printf("There is no compaction history"); + return; + } + + TableBuilder table = new TableBuilder(); + + table.add(toArray(indexNames, String.class)); + for (Object chr : compactionHistories) + { + Map value = chr instanceof Map<?, ?> ? (Map)chr : Collections.emptyMap(); + String[] obj = new String[7]; + obj[0] = (String)value.get("id"); + obj[1] = (String)value.get("keyspace_name"); + obj[2] = (String)value.get("columnfamily_name"); + obj[3] = (String)value.get("compacted_at"); + obj[4] = value.get("bytes_in").toString(); + obj[5] = value.get("bytes_out").toString(); + obj[6] = (String)value.get("rows_merged"); + table.add(obj); + } + table.printTo(out); + } + } +}
