基于C11的简单log,支持C++的‘<<’风格和C的‘可变参数’风格
日志仅由richlog.h单个文件实现功能,软件集成简单。
支持C++的std::cout的<<风格的日志打印,也支持C的printf风格的日志打印
日志多线程安全,采用C++11 mutex 互斥锁
日志格式如下:
- [日志级别][时间戳][模块名][组件名][日志所在文件名][日志所在行号][日志所在函数名]->日志内容
复制代码 日志格式、输出方式可设置,以下为设置函数
- //日志输出到文件开关,默认关闭
- static void set_output_to_file(bool to_file)
- //日志输出到终端开关,默认打开
- static void set_output_to_console(bool to_console)
- //日志打印时间戳开关,默认打开
- static void set_print_timestamp(bool log_timestamp)
- //设置日志打印模块名,默认为空
- static void set_modulename(std::string name)
- //设置日志打印组件名,默认为空
- static void set_componentname(std::string name)
- //日志级别开关,默认打开
- static void set_print_log_level(bool log_level)
- //日志所在文件名开关,默认打开
- static void set_print_filename(bool log_level)
- //日志所在行号开关,默认打开
- static void set_print_linenum(bool plinenum)
- //日志所在函数名,默认打开
- static void set_print_funcname(bool pfuncname)
- //设置日志输出的文件名,默认为空
- static void set_output_to_filename(std::string filename)
复制代码 richlog.h代码
- #ifndef _RICHLOGS_H
- #define _RICHLOGS_H
- #include <cstring>
- #include <cstdio>
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <chrono>
- #include <thread>
- #include <mutex>
- #define CXXLOG_FILENAME(x) (strrchr((x),'/')?strrchr((x),'/')+1:(x))
- #define C11LOG_ERROR CPP_LOG::RichLogs(CPP_LOG::ERROR,CXXLOG_FILENAME(__FILE__),__LINE__,__FUNCTION__)
- #define C11LOG_WARN CPP_LOG::RichLogs(CPP_LOG::WARN,CXXLOG_FILENAME(__FILE__),__LINE__,__FUNCTION__)
- #define C11LOG_INFO CPP_LOG::RichLogs(CPP_LOG::INFO,CXXLOG_FILENAME(__FILE__),__LINE__,__FUNCTION__)
- #define C11LOG_DEBUG CPP_LOG::RichLogs(CPP_LOG::DEBUG,CXXLOG_FILENAME(__FILE__),__LINE__,__FUNCTION__)
- namespace CPP_LOG
- {
- enum LOG_LEVEL{ERROR,WARN,INFO,DEBUG};
- class RichLogs
- {
- public:
- RichLogs(LOG_LEVEL log_level,std::string filename,unsigned int line_num,std::string func_name)
- {
- m_has_endl=false;
- if(m_print_log_level)
- {
- switch(log_level)
- {
- case ERROR:
- m_log_data<<"[ERROR]";
- break;
- case WARN:
- m_log_data<<"[ WARN]";
- break;
- case INFO:
- m_log_data<<"[ INFO]";
- break;
- case DEBUG:
- m_log_data<<"[DEBUG]";
- break;
- }
- }
- if(m_print_timestamp)
- {
- m_log_data<<"["<<getNowTime().count()<<"]";
- }
- if(m_module_name!="")
- {
- m_log_data<<"["<<m_module_name<<"]";
- }
- if(m_component_name!="")
- {
- m_log_data<<"["<<m_component_name<<"]";
- }
- if(m_print_filename)
- {
- m_log_data<<"["<<filename<<"]";
- }
- if(m_print_linenum)
- {
- m_log_data<<"["<<line_num<<"]";
- }
- if(m_print_funcname)
- {
- m_log_data<<"["<<func_name<<"]";
- }
- m_log_data<<"->";
- }
- ~RichLogs()
- {
- if(!m_has_endl)
- {
- m_log_data<<std::endl;
- }
- if(m_output_to_file)
- {
- if(m_output_to_filename!="")
- {
- std::ofstream outputFile;
- outputFile.open(m_output_to_filename,std::ios::app);
- if (outputFile.is_open())
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- outputFile<<m_log_data.str();
- outputFile.flush();
- }
- outputFile.close();
- }
- }
- if(m_output_to_console)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- std::cout<<m_log_data.str();
- }
- }
- RichLogs& operator<<(std::ostream&(*p)(std::ostream&))
- {
- m_has_endl=true;
- m_log_data<<std::endl;
- return *this;
- }
- template<typename T>
- RichLogs& operator<<(const T& logdata)
- {
- m_has_endl=false;
- m_log_data<<logdata;
- return *this;
- }
- // 泛型
- template <typename... Args>
- RichLogs& operator()(const char *pformat, Args... args)
- {
- int total_len = std::snprintf(nullptr, 0, pformat, args...);
- if (0 >= total_len)
- {
- return *this;
- }
- total_len++;
- char *log_str_out = nullptr;
- log_str_out = new(std::nothrow) char[total_len];
- if (NULL == log_str_out || nullptr == log_str_out)
- {
- return *this;
- }
- std::snprintf(log_str_out, total_len, pformat, args...);
- if(log_str_out[total_len-2]=='\n')
- {
- m_has_endl=true;
- }
- else
- {
- m_has_endl=false;
- }
- std::string str(log_str_out);
- delete log_str_out;
- log_str_out = nullptr;
- m_log_data<<str;
- return *this;
- }
- static void set_output_to_file(bool to_file)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_output_to_file=to_file;
- }
- static void set_output_to_console(bool to_console)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_output_to_console=to_console;
- }
- static void set_print_timestamp(bool log_timestamp)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_print_timestamp=log_timestamp;
- }
- static void set_modulename(std::string name)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_module_name=name;
- }
- static void set_componentname(std::string name)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_component_name=name;
- }
- static void set_print_log_level(bool log_level)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_print_log_level=log_level;
- }
- static void set_print_filename(bool log_level)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_print_log_level=log_level;
- }
- static void set_print_linenum(bool plinenum)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_print_linenum=plinenum;
- }
- static void set_print_funcname(bool pfuncname)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_print_funcname=pfuncname;
- }
- static void set_output_to_filename(std::string filename)
- {
- std::lock_guard<std::mutex> lock(m_log_mutex);
- m_output_to_filename=filename;
- }
- private:
- bool m_has_endl;
- std::stringstream m_log_data;
- static std::mutex m_log_mutex;
- static bool m_output_to_file;
- static bool m_output_to_console;
- static bool m_print_log_level;
- static bool m_print_timestamp;
- static std::string m_module_name;
- static std::string m_component_name;
- static bool m_print_filename;
- static bool m_print_linenum;
- static bool m_print_funcname;
- static std::string m_output_to_filename;
- std::chrono::milliseconds getNowTime()
- {
- std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now();
- return std::chrono::duration_cast<std::chrono::milliseconds>(now_time.time_since_epoch());
- }
- };
- std::mutex RichLogs::m_log_mutex;
- bool RichLogs::m_output_to_file=false;
- bool RichLogs::m_output_to_console=true;
- bool RichLogs::m_print_log_level=true;
- bool RichLogs::m_print_timestamp=true;
- std::string RichLogs::m_module_name="";
- std::string RichLogs::m_component_name="";
- bool RichLogs::m_print_filename=true;
- bool RichLogs::m_print_linenum=true;
- bool RichLogs::m_print_funcname=true;
- std::string RichLogs::m_output_to_filename="";
- }
- #endif //C11LOG_C11LOG_H
复制代码 测试例子
- #include <iostream>
- #include "richlog.h"
- using namespace std;
- int main()
- {
- CPP_LOG::RichLogs::set_modulename("test123");
- CPP_LOG::RichLogs::set_componentname("sdfghjk");
- CPP_LOG::RichLogs::set_output_to_file(true);
- CPP_LOG::RichLogs::set_output_to_filename("test4444.log");
- for(int i=0;i<100;i++)
- {
- C11LOG_INFO<<"123456 "<<" sdfsdfgfdgjghjsegwdsfbrsntbrsb"<<"54332gfdsbrrbfdxbw4353vsw";
- C11LOG_DEBUG<<"123456 "<<1234<<" "<<345.6<<" sdsafdsv ewtertyui"<<'c'<<'l';
- C11LOG_WARN<<"123456 "<<1234<<" "<<345.6<<" sdsafdsv ewtertyui"<<'c'<<'l';
- C11LOG_ERROR<<"123456 "<<1234<<" "<<345.6<<" sdsafdsv ewtertyui"<<'c'<<'l';
- C11LOG_INFO("%d-%f-%s-%c\n",1234,345.234,"kkkkkkk",'e');
- C11LOG_DEBUG("%d-%f-%s-%c\n",1234,345.234,"kkkkkkk",'e');
- C11LOG_WARN("%d-%f-%s-%c",1234,345.234,"kkkkkkk",'e');
- C11LOG_ERROR("%d-%f-%s-%c",1234,345.234,"kkkkkkk",'e');
- }
- return 0;
- }
复制代码 运行效果:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |