German Capuano
German Capuano

Reputation: 5403

How to force black and white output in google benchmark

I'm using google benchmark in Xcode and it's producing colored output for some reason. Since Xcode doesn't seem to support colored output I'm seeing undesired symbols. I was wondering if it is possible to force black and white output in google benchmark. I prefer answers that use their API but I'm open to other alternatives.

Upvotes: 6

Views: 1209

Answers (1)

osgx
osgx

Reputation: 94255

Color output of Google Benchmark is mentioned in their Readme: https://github.com/google/benchmark#output-formats

Output Formats

The library supports multiple output formats. Use the --benchmark_format=<console|json|csv> flag to set the format type. console is the default format.

The Console format is intended to be a human readable format. By default the format generates color output. Context is output on stderr and the tabular data on stdout.

There is also option to save non-colored copy of output to file with --benchmark_out=file --benchmark_out_format=console (default is json)

The library supports writing the output of the benchmark to a file specified by --benchmark_out=<filename>. The format of the output can be specified using --benchmark_out_format={json|console|csv}. Specifying --benchmark_out does not suppress the console output.

And in implementation they have the flag to disable console coloring:

https://github.com/google/benchmark/blob/a271c36af93c7a3b19dfeb2aefa9ca77a58e52e4/src/benchmark.cc#L87

 DEFINE_string(benchmark_color, "auto",
          "Whether to use colors in the output.  Valid values: "
          "'true'/'yes'/1, 'false'/'no'/0, and 'auto'. 'auto' means to use "
          "colors if the output is being sent to a terminal and the TERM "
          "environment variable is set to a terminal type that supports "
          "colors.");

So, you can use --benchmark_color=false as suggested by Artemy (using wrapper shell script), or try to pass console output with "useless cat pattern":

 ./program | cat

It should set stdout to fail isatty() check in auto-color default mode (this trick works to disable color grep).

Or change your TERM env variable with export TERM=ansi to indicate that you have green-and-black CRT monitor: https://github.com/google/benchmark/blob/09b93ccc6a9aed84c269b6f5b8130c878e518ebb/src/colorprint.cc#L167

  //                 ... This list of
  // supported TERM values is copied from Google Test:
  // <https://github.com/google/googletest/blob/master/googletest/src/gtest.cc#L2925>.
  const char* const SUPPORTED_TERM_VALUES[] = {
      "xterm",         "xterm-color",     "xterm-256color",
      "screen",        "screen-256color", "tmux",
      "tmux-256color", "rxvt-unicode",    "rxvt-unicode-256color",
      "linux",         "cygwin",
};

But with |cat and export TERM=ansi gbench continues to generate color. It must be a bug (!!!) near GetOutputOptions, making IsColorTerminal() logic a noop in case of "auto", so "auto" mode is not really auto it is always enable:

ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {
  int output_opts = ConsoleReporter::OO_Defaults;
  if ((FLAGS_benchmark_color == "auto" && IsColorTerminal()) ||
      IsTruthyFlagValue(FLAGS_benchmark_color)) {
    output_opts |= ConsoleReporter::OO_Color;
  } else {
    output_opts &= ~ConsoleReporter::OO_Color;
}

The IsTruthyFlagValue considers default value "auto" as true, and always enables color output, even when terminal does not support it!

bool IsTruthyFlagValue(const std::string& value) {
  if (value.empty()) return true;
  char ch = value[0];
  return isalnum(ch) &&
         !(ch == '0' || ch == 'f' || ch == 'F' || ch == 'n' || ch == 'N');
}   

Here is the patch to enable auto mode (will work with |cat and TERM=ansi ./program and probably with some IDEs which correctly sets TERM), fell free to do pull request:

--- a/src/benchmark.cc
+++ b/src/benchmark.cc
@@ -555,7 +555,8 @@ bool IsZero(double n) {
 ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {
   int output_opts = ConsoleReporter::OO_Defaults;
   if ((FLAGS_benchmark_color == "auto" && IsColorTerminal()) ||
-      IsTruthyFlagValue(FLAGS_benchmark_color)) {
+      (FLAGS_benchmark_color != "auto" &&
+       IsTruthyFlagValue(FLAGS_benchmark_color))) {
     output_opts |= ConsoleReporter::OO_Color;
   } else {
     output_opts &= ~ConsoleReporter::OO_Color;

Upvotes: 3

Related Questions