diff --git a/CHANGES.txt b/CHANGES.txt index c207f7bfb2..a4ec2293d5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 5.1 + * Add ELAPSED command to cqlsh (CASSANDRA-18861) * Add the ability to disable bulk loading of SSTables (CASSANDRA-18781) * Clean up obsolete functions and simplify cql_version handling in cqlsh (CASSANDRA-18787) Merged from 5.0: diff --git a/doc/modules/cassandra/pages/managing/tools/cqlsh.adoc b/doc/modules/cassandra/pages/managing/tools/cqlsh.adoc index 70b8846009..0afa06dba5 100644 --- a/doc/modules/cassandra/pages/managing/tools/cqlsh.adoc +++ b/doc/modules/cassandra/pages/managing/tools/cqlsh.adoc @@ -322,6 +322,35 @@ EXPAND ON EXPAND OFF ---- +=== `ELAPSED` + +Enables or disables the printing of the elapsed time for a query. Except a quick evalution +of how long a CQL statement took, this is also a complementary output to `TRACING` (if enabled). +A user can debug if there is a communication delay to a node or not comparing the timestamps as `TRACING` tracks +the time elapsed only on the server side. + +`Usage`: + +[source,none] +---- +cqlsh> ELAPSED ON +ELAPSED set to ON +cqlsh> select * from myks.mytb limit 5; + + id | age +----+----- + 5 | 10 + 10 | 10 + 11 | 10 + 1 | 10 + 8 | 10 + +(5 rows) +(6ms elapsed) +cqlsh> DROP KEYSPACE myks ; +(510ms elapsed) +---- + === `LOGIN` Authenticate as a specified Cassandra user for the current session. diff --git a/pylib/cqlshlib/cqlshhandling.py b/pylib/cqlshlib/cqlshhandling.py index e6a121fd80..ad515e63c0 100644 --- a/pylib/cqlshlib/cqlshhandling.py +++ b/pylib/cqlshlib/cqlshhandling.py @@ -33,6 +33,7 @@ my_commands_ending_with_newline = ( 'debug', 'tracing', 'expand', + 'elapsed', 'paging', 'exit', 'quit', @@ -71,6 +72,7 @@ cqlsh_special_cmd_command_syntax_rules = r''' | | | + | | | | @@ -194,6 +196,11 @@ cqlsh_paging_cmd_syntax_rules = r''' ; ''' +cqlsh_elapsed_cmd_syntax_rules = r''' + ::= "ELAPSED" ( switch=( "ON" | "OFF" ) )? + ; +''' + cqlsh_login_cmd_syntax_rules = r''' ::= "LOGIN" username= (password=)? ; @@ -236,6 +243,7 @@ cqlsh_extra_syntax_rules = cqlsh_cmd_syntax_rules + \ cqlsh_tracing_cmd_syntax_rules + \ cqlsh_expand_cmd_syntax_rules + \ cqlsh_paging_cmd_syntax_rules + \ + cqlsh_elapsed_cmd_syntax_rules + \ cqlsh_login_cmd_syntax_rules + \ cqlsh_exit_cmd_syntax_rules + \ cqlsh_clear_cmd_syntax_rules + \ diff --git a/pylib/cqlshlib/cqlshmain.py b/pylib/cqlshlib/cqlshmain.py index 1c47af576e..be3465035a 100755 --- a/pylib/cqlshlib/cqlshmain.py +++ b/pylib/cqlshlib/cqlshmain.py @@ -23,6 +23,7 @@ import os import re import subprocess import sys +import time import traceback import warnings import webbrowser @@ -329,7 +330,7 @@ class Shell(cmd.Cmd): default_page_size = 100 def __init__(self, hostname, port, color=False, - username=None, encoding=None, stdin=None, tty=True, + username=None, encoding=None, elapsed_enabled=False, stdin=None, tty=True, completekey=DEFAULT_COMPLETEKEY, browser=None, use_conn=None, cqlver=None, keyspace=None, tracing_enabled=False, expand_enabled=False, @@ -412,6 +413,7 @@ class Shell(cmd.Cmd): self.tty = tty self.encoding = encoding + self.elapsed_enabled = elapsed_enabled self.output_codec = codecs.lookup(encoding) @@ -970,6 +972,7 @@ class Shell(cmd.Cmd): if not statement: return False, None + start_time = time.time() future = self.session.execute_async(statement, trace=self.tracing_enabled) result = None try: @@ -990,6 +993,8 @@ class Shell(cmd.Cmd): "nodes in system.local and system.peers.") self.conn.refresh_schema_metadata(-1) + elapsed = int((time.time() - start_time) * 1000) + if result is None: return False, None @@ -1003,6 +1008,8 @@ class Shell(cmd.Cmd): # CAS INSERT/UPDATE self.writeresult("") self.print_static_result(result, self.parse_for_update_meta(statement.query_string), with_header=True, tty=self.tty) + if self.elapsed_enabled: + self.writeresult("(%dms elapsed)" % elapsed) self.flush_output() return True, future @@ -1551,7 +1558,8 @@ class Shell(cmd.Cmd): return subshell = Shell(self.hostname, self.port, color=self.color, username=self.username, - encoding=self.encoding, stdin=f, tty=False, use_conn=self.conn, + encoding=self.encoding, elapsed_enabled=self.elapsed_enabled, + stdin=f, tty=False, use_conn=self.conn, cqlver=self.cql_version, keyspace=self.current_keyspace, tracing_enabled=self.tracing_enabled, display_nanotime_format=self.display_nanotime_format, @@ -1656,6 +1664,22 @@ class Shell(cmd.Cmd): self.tracing_enabled \ = self.on_off_switch("TRACING", self.tracing_enabled, parsed.get_binding('switch')) + def do_elapsed(self, parsed): + """ + ELAPSED + + Returns whether displaying of elapsed time for each CQL query is enabled or not + + ELAPSED ON + + Enables displaying of elapsed time for each CQL query + + ELAPSED OFF + + Disables displaying of elapsed time for each CQL query + """ + self.elapsed_enabled = self.on_off_switch("ELAPSED", self.elapsed_enabled, parsed.get_binding('switch')) + def do_expand(self, parsed): """ EXPAND [cqlsh] diff --git a/pylib/cqlshlib/test/test_cqlsh_completion.py b/pylib/cqlshlib/test/test_cqlsh_completion.py index db59297a97..2d01bdb0ae 100644 --- a/pylib/cqlshlib/test/test_cqlsh_completion.py +++ b/pylib/cqlshlib/test/test_cqlsh_completion.py @@ -163,7 +163,7 @@ class TestCqlshCompletion(CqlshCompletionCase): self.trycompletions('', choices=('?', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY', 'COPY', 'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE', 'DROP', 'GRANT', 'HELP', 'INSERT', 'LIST', 'LOGIN', 'PAGING', 'REVOKE', - 'SELECT', 'SHOW', 'SOURCE', 'TRACING', 'EXPAND', 'SERIAL', 'TRUNCATE', + 'SELECT', 'SHOW', 'SOURCE', 'TRACING', 'ELAPSED', 'EXPAND', 'SERIAL', 'TRUNCATE', 'UPDATE', 'USE', 'exit', 'quit', 'CLEAR', 'CLS', 'history')) def test_complete_command_words(self): @@ -248,7 +248,7 @@ class TestCqlshCompletion(CqlshCompletionCase): "VALUES ( 'eggs', 'sausage', 'spam');"), choices=['?', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY', 'COPY', 'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE', 'DROP', - 'EXPAND', 'GRANT', 'HELP', 'INSERT', 'LIST', 'LOGIN', 'PAGING', + 'ELAPSED', 'EXPAND', 'GRANT', 'HELP', 'INSERT', 'LIST', 'LOGIN', 'PAGING', 'REVOKE', 'SELECT', 'SHOW', 'SOURCE', 'SERIAL', 'TRACING', 'TRUNCATE', 'UPDATE', 'USE', 'exit', 'history', 'quit', 'CLEAR', 'CLS'])