前言
- 之前介绍过一个C语言日志库 轻量级c语言开源日志库log.c介绍,源代码只有不到200行,使用非常方便。
- 但是也存在很多缺点,比如日志时间只支持打印到秒,没有作多线程处理,不支持日志回滚。在小型项目或者测试demo中使用还可以,在大型项目中,就无法满足需求了。
- 于是又找到了一个C++日志库plog,虽然代码量较多,但使用也非常简单,并且功能非常强大,可以满足在大型项目中的使用需求。
plog简介
- plog 是一个轻量级、跨平台的C++日志库,它设计简洁且易于使用。有以下特点
- 简单易用: plog 提供了直观的API,允许开发者以简洁的方式在代码中添加日志记录功能。例如,通过LOGD, LOGI, LOGW, LOGE等宏定义来分别表示不同级别的日志输出(如debug、info、warning和error)。
- 多线程支持: plog 设计为线程安全的,可以安全地在多线程环境下使用,确保各个线程的日志记录不会相互干扰。
- 多种日志级别: 支持多种日志级别,可以根据需要调整输出的日志详细程度,只显示重要信息或者包括所有调试细节。
- 文件回滚与滚动日志: plog 允许配置日志文件的大小限制和循环策略,当达到一定大小时会自动创建新的日志文件,以实现日志的滚动存储。
- 异步/同步日志写入: 可以根据需求选择同步或异步的方式来写入日志,提高程序性能,尤其是在大量日志产生时。
- 可扩展性: plog 提供了自定义appender的能力,用户可以创建自己的日志接收器,将日志输出到各种不同的目标,如文件、数据库、网络等。
- 跨平台兼容: plog 能够在多个操作系统和编译器下运行,如Windows、Linux、macOS等,并且兼容多种C++标准。
- 体积小巧: plog 的源代码量小,占用资源少,适合嵌入式系统或其他对体积敏感的应用场景
使用步骤
- 下载源代码后,将根目录下include目录下的所有文件拷贝到我们自己的工程下,然后在工程中包含对应的头文件即可。
使用示例
基本功能
- 通过一个示例演示下基本功能。
- 测试代码 : main.cpp
-
#include <plog/Log.h> // Step1: include the header. #include <plog/Initializers/RollingFileInitializer.h> #include <plog/Appenders/ColorConsoleAppender.h> #include <string.h> #include <iostream> #include <iomanip> void polgFunc(){ PLOG_DEBUG << "DEBUG join polgFunc func"; PLOG_INFO << "DEBUG join polgFunc func"; PLOG_ERROR << "DEBUG join polgFunc func"; } int main() { // 日志初始化 // 参数1 - 日志级别, 参数2 - 日志文件名, 参数3 - 单个日志大小, 参数4 - 日志回滚数 // 如果不想实现日志回滚,参数3和参数4可以不填或者填0 plog::init(plog::info, "plog.log", 1024, 5); // 同时打印到控制台 plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender; plog::get()->addAppender(&consoleAppender); // Also add logging to the console. int iData = 10020; double fData = 3.141592654; std::string sData = "hello plog"; PLOG_DEBUG << "debug hello log!"; LOG_INFO << "info hello log!"; PLOG_WARNING << "warning hello log!"; PLOG_ERROR << "error hello log!"; PLOG_INFO << "int data : " << iData; PLOG_INFO << "int hex data : " << std::hex << iData; PLOG_INFO << "float data : " << fData; PLOG_INFO << "float data : " << std::fixed << std::setprecision(2) << fData; PLOG_INFO << "string data : " << fData; polgFunc(); system("pause"); return 0; }
- 控制台打印
- 文件打印:在当前目录下会生成一个 plog.log 文件
- 日志回滚 : 文件超出我们设置的大小后,可以自动回滚
进阶功能 - 自定义日志打印格式
- 对测试代码进行修改 main.cpp
-
#include <plog/Log.h> // Step1: include the header. #include <plog/Initializers/RollingFileInitializer.h> #include <plog/Appenders/ColorConsoleAppender.h> #include <string.h> #include <iostream> #include <iomanip> // 自定义日志格式器 namespace plog { class MyFormatter { public: static util::nstring header() // This method returns a header for a new file. In our case it is empty. { return util::nstring(); } static util::nstring format(const Record& record) // This method returns a string from a record. { util::nostringstream ss; util::Time t; t.time = record.getTime().time; struct tm *ltime = localtime(&t.time); t.millitm = record.getTime().millitm; // 在这里设置日志打印的格式 ss << "[plog] ["<<ltime->tm_year + 1900 <<"/"<< std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_mon + 1 <<"/"<< std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_mday << "_"; ss << std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_hour << PLOG_NSTR(":") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_min << PLOG_NSTR(":") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << ltime->tm_sec << "."; ss << std::setfill(PLOG_NSTR('0')) << std::setw(3) <<t.millitm << "] "; ss << std::setw(5) << std::left << std::setfill(PLOG_NSTR(' ')) <<severityToString(record.getSeverity()) <<" [" << record.getTid()<< "]"<<" [" << record.getFunc() << ":" << record.getLine() << "] " << record.getMessage() << "\n"; return ss.str(); } }; } void polgFunc(){ PLOG_DEBUG << "DEBUG join polgFunc func"; PLOG_INFO << "DEBUG join polgFunc func"; PLOG_ERROR << "DEBUG join polgFunc func"; } int main() { // 日志初始化 // 参数1 - 日志级别, 参数2 - 日志文件名, 参数3 - 单个日志大小, 参数4 - 日志回滚数 // 如果不想实现日志回滚,参数3和参数4可以不填或者填0 // plog::init(plog::info, "plog.log", 1024, 5); plog::init<plog::MyFormatter>(plog::info, "plogformat.log", 1024, 5); // 同时打印到控制台 plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender; plog::get()->addAppender(&consoleAppender); // Also add logging to the console. int iData = 10020; double fData = 3.141592654; std::string sData = "hello plog"; PLOG_DEBUG << "debug hello log!"; LOG_INFO << "info hello log!"; PLOG_WARNING << "warning hello log!"; PLOG_ERROR << "error hello log!"; PLOG_INFO << "int data : " << iData; PLOG_INFO << "int hex data : " << std::hex << iData; PLOG_INFO << "float data : " << fData; PLOG_INFO << "float data : " << std::fixed << std::setprecision(2) << fData; PLOG_INFO << "string data : " << fData; polgFunc(); system("pause"); return 0; }
- 文件打印:再运行看下文件中的打印
- 可以看到,打印的格式就是我们自定义的格式。