Commit a3dfd72f authored by Tobias Mayer's avatar Tobias Mayer

Allow different log levels for file and console

The concrete log levels can be set with the config options
"logger.file-verbosity" and "logger.console-verbosity".
"logger.verbosity" remains to be supported for backwards
compatibility.
parent f92e049a
...@@ -61,12 +61,13 @@ extern const timespan relaxed_sleep_duration; ...@@ -61,12 +61,13 @@ extern const timespan relaxed_sleep_duration;
namespace logger { namespace logger {
extern const atom_value console;
extern const atom_value verbosity;
extern const char* component_filter; extern const char* component_filter;
extern const atom_value console;
extern const char* console_format; extern const char* console_format;
extern const atom_value console_verbosity;
extern const char* file_format; extern const char* file_format;
extern const char* file_name; extern const char* file_name;
extern const atom_value file_verbosity;
} // namespace logger } // namespace logger
......
...@@ -284,6 +284,8 @@ public: ...@@ -284,6 +284,8 @@ public:
private: private:
void handle_event(event& x); void handle_event(event& x);
void handle_file_event(event& x);
void handle_console_event(event& x);
void log_first_line(); void log_first_line();
...@@ -308,7 +310,9 @@ private: ...@@ -308,7 +310,9 @@ private:
} }
actor_system& system_; actor_system& system_;
int level_; int max_level_;
int console_level_;
int file_level_;
int flags_; int flags_;
detail::shared_spinlock aids_lock_; detail::shared_spinlock aids_lock_;
std::unordered_map<std::thread::id, actor_id> aids_; std::unordered_map<std::thread::id, actor_id> aids_;
...@@ -553,4 +557,3 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; } ...@@ -553,4 +557,3 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; }
"TERMINATE ; ID =" << thisptr->id() \ "TERMINATE ; ID =" << thisptr->id() \
<< "; REASON =" << deep_to_string(rsn).c_str() \ << "; REASON =" << deep_to_string(rsn).c_str() \
<< "; NODE =" << thisptr->node()) << "; NODE =" << thisptr->node())
...@@ -85,7 +85,6 @@ actor_system_config::actor_system_config() ...@@ -85,7 +85,6 @@ actor_system_config::actor_system_config()
logger_file_format = "%r %c %p %a %t %C %M %F:%L %m%n"; logger_file_format = "%r %c %p %a %t %C %M %F:%L %m%n";
logger_console = atom("none"); logger_console = atom("none");
logger_console_format = "%m"; logger_console_format = "%m";
logger_verbosity = atom("trace");
logger_inline_output = false; logger_inline_output = false;
namespace mm = defaults::middleman; namespace mm = defaults::middleman;
middleman_network_backend = mm::network_backend; middleman_network_backend = mm::network_backend;
...@@ -143,14 +142,19 @@ actor_system_config::actor_system_config() ...@@ -143,14 +142,19 @@ actor_system_config::actor_system_config()
"sets the filesystem path of the log file") "sets the filesystem path of the log file")
.add(logger_file_format, "file-format", .add(logger_file_format, "file-format",
"sets the line format for individual log file entires") "sets the line format for individual log file entires")
.add<atom_value>("file-verbosity",
"sets the file output verbosity (quiet|error|warning|info|debug|trace)")
.add(logger_console, "console", .add(logger_console, "console",
"sets the type of output to std::clog (none|colored|uncolored)") "sets the type of output to std::clog (none|colored|uncolored)")
.add(logger_console_format, "console-format", .add(logger_console_format, "console-format",
"sets the line format for printing individual log entires") "sets the line format for printing individual log entires")
.add<atom_value>("console-verbosity",
"sets the console output verbosity"
"(quiet|error|warning|info|debug|trace)")
.add(logger_component_filter, "component-filter", .add(logger_component_filter, "component-filter",
"exclude all listed components from logging") "exclude all listed components from logging")
.add(logger_verbosity, "verbosity", .add(logger_verbosity, "verbosity",
"sets the verbosity (quiet|error|warning|info|debug|trace)") "set file and console verbosity (deprecated)")
.add(logger_inline_output, "inline-output", .add(logger_inline_output, "inline-output",
"sets whether a separate thread is used for I/O"); "sets whether a separate thread is used for I/O");
opt_group{custom_options_, "middleman"} opt_group{custom_options_, "middleman"}
......
...@@ -48,7 +48,7 @@ const timespan desired_batch_complexity = us(50); ...@@ -48,7 +48,7 @@ const timespan desired_batch_complexity = us(50);
const timespan max_batch_delay = ms(5); const timespan max_batch_delay = ms(5);
const timespan credit_round_interval = ms(10); const timespan credit_round_interval = ms(10);
} // namespace streaming } // namespace stream
namespace scheduler { namespace scheduler {
...@@ -74,12 +74,13 @@ const timespan relaxed_sleep_duration = ms(10); ...@@ -74,12 +74,13 @@ const timespan relaxed_sleep_duration = ms(10);
namespace logger { namespace logger {
const atom_value console = atom("none");
const atom_value verbosity = atom("trace");
const char* component_filter = ""; const char* component_filter = "";
const atom_value console = atom("none");
const char* console_format = "%m"; const char* console_format = "%m";
const atom_value console_verbosity = atom("trace");
const char* file_format = "%r %c %p %a %t %C %M %F:%L %m%n"; const char* file_format = "%r %c %p %a %t %C %M %F:%L %m%n";
const char* file_name = "actor_log_[PID]_[TIMESTAMP]_[NODE].log"; const char* file_name = "actor_log_[PID]_[TIMESTAMP]_[NODE].log";
const atom_value file_verbosity = atom("trace");
} // namespace logger } // namespace logger
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <fstream> #include <fstream>
#include <algorithm> #include <algorithm>
#include <condition_variable> #include <condition_variable>
#include <unordered_map>
#include "caf/config.hpp" #include "caf/config.hpp"
...@@ -214,7 +215,7 @@ bool logger::accepts(int level, const char* cname_begin, ...@@ -214,7 +215,7 @@ bool logger::accepts(int level, const char* cname_begin,
const char* cname_end) { const char* cname_end) {
CAF_ASSERT(cname_begin != nullptr && cname_end != nullptr); CAF_ASSERT(cname_begin != nullptr && cname_end != nullptr);
CAF_ASSERT(level >= 0 && level <= 4); CAF_ASSERT(level >= 0 && level <= 4);
if (level > level_) if (level > max_level_)
return false; return false;
if (!component_filter.empty()) { if (!component_filter.empty()) {
auto it = std::search(component_filter.begin(), component_filter.end(), auto it = std::search(component_filter.begin(), component_filter.end(),
...@@ -234,52 +235,60 @@ logger::~logger() { ...@@ -234,52 +235,60 @@ logger::~logger() {
logger::logger(actor_system& sys) logger::logger(actor_system& sys)
: system_(sys), : system_(sys),
level_(CAF_LOG_LEVEL), max_level_(CAF_LOG_LEVEL),
flags_(0), flags_(0),
queue_(policy{}) { queue_(policy{}) {
// nop // nop
} }
void logger::init(actor_system_config& cfg) { namespace {
CAF_IGNORE_UNUSED(cfg); int to_level_int(const atom_value atom) {
#if CAF_LOG_LEVEL >= 0 switch (atom_uint(atom)) {
namespace lg = defaults::logger;
component_filter = get_or(cfg, "logger.component-filter",
lg::component_filter);
// Parse the configured log level.
auto verbosity = get_or(cfg, "logger.verbosity", lg::verbosity);
switch (static_cast<uint64_t>(verbosity)) {
case atom_uint("quiet"): case atom_uint("quiet"):
case atom_uint("QUIET"): case atom_uint("QUIET"):
level_ = CAF_LOG_LEVEL_QUIET; return CAF_LOG_LEVEL_QUIET;
break;
case atom_uint("error"): case atom_uint("error"):
case atom_uint("ERROR"): case atom_uint("ERROR"):
level_ = CAF_LOG_LEVEL_ERROR; return CAF_LOG_LEVEL_ERROR;
break;
case atom_uint("warning"): case atom_uint("warning"):
case atom_uint("WARNING"): case atom_uint("WARNING"):
level_ = CAF_LOG_LEVEL_WARNING; return CAF_LOG_LEVEL_WARNING;
break;
case atom_uint("info"): case atom_uint("info"):
case atom_uint("INFO"): case atom_uint("INFO"):
level_ = CAF_LOG_LEVEL_INFO; return CAF_LOG_LEVEL_INFO;
break;
case atom_uint("debug"): case atom_uint("debug"):
case atom_uint("DEBUG"): case atom_uint("DEBUG"):
level_ = CAF_LOG_LEVEL_DEBUG; return CAF_LOG_LEVEL_DEBUG;
break;
case atom_uint("trace"): case atom_uint("trace"):
case atom_uint("TRACE"): case atom_uint("TRACE"):
level_ = CAF_LOG_LEVEL_TRACE; return CAF_LOG_LEVEL_TRACE;
break;
default: { default: {
// nop // nop
} }
} }
return CAF_LOG_LEVEL_QUIET;
}
} // namespace
void logger::init(actor_system_config& cfg) {
CAF_IGNORE_UNUSED(cfg);
#if CAF_LOG_LEVEL >= 0
namespace lg = defaults::logger;
component_filter = get_or(cfg, "logger.component-filter",
lg::component_filter);
// Parse the configured log level.
auto verbosity = get_if<atom_value>(&cfg, "logger.verbosity");
auto file_verbosity = verbosity ? *verbosity : lg::file_verbosity;
auto console_verbosity = verbosity ? *verbosity : lg::console_verbosity;
file_verbosity = get_or(cfg, "logger.file-verbosity", file_verbosity);
console_verbosity =
get_or(cfg, "logger.console-verbosity", console_verbosity);
file_level_ = to_level_int(file_verbosity);
console_level_ = to_level_int(console_verbosity);
max_level_ = std::max(file_level_, console_level_);
// Parse the format string. // Parse the format string.
file_format_ = parse_format(get_or(cfg, "logger.file-format", file_format_ =
lg::file_format)); parse_format(get_or(cfg, "logger.file-format", lg::file_format));
console_format_ = parse_format(get_or(cfg,"logger.console-format", console_format_ = parse_format(get_or(cfg,"logger.console-format",
lg::console_format)); lg::console_format));
// Set flags. // Set flags.
...@@ -447,12 +456,15 @@ void logger::run() { ...@@ -447,12 +456,15 @@ void logger::run() {
#endif #endif
} }
void logger::handle_event(event& x) { void logger::handle_file_event(event& x) {
// Print to file if available. // Print to file if available.
if (file_) if (file_ && x.level <= file_level_)
render(file_, file_format_, x); render(file_, file_format_, x);
}
void logger::handle_console_event(event& x) {
// Stop if no console output is configured. // Stop if no console output is configured.
if (!has(console_output_flag)) if (!has(console_output_flag) || x.level > console_level_)
return; return;
if (has(uncolored_console_flag)) { if (has(uncolored_console_flag)) {
render(std::clog, console_format_, x); render(std::clog, console_format_, x);
...@@ -482,13 +494,19 @@ void logger::handle_event(event& x) { ...@@ -482,13 +494,19 @@ void logger::handle_event(event& x) {
} }
} }
void logger::handle_event(event& x) {
handle_file_event(x);
handle_console_event(x);
}
void logger::log_first_line() { void logger::log_first_line() {
std::string msg = "level = "; auto make_event = [&](string_view config_val,
msg += to_string(get_or(system_.config(), "logger.verbosity", const atom_value default_val) -> event {
defaults::logger::verbosity)); std::string msg = "level = ";
msg += ", node = "; msg += to_string(get_or(system_.config(), config_val, default_val));
msg += to_string(system_.node()); msg += ", node = ";
event tmp{CAF_LOG_LEVEL_INFO, msg += to_string(system_.node());
return {CAF_LOG_LEVEL_INFO,
CAF_LOG_COMPONENT, CAF_LOG_COMPONENT,
CAF_PRETTY_FUN, CAF_PRETTY_FUN,
__FILE__, __FILE__,
...@@ -497,7 +515,11 @@ void logger::log_first_line() { ...@@ -497,7 +515,11 @@ void logger::log_first_line() {
std::this_thread::get_id(), std::this_thread::get_id(),
0, 0,
make_timestamp()}; make_timestamp()};
handle_event(tmp); };
event file = make_event("logger.file-verbosity", defaults::logger::file_verbosity);
handle_file_event(file);
event console = make_event("logger.console-verbosity", defaults::logger::console_verbosity);
handle_console_event(console);
} }
void logger::log_last_line() { void logger::log_last_line() {
...@@ -516,7 +538,7 @@ void logger::log_last_line() { ...@@ -516,7 +538,7 @@ void logger::log_last_line() {
void logger::start() { void logger::start() {
#if CAF_LOG_LEVEL >= 0 #if CAF_LOG_LEVEL >= 0
parent_thread_ = std::this_thread::get_id(); parent_thread_ = std::this_thread::get_id();
if (level_ == CAF_LOG_LEVEL_QUIET) if (max_level_ == CAF_LOG_LEVEL_QUIET)
return; return;
t0_ = make_timestamp(); t0_ = make_timestamp();
auto f = get_or(system_.config(), "logger.file-name", auto f = get_or(system_.config(), "logger.file-name",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment