From 041ad717a554559e12d56876763c5e1ecc73a653 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Sun, 8 Jul 2018 16:47:38 -0400 Subject: [PATCH] bees: configurable log verbosity Log messages were already labelled with log levels, but there was no way to filter by log level at run time. Implement the filter inside the bees process so it can skip evaluation of the BEESLOG* arguments if the log messages would not be emitted. Fixes: https://github.com/Zygo/bees/issues/67 Signed-off-by: Zygo Blaxell --- README.md | 2 ++ src/bees.cc | 52 +++++++++++++++++++++++++++++++++------------------- src/bees.h | 13 +++++++------ 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index c7e8350..d7bad82 100644 --- a/README.md +++ b/README.md @@ -561,6 +561,8 @@ Command Line Options * --strip-paths (-P) * Paths in log output will have the working directory at Bees startup stripped. +* --verbose (-v) + * Set log verbosity (0 = no output, 8 = all output, default 8). Bug Reports and Contributions diff --git a/src/bees.cc b/src/bees.cc index d38392e..b32683b 100644 --- a/src/bees.cc +++ b/src/bees.cc @@ -30,6 +30,8 @@ using namespace crucible; using namespace std; +int bees_log_level = 8; + int do_cmd_help(char *argv[]) { @@ -48,6 +50,7 @@ do_cmd_help(char *argv[]) "\t-T, --no-timestamps\tOmit timestamps in log output\n" "\t-p, --absolute-paths\tShow absolute paths (default)\n" "\t-P, --strip-paths\tStrip $CWD from beginning of all paths in the log\n" + "\t-v, --verbose\tSet maximum log level (0..8, default 8)\n" "\n" "Optional environment variables:\n" "\tBEESHOME\tPath to hash table and configuration files\n" @@ -655,43 +658,54 @@ bees_main(int argc, char *argv[]) while (1) { int option_index = 0; static struct option long_options[] = { - { "thread-count", required_argument, NULL, 'c' }, { "thread-factor", required_argument, NULL, 'C' }, - { "scan-mode", required_argument, NULL, 'm' }, - { "timestamps", no_argument, NULL, 't' }, - { "no-timestamps", no_argument, NULL, 'T' }, - { "absolute-paths", no_argument, NULL, 'p' }, { "strip-paths", no_argument, NULL, 'P' }, - { "help", no_argument, NULL, 'h' } + { "no-timestamps", no_argument, NULL, 'T' }, + { "thread-count", required_argument, NULL, 'c' }, + { "help", no_argument, NULL, 'h' }, + { "scan-mode", required_argument, NULL, 'm' }, + { "absolute-paths", no_argument, NULL, 'p' }, + { "timestamps", no_argument, NULL, 't' }, + { "verbose", required_argument, NULL, 'v' }, }; - c = getopt_long(argc, argv, "c:C:m:TtPph", long_options, &option_index); + c = getopt_long(argc, argv, "C:PTc:hm:ptv:", long_options, &option_index); if (-1 == c) { break; } switch (c) { - case 'c': - thread_count = stoul(optarg); - break; + case 'C': thread_factor = stod(optarg); break; - case 'm': - BeesRoots::set_scan_mode(static_cast(stoul(optarg))); - break; - case 'T': - chatter_prefix_timestamp = false; - break; - case 't': - chatter_prefix_timestamp = true; - break; case 'P': crucible::set_relative_path(cwd); break; + case 'T': + chatter_prefix_timestamp = false; + break; + case 'c': + thread_count = stoul(optarg); + break; + case 'm': + BeesRoots::set_scan_mode(static_cast(stoul(optarg))); + break; case 'p': crucible::set_relative_path(""); break; + case 't': + chatter_prefix_timestamp = true; + break; + case 'v': + { + int new_log_level = stoul(optarg); + THROW_CHECK1(out_of_range, new_log_level, new_log_level >= 0 || new_log_level <= 8); + bees_log_level = new_log_level; + BEESLOGNOTICE("log level set to " << bees_log_level); + } + break; + case 'h': do_cmd_help(argv); // fallthrough default: diff --git a/src/bees.h b/src/bees.h index 14cb1ce..da87d88 100644 --- a/src/bees.h +++ b/src/bees.h @@ -127,18 +127,18 @@ const int FLAGS_OPEN_FANOTIFY = O_RDWR | O_NOATIME | O_CLOEXEC | O_LARGEFILE; // macros ---------------------------------------- -#define BEESLOG(lv,x) do { Chatter c(lv, BeesNote::get_name()); c << x; } while (0) +#define BEESLOG(lv,x) do { if (lv < bees_log_level) { Chatter c(lv, BeesNote::get_name()); c << x; } } while (0) #define BEESLOGTRACE(x) do { BEESLOG(LOG_DEBUG, x); BeesTracer::trace_now(); } while (0) #define BEESTRACE(x) BeesTracer SRSLY_WTF_C(beesTracer_, __LINE__) ([&]() { BEESLOG(LOG_ERR, x); }) #define BEESTOOLONG(x) BeesTooLong SRSLY_WTF_C(beesTooLong_, __LINE__) ([&](ostream &_btl_os) { _btl_os << x; }) #define BEESNOTE(x) BeesNote SRSLY_WTF_C(beesNote_, __LINE__) ([&](ostream &_btl_os) { _btl_os << x; }) -#define BEESLOGERR(x) BEESLOG(LOG_ERR, x) -#define BEESLOGWARN(x) BEESLOG(LOG_WARNING, x) -#define BEESLOGNOTE(x) BEESLOG(LOG_NOTICE, x) -#define BEESLOGINFO(x) BEESLOG(LOG_INFO, x) -#define BEESLOGDEBUG(x) BEESLOG(LOG_DEBUG, x) +#define BEESLOGERR(x) BEESLOG(LOG_ERR, x) +#define BEESLOGWARN(x) BEESLOG(LOG_WARNING, x) +#define BEESLOGNOTICE(x) BEESLOG(LOG_NOTICE, x) +#define BEESLOGINFO(x) BEESLOG(LOG_INFO, x) +#define BEESLOGDEBUG(x) BEESLOG(LOG_DEBUG, x) #define BEESCOUNT(stat) do { \ BeesStats::s_global.add_count(#stat); \ @@ -825,6 +825,7 @@ public: }; // And now, a giant pile of extern declarations +extern int bees_log_level; extern const char *BEES_VERSION; string pretty(double d); void bees_sync(int fd);