diff --git a/CHANGES.txt b/CHANGES.txt index 15be2a388a..fd3b0c5da3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.1-alpha2 + * Revert breaking change in nodetool clientstats and expose cient options through nodetool clientstats --client-options. (CASSANDRA-17715) * Fix missed nowInSec values in QueryProcessor (CASSANDRA-17458) * Revert removal of withBufferSizeInMB(int size) in CQLSSTableWriter.Builder class and deprecate it in favor of withBufferSizeInMiB(int size) (CASSANDRA-17675) * Remove expired snapshots of dropped tables after restart (CASSANDRA-17619) diff --git a/NEWS.txt b/NEWS.txt index 68bf9934fc..9f0332c9e1 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -94,7 +94,7 @@ New features - Support for native transport rate limiting via native_transport_rate_limiting_enabled and native_transport_max_requests_per_second in cassandra.yaml. - Support for pre hashing passwords on CQL DCL commands - - Expose all client options via system_views.clients and nodetool clientstats. + - Expose all client options via system_views.clients and nodetool clientstats --client-options. - Support for String concatenation has been added through the + operator. - New configuration max_hints_size_per_host to limit the size of local hints files per host in mebibytes. Setting to non-positive value disables the limit, which is the default behavior. Setting to a positive value to ensure diff --git a/src/java/org/apache/cassandra/tools/nodetool/ClientStats.java b/src/java/org/apache/cassandra/tools/nodetool/ClientStats.java index ecaa5f33b9..7ed9b9d443 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/ClientStats.java +++ b/src/java/org/apache/cassandra/tools/nodetool/ClientStats.java @@ -44,6 +44,9 @@ public class ClientStats extends NodeToolCmd @Option(title = "clear_history", name = "--clear-history", description = "Clear the history of connected clients") private boolean clearConnectionHistory = false; + @Option(title = "list_connections_with_client_options", name = "--client-options", description = "Lists all connections and the client options") + private boolean clientOptions = false; + @Override public void execute(NodeProbe probe) { @@ -84,6 +87,31 @@ public class ClientStats extends NodeToolCmd } if (listConnections) + { + List> clients = (List>) probe.getClientMetric("connections"); + if (!clients.isEmpty()) + { + TableBuilder table = new TableBuilder(); + table.add("Address", "SSL", "Cipher", "Protocol", "Version", "User", "Keyspace", "Requests", "Driver-Name", "Driver-Version"); + for (Map conn : clients) + { + table.add(conn.get(ConnectedClient.ADDRESS), + conn.get(ConnectedClient.SSL), + conn.get(ConnectedClient.CIPHER), + conn.get(ConnectedClient.PROTOCOL), + conn.get(ConnectedClient.VERSION), + conn.get(ConnectedClient.USER), + conn.get(ConnectedClient.KEYSPACE), + conn.get(ConnectedClient.REQUESTS), + conn.get(ConnectedClient.DRIVER_NAME), + conn.get(ConnectedClient.DRIVER_VERSION)); + } + table.printTo(out); + out.println(); + } + } + + if (clientOptions) { List> clients = (List>) probe.getClientMetric("connections"); if (!clients.isEmpty()) diff --git a/test/unit/org/apache/cassandra/tools/nodetool/ClientStatsTest.java b/test/unit/org/apache/cassandra/tools/nodetool/ClientStatsTest.java index 98696299f0..c8a1ae9d13 100644 --- a/test/unit/org/apache/cassandra/tools/nodetool/ClientStatsTest.java +++ b/test/unit/org/apache/cassandra/tools/nodetool/ClientStatsTest.java @@ -70,7 +70,7 @@ public class ClientStatsTest extends CQLTester " [(-pp | --print-port)] [(-pw | --password )]\n" + " [(-pwf | --password-file )]\n" + " [(-u | --username )] clientstats [--all]\n" + - " [--by-protocol] [--clear-history]\n" + + " [--by-protocol] [--clear-history] [--client-options]\n" + "\n" + "OPTIONS\n" + " --all\n" + @@ -82,6 +82,9 @@ public class ClientStatsTest extends CQLTester " --clear-history\n" + " Clear the history of connected clients\n" + "\n" + + " --client-options\n" + + " Lists all connections and the client options\n" + + "\n" + " -h , --host \n" + " Node hostname or ip address\n" + "\n" + @@ -132,6 +135,19 @@ public class ClientStatsTest extends CQLTester ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("clientstats", "--all"); tool.assertOnCleanExit(); String stdout = tool.getStdout(); + assertThat(stdout).containsPattern("Address +SSL +Cipher +Protocol +Version +User +Keyspace +Requests +Driver-Name +Driver-Version"); + assertThat(stdout).containsPattern("/127.0.0.1:[0-9]+ false undefined undefined [0-9]+ +anonymous +[0-9]+ +DataStax Java Driver 3.11.0"); + assertThat(stdout).contains("Total connected clients: 2"); + assertThat(stdout).contains("User Connections"); + assertThat(stdout).contains("anonymous 2"); + } + + @Test + public void testClientStatsClientOptions() + { + ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("clientstats", "--client-options"); + tool.assertOnCleanExit(); + String stdout = tool.getStdout(); assertThat(stdout).containsPattern("Address +SSL +Cipher +Protocol +Version +User +Keyspace +Requests +Driver-Name +Driver-Version +Client-Options"); assertThat(stdout).containsPattern("/127.0.0.1:[0-9]+ false undefined undefined [0-9]+ +anonymous +[0-9]+ +DataStax Java Driver 3.11.0"); assertThat(stdout).containsPattern("DRIVER_NAME=DataStax Java Driver");