欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 基于C11的简单log,支持C++的‘<<’风格和C的‘可变参数’风格

基于C11的简单log,支持C++的‘<<’风格和C的‘可变参数’风格

2024/10/25 13:30:28 来源:https://blog.csdn.net/qq_33232152/article/details/141028390  浏览:    关键词:基于C11的简单log,支持C++的‘<<’风格和C的‘可变参数’风格

基于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;
}

运行结果:
日志测试结果

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com