From 0435be9eedea4222894914dc836eecb26ebff86e Mon Sep 17 00:00:00 2001 From: Evgenia Badiyanova Date: Tue, 23 Jan 2024 10:47:33 -0500 Subject: [PATCH] show race report --- esrally/metrics.py | 53 +++++++++++++++++++---------- esrally/rally.py | 83 ++++++++++++++++++++++++++++++++++++++------- esrally/reporter.py | 19 ++++++++++- 3 files changed, 124 insertions(+), 31 deletions(-) diff --git a/esrally/metrics.py b/esrally/metrics.py index 61e00d4dd..8e089ca8a 100644 --- a/esrally/metrics.py +++ b/esrally/metrics.py @@ -1332,26 +1332,31 @@ def format_dict(d): ] ) + headers = [ + "Race ID", + "Race Timestamp", + "Track", + "Challenge", + "Car", + "ES Version", + "Revision", + "Rally Version", + "Track Revision", + "Team Revision", + "User Tags" + ] if len(races) > 0: - console.println("\nRecent races:\n") - console.println( - tabulate.tabulate( - races, - headers=[ - "Race ID", - "Race Timestamp", - "Track", - "Challenge", - "Car", - "ES Version", - "Revision", - "Rally Version", - "Track Revision", - "Team Revision", - "User Tags", - ], + if cfg.opts("system", "list.output_format") == "json": + data_rows = [dict(filter(lambda metric: metric[1], dict(zip(headers, race)).items())) for race in races] + console.println(json.dumps(data_rows, indent=2)) + else: + console.println("\nRecent races:\n") + console.println( + tabulate.tabulate( + races, + headers + ) ) - ) else: console.println("") console.println("No recent races found.") @@ -1599,6 +1604,12 @@ def _track(self): def _benchmark_name(self): return self.cfg.opts("system", "list.races.benchmark_name", mandatory=False) + def _revision(self): + return self.cfg.opts("system", "admin.revision", mandatory=False) + + def _env_id(self): + return self.cfg.opts("system", "admin.env_id", mandatory=False) + def _race_timestamp(self): return self.cfg.opts("system", "add.race_timestamp") @@ -1877,6 +1888,8 @@ def delete_race(self): def list(self): track = self._track() + env_id = self._env_id() + revision = self._revision() name = self._benchmark_name() from_date = self._from_date() to_date = self._to_date() @@ -1907,6 +1920,10 @@ def list(self): } if track: query["query"]["bool"]["filter"].append({"term": {"track": track}}) + if env_id: + query["query"]["bool"]["filter"].append({"term": {"user-tags.env-id": env_id}}) + if revision: + query["query"]["bool"]["filter"].append({"term": {"cluster.revision": revision}}) if name: query["query"]["bool"]["filter"].append( {"bool": {"should": [{"term": {"user-tags.benchmark-name": name}}, {"term": {"user-tags.name": name}}]}} diff --git a/esrally/rally.py b/esrally/rally.py index 738826f78..0137c9b6c 100644 --- a/esrally/rally.py +++ b/esrally/rally.py @@ -180,6 +180,13 @@ def add_track_source(subparser): type=valid_date, default=None, ) + list_parser.add_argument( + "--format", + help="Print results as text or json", + choices=["text", "json"], + default="text", + dest="output_format" + ) add_track_source(list_parser) delete_parser = subparsers.add_parser("delete", help="Delete records") @@ -257,6 +264,44 @@ def add_track_source(subparser): help="Track output directory (default: tracks/)", ) + show_parser = subparsers.add_parser("show", help="Show records for a particular race") + show_parser.add_argument( + "--report-format", + help="Define the output format for the command line report (default: markdown).", + choices=["markdown", "csv", "json"], + default="markdown", + ) + show_parser.add_argument( + "--report-numbers-align", + help="Define the output column number alignment for the command line report (default: decimal).", + choices=["right", "center", "left", "decimal"], + default="decimal", + ) + show_parser.add_argument( + "--report-file", + help="Write the command line report also to the provided file.", + default="", + ) + show_parser.add_argument( + "--show-in-report", + help="Whether to include the comparison in the results file.", + default=True, + ) + show_parser.add_argument( + "--race-id", + default=None, + help="Show records for this Race ID. " + ) + show_parser.add_argument( + "--env-id", + default=None, + help="Show records for race with this env-id user tag. " + ) + show_parser.add_argument( + "--revision", + default=None, + help="Show records for races with this revision. " + ) compare_parser = subparsers.add_parser("compare", help="Compare two races") compare_parser.add_argument( "--baseline", @@ -821,6 +866,7 @@ def add_track_source(subparser): add_parser, race_parser, compare_parser, + show_parser, build_parser, download_parser, install_parser, @@ -841,6 +887,12 @@ def add_track_source(subparser): default=False, action="store_true", ) + p.add_argument( + "--output-format", + help="Suppress as much as output as possible (default: false).", + default="text", + action="store_true", + ) p.add_argument( "--offline", help="Assume that Rally has no connection to the Internet (default: false).", @@ -1086,6 +1138,11 @@ def dispatch_sub_command(arg_parser, args, cfg: types.Config): if sub_command == "compare": configure_reporting_params(args, cfg) reporter.compare(cfg, args.baseline, args.contender) + elif sub_command == "show": + configure_reporting_params(args, cfg) + cfg.add(config.Scope.applicationOverride, "system", "admin.env_id", args.env_id) + cfg.add(config.Scope.applicationOverride, "system", "admin.revision", args.revision) + reporter.summarize_by_id(cfg, args.race_id) elif sub_command == "list": cfg.add(config.Scope.applicationOverride, "system", "list.config.option", args.configuration) cfg.add(config.Scope.applicationOverride, "system", "list.max_results", args.limit) @@ -1093,6 +1150,7 @@ def dispatch_sub_command(arg_parser, args, cfg: types.Config): cfg.add(config.Scope.applicationOverride, "system", "list.races.benchmark_name", args.benchmark_name) cfg.add(config.Scope.applicationOverride, "system", "list.from_date", args.from_date) cfg.add(config.Scope.applicationOverride, "system", "list.to_date", args.to_date) + cfg.add(config.Scope.applicationOverride, "system", "list.output_format", args.output_format) configure_mechanic_params(args, cfg, command_requires_car=False) configure_track_params(arg_parser, args, cfg, command_requires_track=False) dispatch_list(cfg) @@ -1238,7 +1296,7 @@ def main(): sys.exit(0) console.init(quiet=args.quiet) - console.println(BANNER) + #console.println(BANNER) cfg = config.Config(config_name=args.configuration_name) if not cfg.config_present(): @@ -1270,17 +1328,18 @@ def _trap(function, path, exc_info): result = dispatch_sub_command(arg_parser, args, cfg) end = time.time() - if result == ExitStatus.SUCCESSFUL: - console.println("") - console.info("SUCCESS (took %d seconds)" % (end - start), overline="-", underline="-") - elif result == ExitStatus.INTERRUPTED: - console.println("") - console.info("ABORTED (took %d seconds)" % (end - start), overline="-", underline="-") - sys.exit(130) - elif result == ExitStatus.ERROR: - console.println("") - console.info("FAILURE (took %d seconds)" % (end - start), overline="-", underline="-") - sys.exit(64) + if args.output_format != "json": + if result == ExitStatus.SUCCESSFUL: + console.println("") + console.info("SUCCESS (took %d seconds)" % (end - start), overline="-", underline="-") + elif result == ExitStatus.INTERRUPTED: + console.println("") + console.info("ABORTED (took %d seconds)" % (end - start), overline="-", underline="-") + sys.exit(130) + elif result == ExitStatus.ERROR: + console.println("") + console.info("FAILURE (took %d seconds)" % (end - start), overline="-", underline="-") + sys.exit(64) if __name__ == "__main__": diff --git a/esrally/reporter.py b/esrally/reporter.py index 73bd7bef9..1444a15e7 100644 --- a/esrally/reporter.py +++ b/esrally/reporter.py @@ -19,11 +19,12 @@ import io import logging import sys +import json from functools import partial import tabulate -from esrally import exceptions, metrics, types +from esrally import exceptions, metrics, types, config from esrally.utils import console, convert from esrally.utils import io as rio @@ -49,6 +50,15 @@ def compare(cfg: types.Config, baseline_id, contender_id): ComparisonReporter(cfg).report(race_store.find_by_race_id(baseline_id), race_store.find_by_race_id(contender_id)) +def summarize_by_id(cfg: types.Config, race_id): + if race_id: + race = metrics.race_store(cfg).find_by_race_id(race_id) + else: + cfg.add(config.Scope.applicationOverride, "system", "list.max_results", 1) + race = metrics.race_store(cfg).list()[0] + SummaryReporter(metrics.GlobalStats(race.results), cfg).report() + + def print_internal(message): console.println(message, logger=logging.getLogger(__name__).info) @@ -62,6 +72,8 @@ def write_single_report(report_file, report_format, cwd, numbers_align, headers, formatter = partial(format_as_markdown, numbers_align=numbers_align) elif report_format == "csv": formatter = format_as_csv + elif report_format == "json": + formatter = format_as_json else: raise exceptions.SystemSetupError("Unknown report format '%s'" % report_format) print_internal(formatter(headers, data_rich)) @@ -87,6 +99,11 @@ def format_as_csv(headers, data): return out.getvalue() +def format_as_json(headers, data): + data_rows = [dict(filter(lambda metric: metric[1] != "", dict(zip(headers, d)).items())) for d in data] + rendered = json.dumps(data_rows, indent=2) + return rendered + "\n" + def disk_usage_fields(stats): return { "inverted index": stats.disk_usage_inverted_index,