From 8adaa0478a94b5f731ee77e12a8dac29e3a7b46a Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Wed, 5 Jan 2011 11:04:49 -0800 Subject: [PATCH] common: make command-line programs log to stderr command-line programs (as opposed to daemons) should send their logs to stderr rather than to a log file, syslog, etc. This is especially important because most users want to run the ceph command-line programs as non-root, and often only root has permissions to add to the ceph log directory. Create a new function, set_foreground_logging, that overrides ceph.conf settings to force all log output to stderr. For daemons, we still only send the very highest priority messages to stderr, and only before they daemonize(). Don't ever log to stdout because it interferes with scripts that parse the output of stdout. Instead, log to stderr if the user gives the --foreground or --nodaemon argument. Signed-off-by: Colin McCabe --- src/cauthtool.cc | 1 + src/cconf.cc | 1 + src/common/DoutStreambuf.cc | 35 ++++++++++++++++------------------ src/common/DoutStreambuf.h | 9 ++++----- src/common/common_init.cc | 34 +++++++++++++++++++++++++++++++++ src/common/common_init.h | 1 + src/common/debug.cc | 11 ++++++----- src/common/debug.h | 4 ++-- src/config.cc | 14 +++++++++----- src/config.h | 10 ++++++++-- src/crushtool.cc | 2 ++ src/csyn.cc | 1 + src/dumpjournal.cc | 1 + src/dupstore.cc | 1 + src/fakefuse.cc | 1 + src/fakesyn.cc | 1 + src/osdmaptool.cc | 1 + src/rados.cc | 1 + src/rbd.cc | 1 + src/rgw/rgw_admin.cc | 1 + src/streamtest.cc | 1 + src/test/TestDoutStreambuf.cc | 4 +--- src/test/TestEncoding.cc | 1 + src/test/TestSignalHandlers.cc | 4 ++-- src/test/TestTimers.cc | 1 + src/test_trans.cc | 1 + src/testmsgr.cc | 1 + src/tools/ceph.cc | 1 + src/tools/gceph.cc | 1 + 29 files changed, 103 insertions(+), 43 deletions(-) diff --git a/src/cauthtool.cc b/src/cauthtool.cc index d51dbae97bc6d..cc7fccb834ebc 100644 --- a/src/cauthtool.cc +++ b/src/cauthtool.cc @@ -37,6 +37,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, "cauthtool", false); + set_foreground_logging(); const char *me = argv[0]; diff --git a/src/cconf.cc b/src/cconf.cc index 568ecbec800c1..ed495b0d5993d 100644 --- a/src/cconf.cc +++ b/src/cconf.cc @@ -172,6 +172,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(nargs, type, false); + set_foreground_logging(); if ((nargs.size() == 1) && (!strcmp(nargs[0], "-h"))) { usage(); diff --git a/src/common/DoutStreambuf.cc b/src/common/DoutStreambuf.cc index f9b9960f82dbc..72b3d27d46f53 100644 --- a/src/common/DoutStreambuf.cc +++ b/src/common/DoutStreambuf.cc @@ -253,8 +253,7 @@ DoutStreambuf::overflow(DoutStreambuf::int_type c) flags &= ~DOUTSB_FLAG_STDOUT; } if (flags & DOUTSB_FLAG_STDERR) { - // Only write to stderr if the message is important enough. - if (prio_is_visible_on_stderr(prio)) { + if ((flags & DOUTSB_FLAG_STDERR_ALL) || (prio == -1)) { if (safe_write(STDERR_FILENO, start, len)) flags &= ~DOUTSB_FLAG_STDERR; } @@ -283,13 +282,6 @@ void DoutStreambuf::handle_stderr_closed() flags &= ~DOUTSB_FLAG_STDERR; } -template -void DoutStreambuf::handle_stdout_closed() -{ - assert(_dout_lock.is_locked()); - flags &= ~DOUTSB_FLAG_STDOUT; -} - template void DoutStreambuf::read_global_config() { @@ -305,15 +297,21 @@ void DoutStreambuf::read_global_config() flags |= DOUTSB_FLAG_SYSLOG; } - if (g_conf.log_to_stdout) { - if (fd_is_open(STDOUT_FILENO)) { - flags |= DOUTSB_FLAG_STDOUT; - } - } - - if (g_conf.log_to_stderr) { - if (fd_is_open(STDERR_FILENO)) { - flags |= DOUTSB_FLAG_STDERR; + if ((g_conf.log_to_stderr != LOG_TO_STDERR_NONE) && + fd_is_open(STDERR_FILENO)) { + switch (g_conf.log_to_stderr) { + case LOG_TO_STDERR_SOME: + flags |= DOUTSB_FLAG_STDERR_SOME; + break; + case LOG_TO_STDERR_ALL: + flags |= DOUTSB_FLAG_STDERR_ALL; + break; + default: + ostringstream oss; + oss << "DoutStreambuf::read_global_config: can't understand " + << "g_conf.log_to_stderr = " << g_conf.log_to_stderr << "\n"; + primitive_log(oss.str()); + break; } } @@ -413,7 +411,6 @@ std::string DoutStreambuf::config_to_str() const { assert(_dout_lock.is_locked()); ostringstream oss; - oss << "g_conf.log_to_stdout = " << g_conf.log_to_stdout << "\n"; oss << "g_conf.log_to_stderr = " << g_conf.log_to_stderr << "\n"; oss << "g_conf.log_to_syslog = " << g_conf.log_to_syslog << "\n"; oss << "g_conf.log_to_file = " << g_conf.log_to_file << "\n"; diff --git a/src/common/DoutStreambuf.h b/src/common/DoutStreambuf.h index f049dc984d8e1..fcd493535f774 100644 --- a/src/common/DoutStreambuf.h +++ b/src/common/DoutStreambuf.h @@ -30,8 +30,10 @@ public: enum dout_streambuf_flags_t { DOUTSB_FLAG_SYSLOG = 0x01, DOUTSB_FLAG_STDOUT = 0x02, - DOUTSB_FLAG_STDERR = 0x04, - DOUTSB_FLAG_OFILE = 0x08, + DOUTSB_FLAG_STDERR_SOME = 0x04, + DOUTSB_FLAG_STDERR_ALL = 0x08, + DOUTSB_FLAG_STDERR = 0x0c, + DOUTSB_FLAG_OFILE = 0x10, }; typedef traits traits_ty; @@ -50,9 +52,6 @@ public: // for the error to happen. void handle_stderr_closed(); - // Call when you close stdout. - void handle_stdout_closed(); - // Set the flags based on the global configuration void read_global_config(); diff --git a/src/common/common_init.cc b/src/common/common_init.cc index 531a180b8fd6f..4feec7648fb64 100644 --- a/src/common/common_init.cc +++ b/src/common/common_init.cc @@ -19,6 +19,40 @@ #include "include/color.h" #include "tls.h" +/* Set foreground logging + * + * Forces the process to log only to stderr, overriding whatever was in the ceph.conf. + * + * TODO: make this configurable by a command line switch or environment variable, if users want + * an unusual logging setup for their foreground process. + */ +void set_foreground_logging() +{ + free((void*)g_conf.log_file); + g_conf.log_file = NULL; + + free((void*)g_conf.log_dir); + g_conf.log_dir = NULL; + + free((void*)g_conf.log_sym_dir); + g_conf.log_sym_dir = NULL; + + g_conf.log_sym_history = 0; + + g_conf.log_to_stderr = LOG_TO_STDERR_ALL; + + g_conf.log_to_syslog = false; + + g_conf.log_per_instance = false; + + g_conf.log_to_file = false; + + if (_dout_need_open) { + Mutex::Locker l(_dout_lock); + _dout_open_log(false); + } +} + void common_set_defaults(bool daemon) { if (daemon) { diff --git a/src/common/common_init.h b/src/common/common_init.h index fcbbc0b948e38..bcffc8ddf2755 100644 --- a/src/common/common_init.h +++ b/src/common/common_init.h @@ -7,5 +7,6 @@ void common_set_defaults(bool daemon); void common_init(std::vector& args, const char *module_type, bool init_keys); +void set_foreground_logging(); #endif diff --git a/src/common/debug.cc b/src/common/debug.cc index c252beaccb002..8604bf8620556 100644 --- a/src/common/debug.cc +++ b/src/common/debug.cc @@ -17,7 +17,7 @@ Mutex _dout_lock("_dout_lock", false, false /* no lockdep */); #define _STR(x) #x #define STRINGIFY(x) _STR(x) -void _dout_open_log() +void _dout_open_log(bool print_version) { assert(_dout_need_open); assert(_dout_lock.is_locked()); @@ -30,8 +30,10 @@ void _dout_open_log() _dout = new std::ostream(_doss); } - *_dout << "ceph version " << VERSION << " (commit:" - << STRINGIFY(CEPH_GIT_VER) << ")" << std::endl; + if (print_version) { + *_dout << "ceph version " << VERSION << " (commit:" + << STRINGIFY(CEPH_GIT_VER) << ")" << std::endl; + } _dout_need_open = false; } @@ -40,10 +42,9 @@ int dout_handle_daemonize() Mutex::Locker l(_dout_lock); if (_dout_need_open) - _dout_open_log(); + _dout_open_log(true); assert(_doss); - _doss->handle_stdout_closed(); _doss->handle_stderr_closed(); return _doss->handle_pid_change(); } diff --git a/src/common/debug.h b/src/common/debug.h index a11804a902a88..57a076ca288ba 100644 --- a/src/common/debug.h +++ b/src/common/debug.h @@ -29,7 +29,7 @@ extern DoutStreambuf *_doss; extern bool _dout_need_open; extern Mutex _dout_lock; -extern void _dout_open_log(); +extern void _dout_open_log(bool print_version); extern int dout_handle_daemonize(); @@ -37,7 +37,7 @@ extern int dout_create_rank_symlink(int n); static inline void _dout_begin_line(signed int prio) { if (unlikely(_dout_need_open)) - _dout_open_log(); + _dout_open_log(true); // Put priority information into dout _doss->sputc(1); diff --git a/src/config.cc b/src/config.cc index 550619bf9be07..e883c29ab7162 100644 --- a/src/config.cc +++ b/src/config.cc @@ -21,6 +21,7 @@ #include "common/DoutStreambuf.h" #include "common/Logger.h" #include "common/BackTrace.h" +#include "common/common_init.h" #include #include @@ -328,6 +329,7 @@ static struct config_option config_optionsp[] = { OPTION(log_dir, 0, OPT_STR, "/var/log/ceph"), OPTION(log_sym_dir, 0, OPT_STR, 0), OPTION(log_sym_history, 0, OPT_INT, 10), + OPTION(log_to_stderr, 0, OPT_INT, LOG_TO_STDERR_SOME), OPTION(log_to_syslog, 0, OPT_BOOL, false), OPTION(log_per_instance, 0, OPT_BOOL, false), OPTION(log_to_file, 0, OPT_BOOL, true), @@ -1133,15 +1135,13 @@ void parse_startup_config_options(std::vector& args, const char *mo std::vector nargs; bool conf_specified = false; - g_conf.log_to_stdout = false; - g_conf.log_to_stderr = true; - if (!g_conf.id) g_conf.id = (char *)g_default_id; if (!g_conf.type) g_conf.type = (char *)""; bool isdaemon = g_conf.daemonize; + bool force_foreground_logging = false; FOR_EACH_ARG(args) { if (CONF_ARG_EQ("version", 'v')) { @@ -1158,10 +1158,10 @@ void parse_startup_config_options(std::vector& args, const char *mo g_conf.public_addr.parse(args[++i]); } else if (CONF_ARG_EQ("nodaemon", 'D')) { g_conf.daemonize = false; - g_conf.log_to_stdout = true; - g_conf.log_to_stderr = false; + force_foreground_logging = true; } else if (CONF_ARG_EQ("foreground", 'f')) { g_conf.daemonize = false; + force_foreground_logging = true; } else if (isdaemon && (CONF_ARG_EQ("id", 'i') || CONF_ARG_EQ("name", 'n'))) { CONF_SAFE_SET_ARG_VAL(&g_conf.id, OPT_STR); } else if (!isdaemon && (CONF_ARG_EQ("id", 'I') || CONF_ARG_EQ("name", 'n'))) { @@ -1234,6 +1234,10 @@ void parse_startup_config_options(std::vector& args, const char *mo exit(1); } + if (force_foreground_logging) { + set_foreground_logging(); + } + if (!cf) return; diff --git a/src/config.h b/src/config.h index baadfb4df0fbc..50676e68375d1 100644 --- a/src/config.h +++ b/src/config.h @@ -42,6 +42,12 @@ extern void ceph_set_default_id(const char *id); struct EntityName; +enum log_to_stderr_t { + LOG_TO_STDERR_NONE = 0, + LOG_TO_STDERR_SOME = 1, + LOG_TO_STDERR_ALL = 2, +}; + struct md_config_t { char *type; char *id; @@ -82,8 +88,8 @@ struct md_config_t { const char *log_sym_dir; int log_sym_history; - bool log_to_stdout; - bool log_to_stderr; + int log_to_stderr; + bool log_to_syslog; bool log_per_instance; bool log_to_file; diff --git a/src/crushtool.cc b/src/crushtool.cc index 79a2b5f2e9b51..7b381365fdff9 100644 --- a/src/crushtool.cc +++ b/src/crushtool.cc @@ -21,6 +21,7 @@ #include "config.h" +#include "common/common_init.h" #include "crush/CrushWrapper.h" #include "crush/grammar.h" @@ -773,6 +774,7 @@ struct layer_t { int main(int argc, const char **argv) { + set_foreground_logging(); vector args; argv_to_vec(argc, argv, args); diff --git a/src/csyn.cc b/src/csyn.cc index 9c5303cb24f99..29a815c8193f6 100644 --- a/src/csyn.cc +++ b/src/csyn.cc @@ -45,6 +45,7 @@ int main(int argc, const char **argv, char *envp[]) common_set_defaults(false); common_init(args, "csyn", true); + set_foreground_logging(); parse_syn_options(args); // for SyntheticClient diff --git a/src/dumpjournal.cc b/src/dumpjournal.cc index 1da4eed296887..f4d57d03ac2fe 100644 --- a/src/dumpjournal.cc +++ b/src/dumpjournal.cc @@ -82,6 +82,7 @@ int main(int argc, const char **argv, const char *envp[]) common_set_defaults(false); common_init(args, "dumpjournal", false); + set_foreground_logging(); vec_to_argv(args, argc, argv); diff --git a/src/dupstore.cc b/src/dupstore.cc index 49185e79b8a3d..5ffe4f562aed2 100644 --- a/src/dupstore.cc +++ b/src/dupstore.cc @@ -89,6 +89,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, "dumpstore", false); + set_foreground_logging(); // args if (args.size() != 4) diff --git a/src/fakefuse.cc b/src/fakefuse.cc index 6f7d91b5402cc..5551e2f620d56 100644 --- a/src/fakefuse.cc +++ b/src/fakefuse.cc @@ -72,6 +72,7 @@ int main(int argc, const char **argv) { common_set_defaults(false); common_init(args, "fakefuse", false); + set_foreground_logging(); // start messenger thread fakemessenger_startthread(); diff --git a/src/fakesyn.cc b/src/fakesyn.cc index 3b2ac0fc5d7a8..aeb78fc55223b 100644 --- a/src/fakesyn.cc +++ b/src/fakesyn.cc @@ -68,6 +68,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, "fakesyn"); + set_foreground_logging(); int start = 0; diff --git a/src/osdmaptool.cc b/src/osdmaptool.cc index d55e9c84a8857..61265827b048a 100644 --- a/src/osdmaptool.cc +++ b/src/osdmaptool.cc @@ -50,6 +50,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, "osdmaptool", false); + set_foreground_logging(); const char *me = argv[0]; diff --git a/src/rados.cc b/src/rados.cc index f384103c64623..1df8fd39f1cf8 100644 --- a/src/rados.cc +++ b/src/rados.cc @@ -94,6 +94,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, "rados", true); + set_foreground_logging(); vector nargs; bufferlist indata, outdata; diff --git a/src/rbd.cc b/src/rbd.cc index 6d59a6e458ded..45ceb3730d359 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -1115,6 +1115,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, "rbd", true); + set_foreground_logging(); const char *poolname = NULL; uint64_t size = 0; diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 2e58d62438018..b88cd514581d5 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -84,6 +84,7 @@ int main(int argc, char **argv) common_set_defaults(false); common_init(args, "rgw", true); + set_foreground_logging(); const char *user_id = 0; const char *secret_key = 0; diff --git a/src/streamtest.cc b/src/streamtest.cc index fa9a792546ae0..837dff230778e 100644 --- a/src/streamtest.cc +++ b/src/streamtest.cc @@ -98,6 +98,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, NULL, true); + set_foreground_logging(); // args if (args.size() < 3) return -1; diff --git a/src/test/TestDoutStreambuf.cc b/src/test/TestDoutStreambuf.cc index 1f14735b881fa..607bf419e58a3 100644 --- a/src/test/TestDoutStreambuf.cc +++ b/src/test/TestDoutStreambuf.cc @@ -38,14 +38,12 @@ int main(int argc, const char **argv) ceph_set_default_id("admin"); common_set_defaults(false); common_init(args, "ceph", true); + set_foreground_logging(); DoutStreambuf *dos = new DoutStreambuf(); _dout_lock.Lock(); dos->read_global_config(); -// dos->set_flags(DoutStreambuf::DOUTSB_FLAG_SYSLOG | -// DoutStreambuf::DOUTSB_FLAG_STDOUT | -// DoutStreambuf::DOUTSB_FLAG_STDERR); _dout_lock.Unlock(); derr << "using configuration: " << dos->config_to_str() << dendl; diff --git a/src/test/TestEncoding.cc b/src/test/TestEncoding.cc index ec1d8f92a116e..2e0c4893bf949 100644 --- a/src/test/TestEncoding.cc +++ b/src/test/TestEncoding.cc @@ -96,6 +96,7 @@ int main(int argc, const char **argv) ceph_set_default_id("admin"); common_set_defaults(false); common_init(args, "ceph", true); + set_foreground_logging(); ret = test_string_sz("I am the very model of a modern major general"); if (ret) diff --git a/src/test/TestSignalHandlers.cc b/src/test/TestSignalHandlers.cc index cceb42b418aa9..79b3f92a6abd3 100644 --- a/src/test/TestSignalHandlers.cc +++ b/src/test/TestSignalHandlers.cc @@ -93,10 +93,10 @@ int main(int argc, const char **argv) argv_to_vec(argc, argv, args); env_to_vec(args); ceph_set_default_id("admin"); + common_set_defaults(false); - g_conf.log_to_file = true; - g_conf.log_file = tmp_log_file.c_str(); common_init(args, "TestSignalHandlers", true); + set_foreground_logging(); DEFINE_CONF_VARS(usage); FOR_EACH_ARG(args) { diff --git a/src/test/TestTimers.cc b/src/test/TestTimers.cc index 73e8b0f2f51d2..c053524ceda4a 100644 --- a/src/test/TestTimers.cc +++ b/src/test/TestTimers.cc @@ -257,6 +257,7 @@ int main(int argc, const char **argv) ceph_set_default_id("admin"); common_set_defaults(false); common_init(args, "ceph", true); + set_foreground_logging(); int ret; Mutex safe_timer_lock("safe_timer_lock"); diff --git a/src/test_trans.cc b/src/test_trans.cc index 3fb7a288cd6af..0c7bdb95f8be0 100644 --- a/src/test_trans.cc +++ b/src/test_trans.cc @@ -37,6 +37,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, NULL, false); + set_foreground_logging(); // args if (args.size() < 2) return -1; diff --git a/src/testmsgr.cc b/src/testmsgr.cc index 95a3096178008..5f7a02c30137e 100644 --- a/src/testmsgr.cc +++ b/src/testmsgr.cc @@ -71,6 +71,7 @@ int main(int argc, const char **argv, const char *envp[]) { common_set_defaults(false); common_init(args, NULL, false); + set_foreground_logging(); vec_to_argv(args, argc, argv); diff --git a/src/tools/ceph.cc b/src/tools/ceph.cc index a6cbbb2f21866..448e563085e71 100644 --- a/src/tools/ceph.cc +++ b/src/tools/ceph.cc @@ -133,6 +133,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, "ceph", true); + set_foreground_logging(); vec_to_argv(args, argc, argv); diff --git a/src/tools/gceph.cc b/src/tools/gceph.cc index d7ab5e72968fb..45be3fbe310df 100644 --- a/src/tools/gceph.cc +++ b/src/tools/gceph.cc @@ -78,6 +78,7 @@ int main(int argc, const char **argv) common_set_defaults(false); common_init(args, "cephtool", true); + set_foreground_logging(); vec_to_argv(args, argc, argv); -- 2.39.5