From 95e4c484306fa205ecc5bcc26caef258685c791e Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Fri, 15 Apr 2016 10:38:24 -0700 Subject: [PATCH] Add knob for default core output verbosity --- include/grpc/impl/codegen/log.h | 8 +++++ src/core/lib/support/log.c | 30 ++++++++++++++++ src/core/lib/surface/init.c | 2 ++ test/core/support/log_test.c | 62 +++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+) diff --git a/include/grpc/impl/codegen/log.h b/include/grpc/impl/codegen/log.h index 0853350a262..c64b961b80a 100644 --- a/include/grpc/impl/codegen/log.h +++ b/include/grpc/impl/codegen/log.h @@ -38,6 +38,7 @@ #include /* for abort() */ #include +#include #ifdef __cplusplus extern "C" { @@ -61,6 +62,8 @@ typedef enum gpr_log_severity { GPR_LOG_SEVERITY_ERROR } gpr_log_severity; +#define GPR_LOG_VERBOSITY_UNSET -1 + /* Returns a string representation of the log severity */ const char *gpr_log_severity_string(gpr_log_severity severity); @@ -77,6 +80,11 @@ GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, GPRAPI void gpr_log_message(const char *file, int line, gpr_log_severity severity, const char *message); +/* Set global log verbosity */ +GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print); + +GPRAPI void gpr_log_verbosity_init(); + /* Log overrides: applications can use this API to intercept logging calls and use their own implementations */ diff --git a/src/core/lib/support/log.c b/src/core/lib/support/log.c index 04156a5b1fc..cdcd3770455 100644 --- a/src/core/lib/support/log.c +++ b/src/core/lib/support/log.c @@ -31,14 +31,20 @@ * */ +#include +#include #include #include +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" + #include #include extern void gpr_default_log(gpr_log_func_args *args); static gpr_log_func g_log_func = gpr_default_log; +static gpr_atm g_min_severity_to_print = GPR_LOG_VERBOSITY_UNSET; const char *gpr_log_severity_string(gpr_log_severity severity) { switch (severity) { @@ -54,6 +60,8 @@ const char *gpr_log_severity_string(gpr_log_severity severity) { void gpr_log_message(const char *file, int line, gpr_log_severity severity, const char *message) { + if (severity < gpr_atm_acq_load(&g_min_severity_to_print)) return; + gpr_log_func_args lfargs; memset(&lfargs, 0, sizeof(lfargs)); lfargs.file = file; @@ -63,4 +71,26 @@ void gpr_log_message(const char *file, int line, gpr_log_severity severity, g_log_func(&lfargs); } +void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) { + gpr_atm_rel_store(&g_min_severity_to_print, (gpr_atm)min_severity_to_print); +} + +void gpr_log_verbosity_init() { + char *verbosity = gpr_getenv("GRPC_VERBOSITY"); + if (verbosity == NULL) return; + + gpr_log_severity min_severity_to_print = GPR_LOG_VERBOSITY_UNSET; + if (strcmp(verbosity, "DEBUG") == 0) { + min_severity_to_print = GPR_LOG_SEVERITY_DEBUG; + } else if (strcmp(verbosity, "INFO") == 0) { + min_severity_to_print = GPR_LOG_SEVERITY_INFO; + } else if (strcmp(verbosity, "ERROR") == 0) { + min_severity_to_print = GPR_LOG_SEVERITY_ERROR; + } + gpr_free(verbosity); + if ((gpr_atm_acq_load(&g_min_severity_to_print)) == GPR_LOG_VERBOSITY_UNSET) { + gpr_atm_rel_store(&g_min_severity_to_print, (gpr_atm)min_severity_to_print); + } +} + void gpr_set_log_function(gpr_log_func f) { g_log_func = f; } diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c index ec75af6e06f..d4eb2f8ddd9 100644 --- a/src/core/lib/surface/init.c +++ b/src/core/lib/surface/init.c @@ -38,6 +38,7 @@ #include #include +#include #include #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/compress_filter.h" @@ -69,6 +70,7 @@ static gpr_mu g_init_mu; static int g_initializations; static void do_basic_init(void) { + gpr_log_verbosity_init(); gpr_mu_init(&g_init_mu); grpc_register_built_in_plugins(); g_initializations = 0; diff --git a/test/core/support/log_test.c b/test/core/support/log_test.c index b39b0699134..0ae298aa4c0 100644 --- a/test/core/support/log_test.c +++ b/test/core/support/log_test.c @@ -33,16 +33,40 @@ #include +#include #include +#include "src/core/lib/support/env.h" #include "test/core/util/test_config.h" +static bool log_func_reached = false; + static void test_callback(gpr_log_func_args *args) { GPR_ASSERT(0 == strcmp(__FILE__, args->file)); GPR_ASSERT(args->severity == GPR_LOG_SEVERITY_INFO); GPR_ASSERT(0 == strcmp(args->message, "hello 1 2 3")); } +static void test_should_log(gpr_log_func_args *args) { + log_func_reached = true; +} + +static void test_should_not_log(gpr_log_func_args *args) { GPR_ASSERT(false); } + +#define test_log_function_reached(SEVERITY) \ + gpr_set_log_function(test_should_log); \ + log_func_reached = false; \ + gpr_log_message(SEVERITY, "hello 1 2 3"); \ + GPR_ASSERT(log_func_reached); \ + log_func_reached = false; \ + gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3); \ + GPR_ASSERT(log_func_reached); + +#define test_log_function_unreached(SEVERITY) \ + gpr_set_log_function(test_should_not_log); \ + gpr_log_message(SEVERITY, "hello 1 2 3"); \ + gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3); + int main(int argc, char **argv) { grpc_test_init(argc, argv); /* test logging at various verbosity levels */ @@ -54,6 +78,44 @@ int main(int argc, char **argv) { gpr_set_log_function(test_callback); gpr_log_message(GPR_INFO, "hello 1 2 3"); gpr_log(GPR_INFO, "hello %d %d %d", 1, 2, 3); + + /* gpr_log_verbosity_init() will be effective only once, and only before + * gpr_set_log_verbosity() is called */ + gpr_setenv("GRPC_VERBOSITY", "ERROR"); + gpr_log_verbosity_init(); + test_log_function_reached(GPR_ERROR); + test_log_function_unreached(GPR_INFO); + test_log_function_unreached(GPR_DEBUG); + + /* gpr_log_verbosity_init() should not be effective */ + gpr_setenv("GRPC_VERBOSITY", "DEBUG"); + gpr_log_verbosity_init(); + test_log_function_reached(GPR_ERROR); + test_log_function_unreached(GPR_INFO); + test_log_function_unreached(GPR_DEBUG); + + gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); + test_log_function_reached(GPR_ERROR); + test_log_function_reached(GPR_INFO); + test_log_function_reached(GPR_DEBUG); + + gpr_set_log_verbosity(GPR_LOG_SEVERITY_INFO); + test_log_function_reached(GPR_ERROR); + test_log_function_reached(GPR_INFO); + test_log_function_unreached(GPR_DEBUG); + + gpr_set_log_verbosity(GPR_LOG_SEVERITY_ERROR); + test_log_function_reached(GPR_ERROR); + test_log_function_unreached(GPR_INFO); + test_log_function_unreached(GPR_DEBUG); + + /* gpr_log_verbosity_init() should not be effective */ + gpr_setenv("GRPC_VERBOSITY", "DEBUG"); + gpr_log_verbosity_init(); + test_log_function_reached(GPR_ERROR); + test_log_function_unreached(GPR_INFO); + test_log_function_unreached(GPR_DEBUG); + /* TODO(ctiller): should we add a GPR_ASSERT failure test here */ return 0; }