# log-system **Repository Path**: code-eye/log-system ## Basic Information - **Project Name**: log-system - **Description**: 基于C++的多模式下的同步/异步日志系统 - **Primary Language**: C++ - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-08-14 - **Last Updated**: 2025-02-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # log-system ## Introduction Synchronous/asynchronous logging system based on C++ in multiple modes ## Development environment Centos7、vscode/vim、g++/gdb、makefile ### log formatting rule | Format symbol | Format content | | ------------- | ------------------------ | | %p | log level | | %d{%H:%M:%S} | date{hour:minute:second} | | %f | source file name | | %l | source file line number | | %t | thread ID | | %c | logger name | | %T | retract | | %m | payload information | | %n | newline | #### log formattring ```cpp #include "log-system/include/log/log_format.hpp" int main() { log_system::LogMessage message(log_system::LogLevel::INFO, "test.cc", 5, "logger_name", "formatter test"); log_system::Formatter formatter1; std:: cout << formatter1.format(message) << std::endl; log_system::Formatter formatter2("[%p][%d{%H:%M:%S}][%f][%l]%T%m%n"); std::cout << formatter2.format(message) << std::endl; return 0; } ``` ### Log sink mode | mode | extra argument | | ----------------------- | ------------------------------- | | StdoutLogSink | | | SpecifyFileLogSink | file path | | ScrollFileBySizeLogSink | base file path && file max size | | ScrollFileByTimeLogSink | base file path && time gap | #### StdoutLogSink Output directly to the console ```cpp #include "log-system/include/log/log_format.hpp" #include "log-system/include/log/log_sink.hpp" int main() { log_system::LogMessage message(log_system::LogLevel::DEBUG, "test.cc", 5, "logger_name", "stdout log sink test"); log_system::Formatter formatter("[%p][%f][%l][%c]%T%m%n"); std::string format_string = formatter.format(message); log_system::LogSink::pointer stdout_ptr = log_system::LogSinkFactory::create(); stdout_ptr->log(format_string.c_str(), format_string.size()); return 0; } ``` #### SpecifyFileLogSink Receives logs in the specified file path ```cpp #include "log-system/include/log/log_format.hpp" #include "log-system/include/log/log_sink.hpp" int main() { log_system::LogMessage message(log_system::LogLevel::DEBUG, "test.cc", 5, "logger_name", "stdout log sink test"); log_system::Formatter formatter("[%p][%f][%l][%c]%T%m%n"); std::string format_string = formatter.format(message); log_system::LogSink::pointer specify_file_ptr = log_system::LogSinkFactory::create("./logfile/store.log"); specify_file_ptr->log(format_string.c_str(), format_string.size()); return 0; } ``` #### ScrollFileBySizeLogSink Receive as a scroll file that scrolls by size ```cpp #include "log-system/include/log/log_format.hpp" #include "log-system/include/log/log_sink.hpp" int main() { log_system::LogMessage message(log_system::LogLevel::DEBUG, "test.cc", 5, "logger_name", "stdout log sink test"); log_system::Formatter formatter("[%p][%f][%l][%c]%T%m%n"); std::string format_string = formatter.format(message); log_system::LogSink::pointer scroll_by_size_ptr = log_system::LogSinkFactory::create("./logfile/scrollbysize-", 1024 * 1024); size_t cur_size = 0; while(cur_size <= 10 * 1024 * 1024) // 只是一个示例,达到滚动效果 { scroll_by_size_ptr->log(format_string.c_str(), format_string.size()); cur_size += 20; } return 0; } ``` #### ScrollFileByTimeLogSink Receive the scrolling file as it scrolls at time intervals ```cpp #include "log-system/include/log/log_format.hpp" #include "log-system/include/log/log_sink.hpp" int main() { log_system::LogMessage message(log_system::LogLevel::DEBUG, "test.cc", 5, "logger_name", "stdout log sink test"); log_system::Formatter formatter("[%p][%f][%l][%c]%T%m%n"); std::string format_string = formatter.format(message); log_system::LogSink::pointer scroll_by_time_ptr = log_system::LogSinkFactory::create("./logfile/scrollbytime-", log_system::ScrollFileByTimeLogSink::TimeGap::GAP_SECOND); // 按照秒间隔滚动 size_t old_time = log_system::utility::Date::getTime(); while(log_system::utility::Date::getTime() < old_time + 5) // 5秒写入5个文件 { scroll_by_time_ptr->log(format_string.c_str(), format_string.size()); } return 0; } ``` #### Logger category | Logger category | Effect | | --------------- | ------------------------------------------------------------ | | SyncLogger | Directly manage the process to receive logs | | AsyncLogger | The asynchronous worker thread manages how logs are received | ### Logger builder category | Logger builder category | Applicable scene | header file | | ----------------------- | ---------------- | ------------------------------------------------------------ | | LocalLoggerBuilder | Local scope | log-system/include/log/logger.hpp | | GlobalLoggerBuilder | Global scope | log-system/include/log/log_system.hpp or log-system/include/log/logger.hpp | ## log system use ### LoggerDirector constructor declaration ```cpp LoggerDirector(const std::string &logger_name, LoggerDirector::BuilderCategory builder_category = BuilderCategory::LOCAL_BUILDER, LoggerBuilder::Type logger_type = LoggerBuilder::Type::LOGGER_SYNC, log_system::LogLevel::Level limit_level = log_system::LogLevel::Level::UNKNOWN, const std::string &pattern = "[%p][%d{%H:%M:%S}][%f:%l][%t][%c]%T%m%n") ``` logger_name argument must be set, Other parameters can not be set(The default is to use the global builder, synchronous logger, restriction level is UNKONWN, formatting rule string is "[%p][%d{%H:%M:%S}][%f:%l][%t][%c]%T%m%n", asynchronous worker guarantees security) #### argument options ##### builder_category | options | declaration | | ------------------------------------------- | ------------------------------------------------------------ | | log_system::BuilderCategory::LOCAL_BUILDER | With the local builder, the LoggerDiretor object needs to be recreated in different scopes, and different logger names can be set. | | log_system::BuilderCategory::GLOBAL_BUILDER | The global builder is used, and the asynchronous worker is used to perform IO operations on the log information. The program generally appears at the beginning of the main function, and the entire program only needs to be created once to be used in different scopes | ##### logger_type | options | declaration | | --------------------------------------------- | ------------------------------------------------------------ | | log_system::LoggerBuilder::Type::LOGGER_SYNC | Ensure thread synchronization and the log receiver receives logs in an orderly manner | | log_system::LoggerBuilder::Type::LOGGER_ASYNC | An asynchronous worker performs IO processing on logs, which does not guarantee log order | ##### limit_level log_system::LogLevel::Level::UNKNOWN、log_system::LogLevel::Level::DEBUG、log_system::LogLevel::Level::INFO、log_system::LogLevel::Level::WARNING、log_system::LogLevel::Level::ERROR、log_system::LogLevel::Level::FATAL、log_system::LogLevel::Level::OFF log priority: UNKNOWN < DEBUG < INFO < WARNING < ERROR < FATAL < OFF ##### pattern According to your own requirements, generally do not set the default ### LogSinkSet::set() function #### StdoutLogSink The argument for calling this function sink_category uses StdoutLogSink() ```cpp inline void set(log_system::StdoutLogSink sink_category) ``` #### SpecifyFileLogSink The argument for calling this function sink_category uses SpecifyFileLogSink() ```cpp inline void set(log_system::SpecifyFileLogSink sink_category, const std::string &file_path) ``` #### ScrollFileBySizeLogSink The argument for calling this function sink_category uses ScrollFileBySizeLogSink() ```cpp inline void set(log_system::ScrollFileBySizeLogSink sink_category, const std::string &base_filename, size_t maxsize) ``` #### ScrollFileByTimeLogSink The argument for calling this function sink_category uses ScrollFileByTimeLogSink() ```cpp inline void set(log_system::ScrollFileByTimeLogSink sink_category, const std::string &base_filename, log_system::ScrollFileByTimeLogSink::TimeGap tiem_gap) ``` The four set functions and the constructor of the class corresponding to the Log Sink mode in the above heading are passed with similar arguments ### example #### local_builder && logger_sync && set_log_sink ```cpp #include "../include/log/logger.hpp" // #### local_builder && logger_sync void test1() { log_system::LoggerDirector director("test1_logger", log_system::LoggerDirector::BuilderCategory::LOCAL_BUILDER, log_system::LoggerBuilder::LOGGER_SYNC, log_system::LogLevel::DEBUG); log_system::LogSinkSet set(director.getLoggerBuilder()); // log sink set set.set(log_system::StdoutLogSink()); // set stdout log sink set.set(log_system::SpecifyFileLogSink(), "./logfile/test1.log"); // set specify file log sink director.create(); // Pass the set log receiving mode, Logger name, restriction level, and formatter to the Logger class director.getLogger()->info(__FILE__, __LINE__, "%s", "scope : test1()"); director.getLogger()->debug(__FILE__, __LINE__, "%s", "scope : test1()"); } void test2() { log_system::LoggerDirector director("test2_logger", log_system::LoggerDirector::BuilderCategory::LOCAL_BUILDER, log_system::LoggerBuilder::LOGGER_SYNC, log_system::LogLevel::DEBUG); log_system::LogSinkSet set(director.getLoggerBuilder()); set.set(log_system::StdoutLogSink()); // set stdout log sink set.set(log_system::SpecifyFileLogSink(), "./logfile/test2.log"); // set specify file log sink director.create(); // Pass the set log receiving mode, Logger name, restriction level, and formatter to the Logger class director.getLogger()->info(__FILE__, __LINE__, "%s", "scope : test2()"); director.getLogger()->debug(__FILE__, __LINE__, "%s", "scope : test2()"); } int main() { test1(); test2(); } ``` #### local_builder && logger_async && set_log_sink ```cpp #include "../include/log/logger.hpp" // #### local_builder && logger_sync void test1() { log_system::LoggerDirector director("test1_logger", log_system::LoggerDirector::BuilderCategory::LOCAL_BUILDER, log_system::LoggerBuilder::LOGGER_ASYNC, log_system::LogLevel::DEBUG); log_system::LogSinkSet set(director.getLoggerBuilder()); // log sink set set.set(log_system::StdoutLogSink()); // set stdout log sink set.set(log_system::SpecifyFileLogSink(), "./logfile/test1.log"); // set specify file log sink director.create(); // Pass the set log receiving mode, Logger name, restriction level, and formatter to the Logger class director.getLogger()->info(__FILE__, __LINE__, "%s", "scope : test1()"); director.getLogger()->debug(__FILE__, __LINE__, "%s", "scope : test1()"); } void test2() { log_system::LoggerDirector director("test2_logger", log_system::LoggerDirector::BuilderCategory::LOCAL_BUILDER, log_system::LoggerBuilder::LOGGER_ASYNC, log_system::LogLevel::DEBUG); log_system::LogSinkSet set(director.getLoggerBuilder()); // log sink set set.set(log_system::StdoutLogSink()); // set stdout log sink set.set(log_system::SpecifyFileLogSink(), "./logfile/test2.log"); // set specify file log sink director.create(); // Pass the set log receiving mode, Logger name, restriction level, and formatter to the Logger class director.getLogger()->info(__FILE__, __LINE__, "%s", "scope : test2()"); director.getLogger()->debug(__FILE__, __LINE__, "%s", "scope : test2()"); } int main() { test1(); test2(); } ``` #### global_builder && logger_sync && set_log_sink ##### first print log mode ```cpp #include "../include/log/log_system.hpp" class Base { public: Base() { INFO("%s", "Base class constructor done!!!"); // first print log mode } ~Base() { INFO("%s", "Base class destructor done!!!"); } }; // class Base int main() { log_system::LoggerDirector director("master", log_system::LoggerDirector::BuilderCategory::GLOBAL_BUILDER, log_system::LoggerBuilder::LOGGER_SYNC, log_system::LogLevel::DEBUG); log_system::LogSinkSet set(director.getLoggerBuilder()); // log sink set set.set(log_system::StdoutLogSink()); // set stdout log sink set.set(log_system::SpecifyFileLogSink(), "./logfile/test2.log"); // set specify file log sink set.set(log_system::ScrollFileBySizeLogSink(), "./scroll/scrollBySize-", 1024 * 1024); // set scroll file by size log sink set.set(log_system::ScrollFileBySizeLogSink(), "./scroll/scrollByTimeBySecond-", log_system::ScrollFileByTimeLogSink::TimeGap::GAP_SECOND); // set scroll file by time(second) log sink director.create(); // Pass the set log receiving mode, Logger name, restriction level, and formatter to the Logger class } ``` ##### second print log mode ```cpp #include "../include/log/logger.hpp" class Base { public: Base() { log_system::LoggerManager::getInstance().getLogger("master")->info(__FILE__, __LINE__, "%s", "Base class constructor done!!!"); } ~Base() { log_system::LoggerManager::getInstance().defalutLogger()->info(__FILE__, __LINE__, "%s", "Base class destrutor done!!!"); } }; // class Base int main() { log_system::LoggerDirector director("master", log_system::LoggerDirector::BuilderCategory::GLOBAL_BUILDER, log_system::LoggerBuilder::LOGGER_SYNC, log_system::LogLevel::DEBUG); log_system::LogSinkSet set(director.getLoggerBuilder()); // log sink set set.set(log_system::StdoutLogSink()); // set stdout log sink set.set(log_system::SpecifyFileLogSink(), "./logfile/test2.log"); // set specify file log sink set.set(log_system::ScrollFileBySizeLogSink(), "./scroll/scrollBySize-", 1024 * 1024); // set scroll file by size log sink set.set(log_system::ScrollFileBySizeLogSink(), "./scroll/scrollByTimeBySecond-", log_system::ScrollFileByTimeLogSink::TimeGap::GAP_SECOND); // set scroll file by time(second) log sink director.create(); // Pass the set log receiving mode, Logger name, restriction level, and formatter to the Logger class Base b; } ``` #### global_builder && logger_sync && set_log_sink in a similar way.