Repository: cassandra Updated Branches: refs/heads/trunk 47a4cbedf -> c5a819005
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetHostStat.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetHostStat.java b/src/java/org/apache/cassandra/tools/nodetool/SetHostStat.java new file mode 100644 index 0000000..c43abe1 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/SetHostStat.java @@ -0,0 +1,54 @@ +/* + * 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; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class SetHostStat implements Iterable<HostStat> +{ + final List<HostStat> hostStats = new ArrayList<HostStat>(); + final boolean resolveIp; + + public SetHostStat(boolean resolveIp) + { + this.resolveIp = resolveIp; + } + + public int size() + { + return hostStats.size(); + } + + @Override + public Iterator<HostStat> iterator() + { + return hostStats.iterator(); + } + + public void add(String token, String host, Map<InetAddress, Float> ownerships) throws UnknownHostException + { + InetAddress endpoint = InetAddress.getByName(host); + Float owns = ownerships.get(endpoint); + hostStats.add(new HostStat(token, endpoint, resolveIp, owns)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetLoggingLevel.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetLoggingLevel.java b/src/java/org/apache/cassandra/tools/nodetool/SetLoggingLevel.java new file mode 100644 index 0000000..d11d48f --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/SetLoggingLevel.java @@ -0,0 +1,43 @@ +/* + * 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; + +import static org.apache.commons.lang3.StringUtils.EMPTY; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "setlogginglevel", description = "Set the log level threshold for a given class. If both class and level are empty/null, it will reset to the initial configuration") +public class SetLoggingLevel extends NodeToolCmd +{ + @Arguments(usage = "<class> <level>", description = "The class to change the level for and the log level threshold to set (can be empty)") + private List<String> args = new ArrayList<>(); + + @Override + public void execute(NodeProbe probe) + { + String classQualifier = args.size() >= 1 ? args.get(0) : EMPTY; + String level = args.size() == 2 ? args.get(1) : EMPTY; + probe.setLoggingLevel(classQualifier, level); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetStreamThroughput.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetStreamThroughput.java b/src/java/org/apache/cassandra/tools/nodetool/SetStreamThroughput.java new file mode 100644 index 0000000..8055872 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/SetStreamThroughput.java @@ -0,0 +1,37 @@ +/* + * 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; + +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "setstreamthroughput", description = "Set the Mb/s throughput cap for streaming in the system, or 0 to disable throttling") +public class SetStreamThroughput extends NodeToolCmd +{ + @Arguments(title = "stream_throughput", usage = "<value_in_mb>", description = "Value in Mb, 0 to disable throttling", required = true) + private Integer streamThroughput = null; + + @Override + public void execute(NodeProbe probe) + { + probe.setStreamThroughput(streamThroughput); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetTraceProbability.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetTraceProbability.java b/src/java/org/apache/cassandra/tools/nodetool/SetTraceProbability.java new file mode 100644 index 0000000..ebef1a4 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/SetTraceProbability.java @@ -0,0 +1,39 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkArgument; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "settraceprobability", description = "Sets the probability for tracing any given request to value. 0 disables, 1 enables for all requests, 0 is the default") +public class SetTraceProbability extends NodeToolCmd +{ + @Arguments(title = "trace_probability", usage = "<value>", description = "Trace probability between 0 and 1 (ex: 0.2)", required = true) + private Double traceProbability = null; + + @Override + public void execute(NodeProbe probe) + { + checkArgument(traceProbability >= 0 && traceProbability <= 1, "Trace probability must be between 0 and 1"); + probe.setTraceProbability(traceProbability); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java b/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java new file mode 100644 index 0000000..22cc775 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Snapshot.java @@ -0,0 +1,71 @@ +/* + * 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; + +import static com.google.common.collect.Iterables.toArray; +import static org.apache.commons.lang3.StringUtils.join; +import io.airlift.command.Arguments; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "snapshot", description = "Take a snapshot of specified keyspaces or a snapshot of the specified table") +public class Snapshot extends NodeToolCmd +{ + @Arguments(usage = "[<keyspaces...>]", description = "List of keyspaces. By default, all keyspaces") + private List<String> keyspaces = new ArrayList<>(); + + @Option(title = "table", name = {"-cf", "--column-family", "--table"}, description = "The table name (you must specify one and only one keyspace for using this option)") + private String columnFamily = null; + + @Option(title = "tag", name = {"-t", "--tag"}, description = "The name of the snapshot") + private String snapshotName = Long.toString(System.currentTimeMillis()); + + @Override + public void execute(NodeProbe probe) + { + try + { + StringBuilder sb = new StringBuilder(); + + sb.append("Requested creating snapshot(s) for "); + + if (keyspaces.isEmpty()) + sb.append("[all keyspaces]"); + else + sb.append("[").append(join(keyspaces, ", ")).append("]"); + + if (!snapshotName.isEmpty()) + sb.append(" with snapshot name [").append(snapshotName).append("]"); + + System.out.println(sb.toString()); + + probe.takeSnapshot(snapshotName, columnFamily, toArray(keyspaces, String.class)); + System.out.println("Snapshot directory: " + snapshotName); + } catch (IOException e) + { + throw new RuntimeException("Error during taking a snapshot", e); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Status.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Status.java b/src/java/org/apache/cassandra/tools/nodetool/Status.java new file mode 100644 index 0000000..c4b2295 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Status.java @@ -0,0 +1,206 @@ +/* + * 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; + +import io.airlift.command.Arguments; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.text.DecimalFormat; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.locator.EndpointSnitchInfoMBean; +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +import com.google.common.collect.ArrayListMultimap; + +@Command(name = "status", description = "Print cluster information (state, load, IDs, ...)") +public class Status extends NodeToolCmd +{ + @Arguments(usage = "[<keyspace>]", description = "The keyspace name") + private String keyspace = null; + + @Option(title = "resolve_ip", name = {"-r", "--resolve-ip"}, description = "Show node domain names instead of IPs") + private boolean resolveIp = false; + + private boolean isTokenPerNode = true; + private int maxAddressLength = 0; + private String format = null; + private Collection<String> joiningNodes, leavingNodes, movingNodes, liveNodes, unreachableNodes; + private Map<String, String> loadMap, hostIDMap; + private EndpointSnitchInfoMBean epSnitchInfo; + + @Override + public void execute(NodeProbe probe) + { + joiningNodes = probe.getJoiningNodes(); + leavingNodes = probe.getLeavingNodes(); + movingNodes = probe.getMovingNodes(); + loadMap = probe.getLoadMap(); + Map<String, String> tokensToEndpoints = probe.getTokenToEndpointMap(); + liveNodes = probe.getLiveNodes(); + unreachableNodes = probe.getUnreachableNodes(); + hostIDMap = probe.getHostIdMap(); + epSnitchInfo = probe.getEndpointSnitchInfoProxy(); + + StringBuffer errors = new StringBuffer(); + + Map<InetAddress, Float> ownerships = null; + boolean hasEffectiveOwns = false; + try + { + ownerships = probe.effectiveOwnership(keyspace); + hasEffectiveOwns = true; + } + catch (IllegalStateException e) + { + ownerships = probe.getOwnership(); + errors.append("Note: " + e.getMessage() + "%n"); + } + catch (IllegalArgumentException ex) + { + System.out.printf("%nError: " + ex.getMessage() + "%n"); + System.exit(1); + } + + Map<String, SetHostStat> dcs = NodeTool.getOwnershipByDc(probe, resolveIp, tokensToEndpoints, ownerships); + + // More tokens than nodes (aka vnodes)? + if (dcs.values().size() < tokensToEndpoints.keySet().size()) + isTokenPerNode = false; + + findMaxAddressLength(dcs); + + // Datacenters + for (Map.Entry<String, SetHostStat> dc : dcs.entrySet()) + { + String dcHeader = String.format("Datacenter: %s%n", dc.getKey()); + System.out.printf(dcHeader); + for (int i = 0; i < (dcHeader.length() - 1); i++) System.out.print('='); + System.out.println(); + + // Legend + System.out.println("Status=Up/Down"); + System.out.println("|/ State=Normal/Leaving/Joining/Moving"); + + printNodesHeader(hasEffectiveOwns, isTokenPerNode); + + ArrayListMultimap<InetAddress, HostStat> hostToTokens = ArrayListMultimap.create(); + for (HostStat stat : dc.getValue()) + hostToTokens.put(stat.endpoint, stat); + + for (InetAddress endpoint : hostToTokens.keySet()) + { + Float owns = ownerships.get(endpoint); + List<HostStat> tokens = hostToTokens.get(endpoint); + printNode(endpoint.getHostAddress(), owns, tokens, hasEffectiveOwns, isTokenPerNode); + } + } + + System.out.printf("%n" + errors.toString()); + + } + + private void findMaxAddressLength(Map<String, SetHostStat> dcs) + { + maxAddressLength = 0; + for (Map.Entry<String, SetHostStat> dc : dcs.entrySet()) + { + for (HostStat stat : dc.getValue()) + { + maxAddressLength = Math.max(maxAddressLength, stat.ipOrDns().length()); + } + } + } + + private void printNodesHeader(boolean hasEffectiveOwns, boolean isTokenPerNode) + { + String fmt = getFormat(hasEffectiveOwns, isTokenPerNode); + String owns = hasEffectiveOwns ? "Owns (effective)" : "Owns"; + + if (isTokenPerNode) + System.out.printf(fmt, "-", "-", "Address", "Load", owns, "Host ID", "Token", "Rack"); + else + System.out.printf(fmt, "-", "-", "Address", "Load", "Tokens", owns, "Host ID", "Rack"); + } + + private void printNode(String endpoint, Float owns, List<HostStat> tokens, boolean hasEffectiveOwns, boolean isTokenPerNode) + { + String status, state, load, strOwns, hostID, rack, fmt; + fmt = getFormat(hasEffectiveOwns, isTokenPerNode); + if (liveNodes.contains(endpoint)) status = "U"; + else if (unreachableNodes.contains(endpoint)) status = "D"; + else status = "?"; + if (joiningNodes.contains(endpoint)) state = "J"; + else if (leavingNodes.contains(endpoint)) state = "L"; + else if (movingNodes.contains(endpoint)) state = "M"; + else state = "N"; + + load = loadMap.containsKey(endpoint) ? loadMap.get(endpoint) : "?"; + strOwns = owns != null && hasEffectiveOwns ? new DecimalFormat("##0.0%").format(owns) : "?"; + hostID = hostIDMap.get(endpoint); + + try + { + rack = epSnitchInfo.getRack(endpoint); + } catch (UnknownHostException e) + { + throw new RuntimeException(e); + } + + String endpointDns = tokens.get(0).ipOrDns(); + if (isTokenPerNode) + System.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); + } + + private String getFormat( + boolean hasEffectiveOwns, + boolean isTokenPerNode) + { + if (format == null) + { + StringBuilder buf = new StringBuilder(); + String addressPlaceholder = String.format("%%-%ds ", maxAddressLength); + buf.append("%s%s "); // status + buf.append(addressPlaceholder); // address + buf.append("%-9s "); // load + if (!isTokenPerNode) + buf.append("%-11s "); // "Tokens" + if (hasEffectiveOwns) + buf.append("%-16s "); // "Owns (effective)" + else + buf.append("%-6s "); // "Owns + buf.append("%-36s "); // Host ID + if (isTokenPerNode) + buf.append("%-39s "); // token + buf.append("%s%n"); // "Rack" + + format = buf.toString(); + } + + return format; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/StatusBackup.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusBackup.java b/src/java/org/apache/cassandra/tools/nodetool/StatusBackup.java new file mode 100644 index 0000000..49a6750 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusBackup.java @@ -0,0 +1,36 @@ +/* + * 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; + +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "statusbackup", description = "Status of incremental backup") +public class StatusBackup extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + System.out.println( + probe.isIncrementalBackupsEnabled() + ? "running" + : "not running"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/StatusBinary.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusBinary.java b/src/java/org/apache/cassandra/tools/nodetool/StatusBinary.java new file mode 100644 index 0000000..d4fae14 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusBinary.java @@ -0,0 +1,36 @@ +/* + * 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; + +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "statusbinary", description = "Status of native transport (binary protocol)") +public class StatusBinary extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + System.out.println( + probe.isNativeTransportRunning() + ? "running" + : "not running"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/StatusGossip.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusGossip.java b/src/java/org/apache/cassandra/tools/nodetool/StatusGossip.java new file mode 100644 index 0000000..e40df8d --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusGossip.java @@ -0,0 +1,36 @@ +/* + * 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; + +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "statusgossip", description = "Status of gossip") +public class StatusGossip extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + System.out.println( + probe.isGossipRunning() + ? "running" + : "not running"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/StatusHandoff.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusHandoff.java b/src/java/org/apache/cassandra/tools/nodetool/StatusHandoff.java new file mode 100644 index 0000000..5a00069 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusHandoff.java @@ -0,0 +1,36 @@ +/* + * 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; + +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "statushandoff", description = "Status of storing future hints on the current node") +public class StatusHandoff extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + System.out.println( + probe.isHandoffEnabled() + ? "running" + : "not running"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/StatusThrift.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/StatusThrift.java b/src/java/org/apache/cassandra/tools/nodetool/StatusThrift.java new file mode 100644 index 0000000..0cb17d2 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/StatusThrift.java @@ -0,0 +1,36 @@ +/* + * 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; + +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "statusthrift", description = "Status of thrift server") +public class StatusThrift extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + System.out.println( + probe.isThriftServerRunning() + ? "running" + : "not running"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Stop.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Stop.java b/src/java/org/apache/cassandra/tools/nodetool/Stop.java new file mode 100644 index 0000000..b3bb2b8 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Stop.java @@ -0,0 +1,38 @@ +/* + * 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; + +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import org.apache.cassandra.db.compaction.OperationType; +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "stop", description = "Stop compaction") +public class Stop extends NodeToolCmd +{ + @Arguments(title = "compaction_type", usage = "<compaction type>", description = "Supported types are COMPACTION, VALIDATION, CLEANUP, SCRUB, VERIFY, INDEX_BUILD", required = true) + private OperationType compactionType = OperationType.UNKNOWN; + + @Override + public void execute(NodeProbe probe) + { + probe.stop(compactionType.name()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/StopDaemon.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/StopDaemon.java b/src/java/org/apache/cassandra/tools/nodetool/StopDaemon.java new file mode 100644 index 0000000..a0af89f --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/StopDaemon.java @@ -0,0 +1,42 @@ +/* + * 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; + +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; +import org.apache.cassandra.utils.JVMStabilityInspector; + +@Command(name = "stopdaemon", description = "Stop cassandra daemon") +public class StopDaemon extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + try + { + probe.stopCassandraDaemon(); + } catch (Exception e) + { + JVMStabilityInspector.inspectThrowable(e); + // ignored + } + System.out.println("Cassandra has shutdown."); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/TopPartitions.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/TopPartitions.java b/src/java/org/apache/cassandra/tools/nodetool/TopPartitions.java new file mode 100644 index 0000000..35e13ce --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/TopPartitions.java @@ -0,0 +1,117 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.apache.commons.lang3.StringUtils.join; +import io.airlift.command.Arguments; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.TabularDataSupport; + +import org.apache.cassandra.metrics.ColumnFamilyMetrics; +import org.apache.cassandra.metrics.ColumnFamilyMetrics.Sampler; +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; + +@Command(name = "toppartitions", description = "Sample and print the most active partitions for a given column family") +public class TopPartitions extends NodeToolCmd +{ + @Arguments(usage = "<keyspace> <cfname> <duration>", description = "The keyspace, column family name, and duration in milliseconds") + private List<String> args = new ArrayList<>(); + @Option(name = "-s", description = "Capacity of stream summary, closer to the actual cardinality of partitions will yield more accurate results (Default: 256)") + private int size = 256; + @Option(name = "-k", description = "Number of the top partitions to list (Default: 10)") + private int topCount = 10; + @Option(name = "-a", description = "Comma separated list of samplers to use (Default: all)") + private String samplers = join(ColumnFamilyMetrics.Sampler.values(), ','); + @Override + public void execute(NodeProbe probe) + { + 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)"); + String keyspace = args.get(0); + String cfname = args.get(1); + Integer duration = Integer.parseInt(args.get(2)); + // generate the list of samplers + List<Sampler> targets = Lists.newArrayList(); + for (String s : samplers.split(",")) + { + try + { + targets.add(Sampler.valueOf(s.toUpperCase())); + } catch (Exception e) + { + throw new IllegalArgumentException(s + " is not a valid sampler, choose one of: " + join(Sampler.values(), ", ")); + } + } + + Map<Sampler, CompositeData> results; + try + { + results = probe.getPartitionSample(keyspace, cfname, size, duration, topCount, targets); + } catch (OpenDataException e) + { + throw new RuntimeException(e); + } + boolean first = true; + for(Entry<Sampler, CompositeData> result : results.entrySet()) + { + CompositeData sampling = result.getValue(); + // weird casting for http://bugs.sun.com/view_bug.do?bug_id=6548436 + List<CompositeData> topk = (List<CompositeData>) (Object) Lists.newArrayList(((TabularDataSupport) sampling.get("partitions")).values()); + Collections.sort(topk, new Ordering<CompositeData>() + { + public int compare(CompositeData left, CompositeData right) + { + return Long.compare((long) right.get("count"), (long) left.get("count")); + } + }); + 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); + if (topk.size() == 0) + { + System.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", "+/-"); + for (CompositeData entry : topk) + System.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 http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/TpStats.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/TpStats.java b/src/java/org/apache/cassandra/tools/nodetool/TpStats.java new file mode 100644 index 0000000..4a17c4c --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/TpStats.java @@ -0,0 +1,51 @@ +/* + * 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; + +import io.airlift.command.Command; + +import java.util.Map; + +import org.apache.cassandra.concurrent.Stage; +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "tpstats", description = "Print usage statistics of thread pools") +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"); + + for (Stage stage : Stage.jmxEnabledStages()) + { + System.out.printf("%-25s%10s%10s%15s%10s%18s%n", + stage.getJmxName(), + probe.getThreadPoolMetric(stage, "ActiveTasks"), + probe.getThreadPoolMetric(stage, "PendingTasks"), + probe.getThreadPoolMetric(stage, "CompletedTasks"), + probe.getThreadPoolMetric(stage, "CurrentlyBlockedTasks"), + probe.getThreadPoolMetric(stage, "TotalBlockedTasks")); + } + + System.out.printf("%n%-20s%10s%n", "Message type", "Dropped"); + for (Map.Entry<String, Integer> entry : probe.getDroppedMessages().entrySet()) + System.out.printf("%-20s%10s%n", entry.getKey(), entry.getValue()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/TruncateHints.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/TruncateHints.java b/src/java/org/apache/cassandra/tools/nodetool/TruncateHints.java new file mode 100644 index 0000000..bcd554f --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/TruncateHints.java @@ -0,0 +1,41 @@ +/* + * 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; + +import static org.apache.commons.lang3.StringUtils.EMPTY; +import io.airlift.command.Arguments; +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "truncatehints", description = "Truncate all hints on the local node, or truncate hints for the endpoint(s) specified.") +public class TruncateHints extends NodeToolCmd +{ + @Arguments(usage = "[endpoint ... ]", description = "Endpoint address(es) to delete hints for, either ip address (\"127.0.0.1\") or hostname") + private String endpoint = EMPTY; + + @Override + public void execute(NodeProbe probe) + { + if (endpoint.isEmpty()) + probe.truncateHints(); + else + probe.truncateHints(endpoint); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/UpgradeSSTable.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/UpgradeSSTable.java b/src/java/org/apache/cassandra/tools/nodetool/UpgradeSSTable.java new file mode 100644 index 0000000..86a2cd5 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/UpgradeSSTable.java @@ -0,0 +1,56 @@ +/* + * 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; + +import io.airlift.command.Arguments; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "upgradesstables", description = "Rewrite sstables (for the requested tables) that are not on the current version (thus upgrading them to said current version)") +public class UpgradeSSTable extends NodeToolCmd +{ + @Arguments(usage = "[<keyspace> <tables>...]", description = "The keyspace followed by one or many tables") + private List<String> args = new ArrayList<>(); + + @Option(title = "include_all", name = {"-a", "--include-all-sstables"}, description = "Use -a to include all sstables, even those already on the current version") + private boolean includeAll = false; + + @Override + public void execute(NodeProbe probe) + { + List<String> keyspaces = parseOptionalKeyspace(args, probe); + String[] cfnames = parseOptionalColumnFamilies(args); + + for (String keyspace : keyspaces) + { + try + { + probe.upgradeSSTables(System.out, keyspace, !includeAll, cfnames); + } catch (Exception e) + { + throw new RuntimeException("Error occurred during enabling auto-compaction", e); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Verify.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Verify.java b/src/java/org/apache/cassandra/tools/nodetool/Verify.java new file mode 100644 index 0000000..813b761 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Verify.java @@ -0,0 +1,58 @@ +/* + * 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; + +import io.airlift.command.Arguments; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "verify", description = "Verify (check data checksum for) one or more tables") +public class Verify extends NodeToolCmd +{ + @Arguments(usage = "[<keyspace> <tables>...]", description = "The keyspace followed by one or many tables") + private List<String> args = new ArrayList<>(); + + @Option(title = "extended_verify", + name = {"-e", "--extended-verify"}, + description = "Verify each cell data, beyond simply checking sstable checksums") + private boolean extendedVerify = false; + + @Override + public void execute(NodeProbe probe) + { + List<String> keyspaces = parseOptionalKeyspace(args, probe); + String[] cfnames = parseOptionalColumnFamilies(args); + + for (String keyspace : keyspaces) + { + try + { + probe.verify(System.out, extendedVerify, keyspace, cfnames); + } catch (Exception e) + { + throw new RuntimeException("Error occurred during verifying", e); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Version.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/Version.java b/src/java/org/apache/cassandra/tools/nodetool/Version.java new file mode 100644 index 0000000..2495508 --- /dev/null +++ b/src/java/org/apache/cassandra/tools/nodetool/Version.java @@ -0,0 +1,33 @@ +/* + * 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; + +import io.airlift.command.Command; + +import org.apache.cassandra.tools.NodeProbe; +import org.apache.cassandra.tools.NodeTool.NodeToolCmd; + +@Command(name = "version", description = "Print cassandra version") +public class Version extends NodeToolCmd +{ + @Override + public void execute(NodeProbe probe) + { + System.out.println("ReleaseVersion: " + probe.getReleaseVersion()); + } +} \ No newline at end of file
