From 88218ee21de591aca2cad80da482c33bab39283b Mon Sep 17 00:00:00 2001 From: Roberto Scolaro Date: Fri, 31 May 2024 10:30:33 +0000 Subject: [PATCH 1/2] feat(sysdig): implement NO_COLOR standard Signed-off-by: Roberto Scolaro --- userspace/sysdig/sysdig.cpp | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/userspace/sysdig/sysdig.cpp b/userspace/sysdig/sysdig.cpp index a82d34195c..28a4096dbc 100644 --- a/userspace/sysdig/sysdig.cpp +++ b/userspace/sysdig/sysdig.cpp @@ -290,6 +290,7 @@ static void usage() " -M Stop collecting after reached.\n" " -n , --numevents=\n" " Stop capturing after events\n" +" --no-color Avoid using colors on terminal output.\n" " --page-faults Capture user/kernel major/minor page faults\n" " --plugin-config-file\n" " Load the plugin configuration from a Falco-compatible yaml file.\n" @@ -1037,6 +1038,7 @@ sysdig_init_res sysdig_init(int argc, char **argv) sinsp_opener opener; std::unique_ptr filter_list; std::shared_ptr filter_factory; + bool no_color_flag = false; // These variables are for the cycle_writer engine int duration_seconds = 0; @@ -1110,22 +1112,10 @@ sysdig_init_res sysdig_init(int argc, char **argv) {"print-hex", no_argument, 0, 'x'}, {"print-hex-ascii", no_argument, 0, 'X'}, {"compress", no_argument, 0, 'z' }, + {"no-color", no_argument, 0, 0 }, {0, 0, 0, 0} }; -#ifndef _WIN32 - if (isatty(fileno(stdout))) - { - output_format = R"(*%evt.num %evt.outputtime %evt.cpu \e[01;32m%proc.name\e[00m (\e[01;36m%proc.pid\e[00m.%thread.tid) %evt.dir \e[01;34m%evt.type\e[00m %evt.info)"; - output_format_plugin = R"(*%evt.num %evt.datetime.s [\e[01;32m%evt.pluginname\e[00m] %evt.plugininfo)"; - } - else -#endif - { - output_format = "*%evt.num %evt.outputtime %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info"; - output_format_plugin = "*%evt.num %evt.datetime.s [%evt.pluginname] %evt.plugininfo"; - } - try { inspector.reset(new sinsp()); @@ -1640,6 +1630,11 @@ sysdig_init_res sysdig_init(int argc, char **argv) plugins.print_plugin_info(inspector.get(), filter_list.get(), name); return sysdig_init_res(EXIT_SUCCESS); } + + else if (optname == "no-color") + { + no_color_flag = true; + } } break; // getopt_long : '?' for an ambiguous match or an extraneous parameter @@ -1651,6 +1646,21 @@ sysdig_init_res sysdig_init(int argc, char **argv) } } +#ifndef _WIN32 + char* no_color = getenv("NO_COLOR"); + if (isatty(fileno(stdout)) && + (no_color != nullptr && strcmp(no_color, "1") != 0) && !no_color_flag) + { + output_format = R"(*%evt.num %evt.outputtime %evt.cpu \e[01;32m%proc.name\e[00m (\e[01;36m%proc.pid\e[00m.%thread.tid) %evt.dir \e[01;34m%evt.type\e[00m %evt.info)"; + output_format_plugin = R"(*%evt.num %evt.datetime.s [\e[01;32m%evt.pluginname\e[00m] %evt.plugininfo)"; + } + else +#endif + { + output_format = "*%evt.num %evt.outputtime %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info"; + output_format_plugin = "*%evt.num %evt.datetime.s [%evt.pluginname] %evt.plugininfo"; + } + // given the CLI options, we finish loading and initializing plugins. // if no plugin has been specified as input with -I, we try to // reload the config file (if present), and set the input plugin From 3f0336ecda7e5af8aee475e2aefd2ce662e78029 Mon Sep 17 00:00:00 2001 From: Roberto Scolaro Date: Tue, 4 Jun 2024 08:26:45 +0000 Subject: [PATCH 2/2] fix(sysdig): address review comments Signed-off-by: Roberto Scolaro --- userspace/sysdig/sysdig.cpp | 51 +++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/userspace/sysdig/sysdig.cpp b/userspace/sysdig/sysdig.cpp index 28a4096dbc..151a70459e 100644 --- a/userspace/sysdig/sysdig.cpp +++ b/userspace/sysdig/sysdig.cpp @@ -72,6 +72,12 @@ static std::atomic g_plugin_input = false; std::vector g_chisels; #endif +enum color_term_out { + COLOR = 0, + NO_COLOR, + FORCE_COLOR +}; + static void usage(); // @@ -290,7 +296,8 @@ static void usage() " -M Stop collecting after reached.\n" " -n , --numevents=\n" " Stop capturing after events\n" -" --no-color Avoid using colors on terminal output.\n" +" --color \n" +" Set colors settings on terminal output.\n" " --page-faults Capture user/kernel major/minor page faults\n" " --plugin-config-file\n" " Load the plugin configuration from a Falco-compatible yaml file.\n" @@ -962,6 +969,15 @@ void disable_tty_echo() { } #endif +static inline bool stdout_supports_color() +{ +#ifdef _WIN32 + return false; +#else + return isatty(fileno(stdout)); +#endif +} + std::string escape_output_format(const std::string& s) { std::stringstream ss{""}; @@ -1038,7 +1054,7 @@ sysdig_init_res sysdig_init(int argc, char **argv) sinsp_opener opener; std::unique_ptr filter_list; std::shared_ptr filter_factory; - bool no_color_flag = false; + color_term_out color_flag = COLOR; // These variables are for the cycle_writer engine int duration_seconds = 0; @@ -1112,7 +1128,7 @@ sysdig_init_res sysdig_init(int argc, char **argv) {"print-hex", no_argument, 0, 'x'}, {"print-hex-ascii", no_argument, 0, 'X'}, {"compress", no_argument, 0, 'z' }, - {"no-color", no_argument, 0, 0 }, + {"color", required_argument, 0, 0 }, {0, 0, 0, 0} }; @@ -1631,9 +1647,26 @@ sysdig_init_res sysdig_init(int argc, char **argv) return sysdig_init_res(EXIT_SUCCESS); } - else if (optname == "no-color") + else if (optname == "color") { - no_color_flag = true; + auto color_state = std::string(optarg); + if (color_state == "true") + { + color_flag = COLOR; + } + else if (color_state == "force") + { + color_flag = FORCE_COLOR; + } + else if (color_state == "false") + { + color_flag = NO_COLOR; + } + else + { + fprintf(stderr, "invalid color mode for flag --color\n"); + return sysdig_init_res(EXIT_FAILURE); + } } } break; @@ -1646,16 +1679,14 @@ sysdig_init_res sysdig_init(int argc, char **argv) } } -#ifndef _WIN32 - char* no_color = getenv("NO_COLOR"); - if (isatty(fileno(stdout)) && - (no_color != nullptr && strcmp(no_color, "1") != 0) && !no_color_flag) + char* no_color_env = getenv("NO_COLOR"); + if ((color_flag == FORCE_COLOR) || + (stdout_supports_color() && (no_color_env != nullptr && no_color_env[0] != '\0') && color_flag == COLOR)) { output_format = R"(*%evt.num %evt.outputtime %evt.cpu \e[01;32m%proc.name\e[00m (\e[01;36m%proc.pid\e[00m.%thread.tid) %evt.dir \e[01;34m%evt.type\e[00m %evt.info)"; output_format_plugin = R"(*%evt.num %evt.datetime.s [\e[01;32m%evt.pluginname\e[00m] %evt.plugininfo)"; } else -#endif { output_format = "*%evt.num %evt.outputtime %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info"; output_format_plugin = "*%evt.num %evt.datetime.s [%evt.pluginname] %evt.plugininfo";