Skip to content

Commit e9645ac

Browse files
excelle08meta-codesync[bot]
authored andcommitted
Only send final JSON benchmark result to stdout, move others to stderr (#247)
Summary: Pull Request resolved: #247 In Benchpress's run command, let's only print the final benchmark result report (in JSON) to stdout and redirect all other messages to stderr and/or benchpress.log. This will enable other scripts to easily extract and parse the results. Reviewed By: charles-typ Differential Revision: D84308887 fbshipit-source-id: 41f1b60ae6aa42c0de254d8eeb5f33082e1adfd7
1 parent 2e08c9a commit e9645ac

7 files changed

Lines changed: 22 additions & 18 deletions

File tree

benchpress/cli/commands/run.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def run(self, args, jobs) -> None:
119119

120120
jobs = get_target_jobs(jobs, args.jobs).values()
121121

122-
click.echo("Will run {} job(s)".format(len(jobs)))
122+
logger.info("Will run {} job(s)".format(len(jobs)))
123123

124124
history = History(args.results)
125125
now = datetime.now(timezone.utc)
@@ -184,18 +184,19 @@ def run(self, args, jobs) -> None:
184184
try:
185185
role_in = json.loads(args.role_input)
186186
except Exception:
187-
click.echo("role_input must be json dictionary format")
188-
click.echo("example input format for iperf:")
187+
click.echo("role_input must be json dictionary format", err=True)
188+
click.echo("example input format for iperf:", err=True)
189189
click.echo(
190-
'./benchpress run iperf --role client --role_input=\'{"server_hostname":"rtptest1234.prn1"}\''
190+
'./benchpress run iperf --role client --role_input=\'{"server_hostname":"rtptest1234.prn1"}\'',
191+
err=True,
191192
)
192193
exit(1)
193194

194195
for job in jobs:
195196
if not verify_install(job.install_script):
196-
click.echo("Benchmark {} not installed".format(job.name))
197+
logger.error("Benchmark {} not installed".format(job.name))
197198
continue
198-
click.echo('Running "{}": {}'.format(job.name, job.description))
199+
click.echo('Running "{}": {}'.format(job.name, job.description), err=True)
199200

200201
if args.dry_run:
201202
job_cmd = job.dry_run(args.role, role_in)
@@ -218,7 +219,7 @@ def run(self, args, jobs) -> None:
218219
job.hooks.append((hook, HookFactory.create(hook), hook_opts))
219220

220221
if args.disable_hooks:
221-
click.echo("Hooks globally disabled as requested")
222+
logger.warning("Hooks globally disabled as requested")
222223
else:
223224
job.start_hooks()
224225
metrics_dir = f"benchmark_metrics_{job.uuid}"
@@ -254,7 +255,7 @@ def run(self, args, jobs) -> None:
254255

255256
final_metrics["metrics"] = metrics
256257
stdout_reporter = ReporterFactory.create("stdout")
257-
click.echo("Results Report:")
258+
click.echo("Results Report:", err=True)
258259
stdout_reporter.report(job, final_metrics)
259260

260261
json_reporter.report(job, final_metrics)
@@ -265,7 +266,8 @@ def run(self, args, jobs) -> None:
265266
click.echo(
266267
'Finished running "{}": {} with uuid: {}'.format(
267268
job.name, job.description, job.uuid
268-
)
269+
),
270+
err=True,
269271
)
270272

271273
json_reporter.close()

benchpress/cli/main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ def parse_override_job_args(override_job_args):
240240
(
241241
"Could not properly parse --override_job_args flag. "
242242
"Run ./automark exec -h to see an example of what to pass in."
243-
)
243+
),
244+
err=True,
244245
)
245246
raise
246247

benchpress/lib/job.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def get_file_based_cmd(self, role=None, role_input=None, fp=None):
205205
"""Dump the run command in a file and execute it."""
206206
logger.info('Starting "{}"'.format(self.name))
207207
cmd = self.dry_run(role, role_input)
208-
click.echo("Job execution command: {}".format(cmd))
208+
click.echo("Job execution command: {}".format(cmd), err=True)
209209
# add string to cmd so that it dumps the stdout and strerr to different files
210210
# cmd = cmd + " > benchpress_run_output.txt 2> benchpress_run_error.txt"
211211

@@ -237,7 +237,7 @@ def run(self, role=None, role_input=None):
237237
)
238238
else:
239239
cmd = get_safe_cmd([self.binary] + self.args)
240-
click.echo("Job execution command: {}".format(cmd))
240+
click.echo("Job execution command: {}".format(cmd), err=True)
241241
process = subprocess.Popen(
242242
cmd,
243243
stdout=subprocess.PIPE,
@@ -343,7 +343,7 @@ def _print_output_summary(self, stdout, stderr):
343343
if len(stderr) > TRIM_OUTPUT_LINES:
344344
output += f"\n[...trimmed to last {TRIM_OUTPUT_LINES} lines...]\n"
345345
output += "\t{}".format("\n\t".join(stderr[-TRIM_OUTPUT_LINES:]))
346-
click.echo(output)
346+
click.echo(output, err=True)
347347

348348

349349
class JobSuiteBuilder:

benchpress/plugins/hooks/perf_monitors/topdown.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,12 +457,12 @@ def install_if_not_available(self):
457457
return False
458458
subprocess.run(["topdown-tool", "--help"], capture_output=True, check=True)
459459
except subprocess.CalledProcessError as e:
460-
print(
460+
logger.warning(
461461
f"Failed to install topdown-tool. Command: {e.cmd}, exit code: {e.returncode}"
462462
)
463463
return False
464464
except OSError:
465-
print("Unable to chdir telemetry-solution/tools/topdown_tool")
465+
logger.warning("Unable to chdir telemetry-solution/tools/topdown_tool")
466466
return False
467467
return True
468468

benchpress/plugins/parsers/clang.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
# LICENSE file in the root directory of this source tree.
55

66
# pyre-unsafe
7+
import logging
78
import re
89

910
from benchpress.lib.parser import Parser
1011

12+
logger = logging.getLogger(__name__)
13+
1114

1215
class ClangParser(Parser):
1316
def parse(self, stdout, stderr, returncode):
@@ -65,6 +68,6 @@ def try_parse_time(self, line: str) -> float:
6568
minute = int(m.group(1))
6669
second = float(m.group(2))
6770
except ValueError:
68-
print("Failed to parse clang build time")
71+
logger.error("Failed to parse clang build time")
6972
return -1
7073
return minute * 60 + second

benchpress/plugins/parsers/multichase_pointer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,4 @@ def parse(self, stdout, stderr, returncode):
6060
key = key + " thread count " + thread_count
6161
key = key + " latency (ns)"
6262
metrics[key] = float(v.strip())
63-
print("metrics", metrics)
6463
return metrics

benchpress/plugins/parsers/small_locks_bench.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,4 @@ def parse(self, stdout, stderr, returncode):
3333
metrics[lock_name + " stddev in us"] = float(stddev_val)
3434
max_val = re.findall(REGEX_VAL_AFTER_MAX, line)[0]
3535
metrics[lock_name + " max in us"] = float(max_val)
36-
print(metrics)
3736
return metrics

0 commit comments

Comments
 (0)