161 lines
4.6 KiB
C++
161 lines
4.6 KiB
C++
|
|
#include "vp_logger.h"
|
|
|
|
namespace vp_utils {
|
|
|
|
vp_logger::vp_logger(/* args */)
|
|
{
|
|
}
|
|
|
|
vp_logger::~vp_logger() {
|
|
die();
|
|
if (log_writer_th.joinable()) {
|
|
log_writer_th.join();
|
|
}
|
|
}
|
|
|
|
void vp_logger::die() {
|
|
alive = false;
|
|
std::lock_guard<std::mutex> guard(log_cache_mutex);
|
|
log_cache.push("die");
|
|
log_cache_semaphore.signal();
|
|
}
|
|
|
|
void vp_logger::init() {
|
|
inited = true;
|
|
|
|
// initialize file writer
|
|
file_writer.init(log_dir, log_file_name_template);
|
|
|
|
#ifdef VP_WITH_KAFKA
|
|
// initialize kafka writer
|
|
auto servers_and_topic = vp_utils::string_split(kafka_servers_and_topic, '/');
|
|
assert(servers_and_topic.size() == 2);
|
|
kafka_writer.init(servers_and_topic[0], servers_and_topic[1]);
|
|
#endif
|
|
|
|
// run thread
|
|
auto t = std::thread(&vp_logger::log_write_run, this);
|
|
log_writer_th = std::move(t);
|
|
}
|
|
|
|
void vp_logger::log(vp_log_level level, const std::string& message, const char* code_file, int code_line) {
|
|
// make sure logger is initialized
|
|
if (!inited) {
|
|
throw "vp_logger is not initialized yet!";
|
|
}
|
|
|
|
// level filter
|
|
if (level > log_level) {
|
|
return;
|
|
}
|
|
|
|
// keywords filter for debug level
|
|
if (level == vp_log_level::DEBUG && keywords_for_debug_log.size() != 0) {
|
|
bool filterd = true;
|
|
for(auto& keywords: keywords_for_debug_log) {
|
|
if (message.find(keywords) != std::string::npos) {
|
|
filterd = false;
|
|
break;
|
|
}
|
|
}
|
|
if (filterd) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* create log */
|
|
std::string new_log = "";
|
|
// 100% true for log time
|
|
if (include_time) {
|
|
new_log += vp_utils::time_format(NOW, log_time_templete);
|
|
}
|
|
|
|
// log level
|
|
if (include_level) {
|
|
new_log += "[" + log_level_names.at(level) + "]";
|
|
}
|
|
|
|
// thread id
|
|
if (include_thread_id) {
|
|
auto id = std::this_thread::get_id();
|
|
std::stringstream ss;
|
|
ss << std::hex << id; // to hex
|
|
auto thread_id = ss.str();
|
|
new_log += "[" + thread_id + "]";
|
|
}
|
|
|
|
// code location
|
|
if (include_code_location) {
|
|
new_log += "[" + std::string(code_file) + ":" + std::to_string(code_line) + "]";
|
|
}
|
|
|
|
new_log += " " + message;
|
|
|
|
/* write to cache */
|
|
// min lock range
|
|
std::lock_guard<std::mutex> guard(log_cache_mutex);
|
|
log_cache.push(new_log);
|
|
// notify
|
|
log_cache_semaphore.signal();
|
|
}
|
|
|
|
void vp_logger::log_write_run() {
|
|
bool log_thres_warned = false;
|
|
/* below code runs in single thread */
|
|
while (inited && alive) {
|
|
// wait for data
|
|
log_cache_semaphore.wait();
|
|
auto log = log_cache.front();
|
|
log_cache.pop();
|
|
|
|
if (log == "die") {
|
|
continue;
|
|
}
|
|
|
|
/* watch the log cache size */
|
|
auto log_cache_size = 0;
|
|
{
|
|
// min lock range
|
|
std::lock_guard<std::mutex> guard(log_cache_mutex);
|
|
log_cache_size = log_cache.size();
|
|
}
|
|
if (!log_thres_warned && log_cache_size > log_cache_warn_threshold) {
|
|
VP_WARN(vp_utils::string_format("[logger] log cache size is exceeding threshold! cache size is: [%d], threshold is: [%d]", log_cache_size, log_cache_warn_threshold));
|
|
log_thres_warned = true; // warn 1 time
|
|
}
|
|
if (log_cache_size <= log_cache_warn_threshold) {
|
|
log_thres_warned = false;
|
|
}
|
|
|
|
/* write to devices */
|
|
if (log_to_console) {
|
|
write_to_console(log);
|
|
}
|
|
|
|
if (log_to_file) {
|
|
write_to_file(log);
|
|
}
|
|
|
|
if (log_to_kafka) {
|
|
write_to_kafka(log);
|
|
}
|
|
}
|
|
}
|
|
|
|
void vp_logger::write_to_console(const std::string& log) {
|
|
std::cout << log << std::endl;
|
|
}
|
|
|
|
void vp_logger::write_to_file(const std::string& log) {
|
|
// file_writer.write(log);
|
|
file_writer << log;
|
|
}
|
|
|
|
void vp_logger::write_to_kafka(const std::string& log) {
|
|
#ifdef VP_WITH_KAFKA
|
|
// kafka_writer.write(log);
|
|
kafka_writer << log;
|
|
#endif
|
|
}
|
|
} |