ToB企服应用市场:ToB评测及商务社交产业平台

标题: 基于C11的简单log,支持C++的‘<<’风格和C的‘可变参数’风格 [打印本页]

作者: 北冰洋以北    时间: 2024-8-10 06:26
标题: 基于C11的简单log,支持C++的‘<<’风格和C的‘可变参数’风格
基于C11的简单log,支持C++的‘<<’风格和C的‘可变参数’风格

日志仅由richlog.h单个文件实现功能,软件集成简单。
支持C++的std::cout的<<风格的日志打印,也支持C的printf风格的日志打印
日志多线程安全,采用C++11 mutex 互斥锁
日志格式如下:
  1. [日志级别][时间戳][模块名][组件名][日志所在文件名][日志所在行号][日志所在函数名]->日志内容
复制代码
日志格式、输出方式可设置,以下为设置函数
  1. //日志输出到文件开关,默认关闭
  2. static void set_output_to_file(bool to_file)
  3. //日志输出到终端开关,默认打开
  4. static void set_output_to_console(bool to_console)
  5. //日志打印时间戳开关,默认打开
  6. static void set_print_timestamp(bool log_timestamp)
  7. //设置日志打印模块名,默认为空
  8. static void set_modulename(std::string name)
  9. //设置日志打印组件名,默认为空
  10. static void set_componentname(std::string name)
  11. //日志级别开关,默认打开
  12. static void set_print_log_level(bool log_level)
  13. //日志所在文件名开关,默认打开
  14. static void set_print_filename(bool log_level)
  15. //日志所在行号开关,默认打开
  16. static void set_print_linenum(bool plinenum)
  17. //日志所在函数名,默认打开
  18. static void set_print_funcname(bool pfuncname)
  19. //设置日志输出的文件名,默认为空
  20. static void set_output_to_filename(std::string filename)
复制代码
richlog.h代码
  1. #ifndef _RICHLOGS_H
  2. #define _RICHLOGS_H
  3. #include <cstring>
  4. #include <cstdio>
  5. #include <iostream>
  6. #include <fstream>
  7. #include <sstream>
  8. #include <chrono>
  9. #include <thread>
  10. #include <mutex>
  11. #define CXXLOG_FILENAME(x) (strrchr((x),'/')?strrchr((x),'/')+1:(x))
  12. #define C11LOG_ERROR   CPP_LOG::RichLogs(CPP_LOG::ERROR,CXXLOG_FILENAME(__FILE__),__LINE__,__FUNCTION__)
  13. #define C11LOG_WARN    CPP_LOG::RichLogs(CPP_LOG::WARN,CXXLOG_FILENAME(__FILE__),__LINE__,__FUNCTION__)
  14. #define C11LOG_INFO    CPP_LOG::RichLogs(CPP_LOG::INFO,CXXLOG_FILENAME(__FILE__),__LINE__,__FUNCTION__)
  15. #define C11LOG_DEBUG   CPP_LOG::RichLogs(CPP_LOG::DEBUG,CXXLOG_FILENAME(__FILE__),__LINE__,__FUNCTION__)
  16. namespace CPP_LOG
  17. {
  18. enum  LOG_LEVEL{ERROR,WARN,INFO,DEBUG};
  19. class RichLogs
  20. {
  21. public:
  22.     RichLogs(LOG_LEVEL log_level,std::string filename,unsigned int line_num,std::string func_name)
  23.     {
  24.         m_has_endl=false;
  25.         if(m_print_log_level)
  26.         {
  27.             switch(log_level)
  28.             {
  29.                 case ERROR:
  30.                     m_log_data<<"[ERROR]";
  31.                     break;
  32.                 case WARN:
  33.                     m_log_data<<"[ WARN]";
  34.                     break;
  35.                 case INFO:
  36.                     m_log_data<<"[ INFO]";
  37.                     break;
  38.                 case DEBUG:
  39.                     m_log_data<<"[DEBUG]";
  40.                     break;
  41.             }
  42.         }
  43.         if(m_print_timestamp)
  44.         {
  45.             m_log_data<<"["<<getNowTime().count()<<"]";
  46.         }
  47.         if(m_module_name!="")
  48.         {
  49.             m_log_data<<"["<<m_module_name<<"]";
  50.         }
  51.         if(m_component_name!="")
  52.         {
  53.             m_log_data<<"["<<m_component_name<<"]";
  54.         }
  55.         if(m_print_filename)
  56.         {
  57.             m_log_data<<"["<<filename<<"]";
  58.         }
  59.         if(m_print_linenum)
  60.         {
  61.             m_log_data<<"["<<line_num<<"]";
  62.         }
  63.         if(m_print_funcname)
  64.         {
  65.             m_log_data<<"["<<func_name<<"]";
  66.         }
  67.         m_log_data<<"->";
  68.     }
  69.     ~RichLogs()
  70.     {
  71.         if(!m_has_endl)
  72.         {
  73.             m_log_data<<std::endl;
  74.         }
  75.         if(m_output_to_file)
  76.         {
  77.             if(m_output_to_filename!="")
  78.             {
  79.                 std::ofstream outputFile;
  80.                 outputFile.open(m_output_to_filename,std::ios::app);
  81.                 if (outputFile.is_open())
  82.                 {
  83.                     std::lock_guard<std::mutex> lock(m_log_mutex);
  84.                     outputFile<<m_log_data.str();
  85.                     outputFile.flush();
  86.                 }
  87.                 outputFile.close();
  88.             }
  89.         }
  90.         if(m_output_to_console)
  91.         {
  92.             std::lock_guard<std::mutex> lock(m_log_mutex);
  93.             std::cout<<m_log_data.str();
  94.         }
  95.     }
  96.     RichLogs& operator<<(std::ostream&(*p)(std::ostream&))
  97.     {
  98.         m_has_endl=true;
  99.         m_log_data<<std::endl;
  100.         return *this;
  101.     }
  102.     template<typename T>
  103.     RichLogs& operator<<(const T& logdata)
  104.     {
  105.         m_has_endl=false;
  106.         m_log_data<<logdata;
  107.         return *this;
  108.     }
  109.     // 泛型
  110.     template <typename... Args>
  111.     RichLogs& operator()(const char *pformat, Args... args)
  112.     {
  113.         int total_len = std::snprintf(nullptr, 0, pformat, args...);
  114.         if (0 >= total_len)
  115.         {
  116.             return *this;
  117.         }
  118.         total_len++;
  119.         char *log_str_out = nullptr;
  120.         log_str_out = new(std::nothrow) char[total_len];
  121.         if (NULL == log_str_out || nullptr == log_str_out)
  122.         {
  123.             return *this;
  124.         }
  125.         std::snprintf(log_str_out, total_len, pformat, args...);
  126.         if(log_str_out[total_len-2]=='\n')
  127.         {
  128.             m_has_endl=true;
  129.         }
  130.         else
  131.         {
  132.             m_has_endl=false;
  133.         }
  134.         std::string str(log_str_out);
  135.         delete log_str_out;
  136.         log_str_out = nullptr;
  137.         m_log_data<<str;
  138.         return *this;
  139.     }
  140.     static void set_output_to_file(bool to_file)
  141.     {
  142.         std::lock_guard<std::mutex> lock(m_log_mutex);
  143.         m_output_to_file=to_file;
  144.     }
  145.     static void set_output_to_console(bool to_console)
  146.     {
  147.         std::lock_guard<std::mutex> lock(m_log_mutex);
  148.         m_output_to_console=to_console;
  149.     }
  150.     static void set_print_timestamp(bool log_timestamp)
  151.     {
  152.         std::lock_guard<std::mutex> lock(m_log_mutex);
  153.         m_print_timestamp=log_timestamp;
  154.     }
  155.     static void set_modulename(std::string name)
  156.     {
  157.         std::lock_guard<std::mutex> lock(m_log_mutex);
  158.         m_module_name=name;
  159.     }
  160.     static void set_componentname(std::string name)
  161.     {
  162.         std::lock_guard<std::mutex> lock(m_log_mutex);
  163.         m_component_name=name;
  164.     }
  165.     static void set_print_log_level(bool log_level)
  166.     {
  167.         std::lock_guard<std::mutex> lock(m_log_mutex);
  168.         m_print_log_level=log_level;
  169.     }
  170.     static void set_print_filename(bool log_level)
  171.     {
  172.         std::lock_guard<std::mutex> lock(m_log_mutex);
  173.         m_print_log_level=log_level;
  174.     }
  175.     static void set_print_linenum(bool plinenum)
  176.     {
  177.         std::lock_guard<std::mutex> lock(m_log_mutex);
  178.         m_print_linenum=plinenum;
  179.     }
  180.     static void set_print_funcname(bool pfuncname)
  181.     {
  182.         std::lock_guard<std::mutex> lock(m_log_mutex);
  183.         m_print_funcname=pfuncname;
  184.     }
  185.     static void set_output_to_filename(std::string filename)
  186.     {
  187.         std::lock_guard<std::mutex> lock(m_log_mutex);
  188.         m_output_to_filename=filename;
  189.     }
  190. private:
  191.     bool m_has_endl;
  192.     std::stringstream m_log_data;
  193.     static std::mutex m_log_mutex;
  194.     static bool m_output_to_file;
  195.     static bool m_output_to_console;
  196.     static bool m_print_log_level;
  197.     static bool m_print_timestamp;
  198.     static std::string m_module_name;
  199.     static std::string m_component_name;
  200.     static bool m_print_filename;
  201.     static bool m_print_linenum;
  202.     static bool m_print_funcname;
  203.     static std::string m_output_to_filename;
  204.     std::chrono::milliseconds getNowTime()
  205.     {
  206.         std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now();
  207.         return std::chrono::duration_cast<std::chrono::milliseconds>(now_time.time_since_epoch());
  208.     }
  209. };
  210. std::mutex RichLogs::m_log_mutex;
  211. bool RichLogs::m_output_to_file=false;
  212. bool RichLogs::m_output_to_console=true;
  213. bool RichLogs::m_print_log_level=true;
  214. bool RichLogs::m_print_timestamp=true;
  215. std::string RichLogs::m_module_name="";
  216. std::string RichLogs::m_component_name="";
  217. bool RichLogs::m_print_filename=true;
  218. bool RichLogs::m_print_linenum=true;
  219. bool RichLogs::m_print_funcname=true;
  220. std::string RichLogs::m_output_to_filename="";
  221. }
  222. #endif //C11LOG_C11LOG_H
复制代码
测试例子
  1. #include <iostream>
  2. #include "richlog.h"
  3. using namespace std;
  4. int main()
  5. {
  6.     CPP_LOG::RichLogs::set_modulename("test123");
  7.     CPP_LOG::RichLogs::set_componentname("sdfghjk");
  8.     CPP_LOG::RichLogs::set_output_to_file(true);
  9.     CPP_LOG::RichLogs::set_output_to_filename("test4444.log");
  10.     for(int i=0;i<100;i++)
  11.     {
  12.         C11LOG_INFO<<"123456 "<<" sdfsdfgfdgjghjsegwdsfbrsntbrsb"<<"54332gfdsbrrbfdxbw4353vsw";
  13.         C11LOG_DEBUG<<"123456 "<<1234<<" "<<345.6<<" sdsafdsv ewtertyui"<<'c'<<'l';
  14.         C11LOG_WARN<<"123456 "<<1234<<" "<<345.6<<" sdsafdsv ewtertyui"<<'c'<<'l';
  15.         C11LOG_ERROR<<"123456 "<<1234<<" "<<345.6<<" sdsafdsv ewtertyui"<<'c'<<'l';
  16.         C11LOG_INFO("%d-%f-%s-%c\n",1234,345.234,"kkkkkkk",'e');
  17.         C11LOG_DEBUG("%d-%f-%s-%c\n",1234,345.234,"kkkkkkk",'e');
  18.         C11LOG_WARN("%d-%f-%s-%c",1234,345.234,"kkkkkkk",'e');
  19.         C11LOG_ERROR("%d-%f-%s-%c",1234,345.234,"kkkkkkk",'e');
  20.     }
  21.     return 0;
  22. }
复制代码
运行效果:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4