Merge branch 'master' of github.com:cloudius-systems/urchin into db

This commit is contained in:
Avi Kivity
2015-07-16 13:10:49 +03:00
4 changed files with 52 additions and 6 deletions

View File

@@ -685,6 +685,8 @@ public:
val(logger_log_level, string_map, /* none */, Used,\
"map of logger name to log level. Valid values are trace, debug, info, warn, error. " \
"Use --help-loggers for a list of logger names") \
val(log_to_stdout, bool, true, Used, "Send log output to stdout") \
val(log_to_syslog, bool, false, Used, "Send log output to syslog") \
/* done! */
#define _make_value_member(name, type, deflt, status, desc, ...) \

44
log.cc
View File

@@ -3,10 +3,12 @@
*/
#include "log.hh"
#include "core/array_map.hh"
#include <cxxabi.h>
#include <system_error>
#include <boost/range/adaptor/map.hpp>
#include <map>
#include <syslog.h>
namespace logging {
@@ -46,6 +48,9 @@ std::istream& operator>>(std::istream& in, log_level& level) {
namespace logging {
std::atomic<bool> logger::_stdout = { true };
std::atomic<bool> logger::_syslog = { false };
logger::logger(sstring name) : _name(std::move(name)) {
logger_registry().register_logger(this);
}
@@ -60,21 +65,52 @@ logger::~logger() {
void
logger::really_do_log(log_level level, const char* fmt, stringer** s, size_t n) {
std::ostringstream out;
const char* p = fmt;
while (*p != '\0') {
if (*p == '{' && *(p+1) == '}') {
p += 2;
if (n > 0) {
(*s++)->append(std::cout);
(*s++)->append(out);
--n;
} else {
std::cout << "???";
out << "???";
}
} else {
std::cout << *p++;
out << *p++;
}
}
std::cout << "\n";
out << "\n";
auto msg = out.str();
if (_stdout.load(std::memory_order_relaxed)) {
std::cout << out;
}
if (_syslog.load(std::memory_order_relaxed)) {
static array_map<int, 20> level_map = {
{ int(log_level::debug), LOG_DEBUG },
{ int(log_level::info), LOG_INFO },
{ int(log_level::trace), LOG_DEBUG }, // no LOG_TRACE
{ int(log_level::warn), LOG_WARNING },
{ int(log_level::error), LOG_ERR },
};
// NOTE: syslog() can block, which will stall the reactor thread.
// this should be rare (will have to fill the pipe buffer
// before syslogd can clear it) but can happen. If it does,
// we'll have to implement some internal buffering (which
// still means the problem can happen, just less frequently).
// syslog() interprets % characters, so send msg as a parameter
syslog(level_map[int(level)], "%s", msg.c_str());
}
}
void
logger::set_stdout_enabled(bool enabled) {
_stdout.store(enabled, std::memory_order_relaxed);
}
void
logger::set_syslog_enabled(bool enabled) {
_syslog.store(enabled, std::memory_order_relaxed);
}
void

4
log.hh
View File

@@ -46,6 +46,8 @@ class registry;
class logger {
sstring _name;
std::atomic<log_level> _level = { log_level::warn };
static std::atomic<bool> _stdout;
static std::atomic<bool> _syslog;
private:
struct stringer {
// no need for virtual dtor, since not dynamically destroyed
@@ -104,6 +106,8 @@ public:
void set_level(log_level level) {
_level.store(level, std::memory_order_relaxed);
}
static void set_stdout_enabled(bool enabled);
static void set_syslog_enabled(bool enabled);
};
class registry {

View File

@@ -36,13 +36,16 @@ void do_help_loggers() {
}
}
void apply_logger_settings(sstring default_level, db::config::string_map levels) {
void apply_logger_settings(sstring default_level, db::config::string_map levels,
bool log_to_stdout, bool log_to_syslog) {
logging::logger_registry().set_all_loggers_level(boost::lexical_cast<logging::log_level>(std::string(default_level)));
for (auto&& kv: levels) {
auto&& k = kv.first;
auto&& v = kv.second;
logging::logger_registry().set_logger_level(k, boost::lexical_cast<logging::log_level>(std::string(v)));
}
logging::logger::set_stdout_enabled(log_to_stdout);
logging::logger::set_syslog_enabled(log_to_syslog);
}
int main(int ac, char** av) {
@@ -75,7 +78,8 @@ int main(int ac, char** av) {
auto&& opts = app.configuration();
return read_config(opts, *cfg).then([&cfg, &db, &qp, &proxy, &ctx, &opts]() {
apply_logger_settings(cfg->default_log_level(), cfg->logger_log_level());
apply_logger_settings(cfg->default_log_level(), cfg->logger_log_level(),
cfg->log_to_stdout(), cfg->log_to_syslog());
dht::set_global_partitioner(cfg->partitioner());
uint16_t thrift_port = cfg->rpc_port();
uint16_t cql_port = cfg->native_transport_port();