Commit c736d978 authored by Dominik Charousset's avatar Dominik Charousset Committed by Dominik Charousset

Allow apps to always use the caf::logger

Currently, the CAF logger is only available if CAF was compiled with
non-quiet log level. This change allows applications to use the CAF
logger regardless of the build config.
parent fe48cbb6
...@@ -320,6 +320,8 @@ private: ...@@ -320,6 +320,8 @@ private:
void init(actor_system_config& cfg); void init(actor_system_config& cfg);
bool open_file();
// -- event handling --------------------------------------------------------- // -- event handling ---------------------------------------------------------
void handle_event(const event& x); void handle_event(const event& x);
...@@ -375,6 +377,9 @@ private: ...@@ -375,6 +377,9 @@ private:
// Filled with log events by other threads. // Filled with log events by other threads.
detail::ringbuffer<event, queue_size> queue_; detail::ringbuffer<event, queue_size> queue_;
// Stores the assembled name of the log file.
std::string file_name_;
// Executes `logger::run`. // Executes `logger::run`.
std::thread thread_; std::thread thread_;
}; };
...@@ -435,25 +440,6 @@ bool operator==(const logger::field& x, const logger::field& y); ...@@ -435,25 +440,6 @@ bool operator==(const logger::field& x, const logger::field& y);
// -- logging macros ----------------------------------------------------------- // -- logging macros -----------------------------------------------------------
#if CAF_LOG_LEVEL == CAF_LOG_LEVEL_QUIET
#define CAF_LOG_IMPL(unused1, unused2, unused3)
// placeholder macros when compiling without logging
inline caf::actor_id caf_set_aid_dummy() { return 0; }
#define CAF_PUSH_AID(unused) CAF_VOID_STMT
#define CAF_PUSH_AID_FROM_PTR(unused) CAF_VOID_STMT
#define CAF_SET_AID(unused) caf_set_aid_dummy()
#define CAF_SET_LOGGER_SYS(unused) CAF_VOID_STMT
#define CAF_LOG_TRACE(unused)
#else // CAF_LOG_LEVEL == CAF_LOG_LEVEL_QUIET
#define CAF_LOG_IMPL(component, loglvl, message) \ #define CAF_LOG_IMPL(component, loglvl, message) \
do { \ do { \
auto CAF_UNIFYN(caf_logger) = caf::logger::current_logger(); \ auto CAF_UNIFYN(caf_logger) = caf::logger::current_logger(); \
...@@ -518,8 +504,6 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; } ...@@ -518,8 +504,6 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; }
#define CAF_LOG_ERROR(output) \ #define CAF_LOG_ERROR(output) \
CAF_LOG_IMPL(CAF_LOG_COMPONENT, CAF_LOG_LEVEL_ERROR, output) CAF_LOG_IMPL(CAF_LOG_COMPONENT, CAF_LOG_LEVEL_ERROR, output)
#endif // CAF_LOG_LEVEL == CAF_LOG_LEVEL_QUIET
#ifndef CAF_LOG_INFO #ifndef CAF_LOG_INFO
#define CAF_LOG_INFO(output) CAF_VOID_STMT #define CAF_LOG_INFO(output) CAF_VOID_STMT
#define CAF_LOG_INFO_IF(cond, output) CAF_VOID_STMT #define CAF_LOG_INFO_IF(cond, output) CAF_VOID_STMT
......
...@@ -188,8 +188,6 @@ string_view reduce_symbol(std::ostream& out, string_view symbol) { ...@@ -188,8 +188,6 @@ string_view reduce_symbol(std::ostream& out, string_view symbol) {
return symbol; return symbol;
} }
#if CAF_LOG_LEVEL >= 0
#if defined(CAF_NO_THREAD_LOCAL) #if defined(CAF_NO_THREAD_LOCAL)
pthread_key_t s_key; pthread_key_t s_key;
...@@ -232,17 +230,6 @@ inline logger* get_current_logger() { ...@@ -232,17 +230,6 @@ inline logger* get_current_logger() {
#endif // CAF_NO_THREAD_LOCAL #endif // CAF_NO_THREAD_LOCAL
#else // CAF_LOG_LEVEL
inline void set_current_logger(logger*) {
// nop
}
inline logger* get_current_logger() {
return nullptr;
}
#endif // CAF_LOG_LEVEL
} // namespace <anonymous> } // namespace <anonymous>
logger::config::config() logger::config::config()
...@@ -358,7 +345,7 @@ bool logger::accepts(unsigned level, atom_value cname) { ...@@ -358,7 +345,7 @@ bool logger::accepts(unsigned level, atom_value cname) {
[=](atom_value name) { return name == cname; }); [=](atom_value name) { return name == cname; });
} }
logger::logger(actor_system& sys) : system_(sys) { logger::logger(actor_system& sys) : system_(sys), t0_(make_timestamp()) {
// nop // nop
} }
...@@ -404,6 +391,17 @@ void logger::init(actor_system_config& cfg) { ...@@ -404,6 +391,17 @@ void logger::init(actor_system_config& cfg) {
} }
} }
bool logger::open_file() {
if (file_verbosity() == CAF_LOG_LEVEL_QUIET || file_name_.empty())
return false;
file_.open(file_name_, std::ios::out | std::ios::app);
if (!file_) {
std::cerr << "unable to open log file " << file_name_ << std::endl;
return false;
}
return true;
}
void logger::render_fun_prefix(std::ostream& out, const event& x) { void logger::render_fun_prefix(std::ostream& out, const event& x) {
// Extract the prefix of a function name. For example: // Extract the prefix of a function name. For example:
// virtual std::vector<int> my::namespace::foo(int); // virtual std::vector<int> my::namespace::foo(int);
...@@ -550,6 +548,8 @@ void logger::run() { ...@@ -550,6 +548,8 @@ void logger::run() {
queue_.wait_nonempty(); queue_.wait_nonempty();
if (queue_.front().message.empty()) if (queue_.front().message.empty())
return; return;
if (!open_file() && console_verbosity() == CAF_LOG_LEVEL_QUIET)
return;
log_first_line(); log_first_line();
// Loop until receiving an empty message. // Loop until receiving an empty message.
for (;;) { for (;;) {
...@@ -635,49 +635,48 @@ void logger::start() { ...@@ -635,49 +635,48 @@ void logger::start() {
parent_thread_ = std::this_thread::get_id(); parent_thread_ = std::this_thread::get_id();
if (verbosity() == CAF_LOG_LEVEL_QUIET) if (verbosity() == CAF_LOG_LEVEL_QUIET)
return; return;
t0_ = make_timestamp(); file_name_ = get_or(system_.config(), "logger.file-name",
auto f = get_or(system_.config(), "logger.file-name",
defaults::logger::file_name); defaults::logger::file_name);
if (f.empty()) { if (file_name_.empty()) {
// No need to continue if console and log file are disabled. // No need to continue if console and log file are disabled.
if (console_verbosity() == CAF_LOG_LEVEL_QUIET) if (console_verbosity() == CAF_LOG_LEVEL_QUIET)
return; return;
} else { } else {
// Replace placeholders. // Replace placeholders.
const char pid[] = "[PID]"; const char pid[] = "[PID]";
auto i = std::search(f.begin(), f.end(), std::begin(pid), auto i = std::search(file_name_.begin(), file_name_.end(), std::begin(pid),
std::end(pid) - 1); std::end(pid) - 1);
if (i != f.end()) { if (i != file_name_.end()) {
auto id = std::to_string(detail::get_process_id()); auto id = std::to_string(detail::get_process_id());
f.replace(i, i + sizeof(pid) - 1, id); file_name_.replace(i, i + sizeof(pid) - 1, id);
} }
const char ts[] = "[TIMESTAMP]"; const char ts[] = "[TIMESTAMP]";
i = std::search(f.begin(), f.end(), std::begin(ts), std::end(ts) - 1); i = std::search(file_name_.begin(), file_name_.end(), std::begin(ts),
if (i != f.end()) { std::end(ts) - 1);
if (i != file_name_.end()) {
auto t0_str = timestamp_to_string(t0_); auto t0_str = timestamp_to_string(t0_);
f.replace(i, i + sizeof(ts) - 1, t0_str); file_name_.replace(i, i + sizeof(ts) - 1, t0_str);
} }
const char node[] = "[NODE]"; const char node[] = "[NODE]";
i = std::search(f.begin(), f.end(), std::begin(node), std::end(node) - 1); i = std::search(file_name_.begin(), file_name_.end(), std::begin(node),
if (i != f.end()) { std::end(node) - 1);
if (i != file_name_.end()) {
auto nid = to_string(system_.node()); auto nid = to_string(system_.node());
f.replace(i, i + sizeof(node) - 1, nid); file_name_.replace(i, i + sizeof(node) - 1, nid);
}
file_.open(f, std::ios::out | std::ios::app);
if (!file_) {
std::cerr << "unable to open log file " << f << std::endl;
return;
} }
} }
if (cfg_.inline_output) if (cfg_.inline_output) {
// Open file immediately for inline output.
open_file();
log_first_line(); log_first_line();
else } else {
thread_ = std::thread{[this] { thread_ = std::thread{[this] {
detail::set_thread_name("caf.logger"); detail::set_thread_name("caf.logger");
this->system_.thread_started(); this->system_.thread_started();
this->run(); this->run();
this->system_.thread_terminates(); this->system_.thread_terminates();
}}; }};
}
} }
void logger::stop() { void logger::stop() {
......
...@@ -121,7 +121,7 @@ CAF_TEST(counting_system_without_actor) { ...@@ -121,7 +121,7 @@ CAF_TEST(counting_system_without_actor) {
assumed_init_calls = 1; assumed_init_calls = 1;
assumed_thread_count = get_or(cfg, "scheduler.max-threads", assumed_thread_count = get_or(cfg, "scheduler.max-threads",
defaults::scheduler::max_threads) defaults::scheduler::max_threads)
+ 1; // caf.clock thread + 2; // caf.clock and caf.logger
auto& sched = sys.scheduler(); auto& sched = sys.scheduler();
if (sched.detaches_utility_actors()) if (sched.detaches_utility_actors())
assumed_thread_count += sched.num_utility_actors(); assumed_thread_count += sched.num_utility_actors();
...@@ -131,7 +131,7 @@ CAF_TEST(counting_system_with_actor) { ...@@ -131,7 +131,7 @@ CAF_TEST(counting_system_with_actor) {
assumed_init_calls = 1; assumed_init_calls = 1;
assumed_thread_count = get_or(cfg, "scheduler.max-threads", assumed_thread_count = get_or(cfg, "scheduler.max-threads",
defaults::scheduler::max_threads) defaults::scheduler::max_threads)
+ 2; // caf.clock thread plus detached actor + 3; // caf.clock, caf.logger, and detached actor
auto& sched = sys.scheduler(); auto& sched = sys.scheduler();
if (sched.detaches_utility_actors()) if (sched.detaches_utility_actors())
assumed_thread_count += sched.num_utility_actors(); assumed_thread_count += sched.num_utility_actors();
......
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