当前位置: 首页 > news >正文

【C++】plog

GitHub地址:Plog - portable, simple and extensible C++ logging library

介绍

Plog is一个C++日志库,旨在保持尽可能的简单、小巧和灵活。它被创建作为现有大型库的替代品,并提供了一些独特的功能,如CSV日志格式和宽字符串支持。

主打一个小,灵活吗?

先来一段Demo

#include <plog/Log.h> // Step1: include the headers
#include "plog/Initializers/RollingFileInitializer.h"int main()
{plog::init(plog::debug, "Hello.txt"); // Step2: initialize the logger// Step3: write log messages using a special macro// There are several log macros, use the macro you liked the mostPLOGD << "Hello log!"; // short macroPLOG_DEBUG << "Hello log!"; // long macroPLOG(plog::debug) << "Hello log!"; // function-style macro// Also you can use LOG_XXX macro but it may clash with other logging librariesLOGD << "Hello log!"; // short macroLOG_DEBUG << "Hello log!"; // long macroLOG(plog::debug) << "Hello log!"; // function-style macroreturn 0;
}

输出:

2015-05-18 23:12:43.921 DEBUG [21428] [main@13] Hello log!
2015-05-18 23:12:43.968 DEBUG [21428] [main@14] Hello log!
2015-05-18 23:12:43.968 DEBUG [21428] [main@15] Hello log!

日志有的都有了,怎么设置日志的格式,模式, 怎么输出到文件呢?

Here is the translation of the provided information:

  • 非常小(略多于1000行代码)
  • 易于使用
  • 仅包含头文件
  • 没有第三方依赖
  • 跨平台支持:Windows、Linux、FreeBSD、macOS、Android、RTEMS(gcc、clang、msvc、mingw、mingw-w64、icc、c++builder)
  • 线程安全和类型安全
  • 格式化器:TXT、CSV、FuncMessage、MessageOnly
  • 输出器:RollingFile、Console、ColorConsole、Android、EventLog、DebugOutput、DynamicAppender
  • 自动捕获 ‘this’ 指针(仅在 msvc 上支持)
  • 惰性流评估
  • 兼容 Unicode,文件以 UTF-8 存储,支持 Utf8Everywhere
  • 不要求 C++11
  • 可扩展
  • 没有对 windows.h 的依赖
  • 可使用 UTC 或本地时间
  • 可以以 HEX 或 ASCII 打印缓冲区
  • 可以打印 std 容器
  • 使用现代 CMake

1000多行就实现了,还是有点厉害啊,有机会学习一波

使用说明

Step1 导入头文件

你需要执行以下步骤:

  1. 将 plog/include 添加到项目的包含路径中。
  2. 在你的 cpp/h 文件中添加 #include <plog/Log.h>(如果你使用了预编译头文件,将这个 include 添加到那里是一个不错的选择)。

Step2 初始化

Logger& init(Severity maxSeverity, const char/wchar_t* fileName, size_t maxFileSize = 0, int maxFiles = 0
);

-maxSeverity 是日志记录器的严重性上限。所有日志消息都有其自己的严重性,如果它高于设定的上限,那么这些消息将被丢弃。Plog 定义了以下严重性级别:

enum Severity
{none = 0, // will always be printedfatal = 1,error = 2,warning = 3,info = 4,debug = 5,verbose = 6
};

日志格式会根据 fileName 文件扩展名自动确定:

  • .csv => CSV 格式
  • 其他任何扩展名 => TXT 格式

滚动行为由 maxFileSizemaxFiles 参数控制:

  • maxFileSize - 日志文件的最大大小(以字节为单位)
  • maxFiles - 保留的日志文件数量

如果其中一个参数的值为零,则禁用日志滚动。

示例:

plog::init(plog::warning, "c:\\logs\\log.csv", 1000000, 5);

在这里,日志记录器被初始化为将所有最高严重性为警告的消息写入以 CSV 格式存储的文件。最大日志文件大小设置为 1,000,000 字节,同时保留 5 个日志文件。

Step3 打log

Long macros:

PLOG_VERBOSE << "verbose";
PLOG_DEBUG << "debug";
PLOG_INFO << "info";
PLOG_WARNING << "warning";
PLOG_ERROR << "error";
PLOG_FATAL << "fatal";
PLOG_NONE << "none";

Short macros:

PLOGV << "verbose";
PLOGD << "debug";
PLOGI << "info";
PLOGW << "warning";
PLOGE << "error";
PLOGF << "fatal";
PLOGN << "none";

Function-style macros:

PLOG(severity) << "msg";

Conditional logging macros

PLOG_VERBOSE_IF(cond) << "verbose";
PLOG_DEBUG_IF(cond) << "debug";
PLOG_INFO_IF(cond) << "info";
PLOG_WARNING_IF(cond) << "warning";
PLOG_ERROR_IF(cond) << "error";
PLOG_FATAL_IF(cond) << "fatal";
PLOG_NONE_IF(cond) << "none";PLOGV_IF(cond) << "verbose";
PLOGD_IF(cond) << "debug";
PLOGI_IF(cond) << "info";
PLOGW_IF(cond) << "warning";
PLOGE_IF(cond) << "error";
PLOGF_IF(cond) << "fatal";
PLOGN_IF(cond) << "none";

Appender

有时候我们想在终端和文件同时输出,就需要用到Appender的概念了。你需要构造一个带有格式化器的 Appender,并将其传递给 plog::init 函数。

Logger& init(Severity maxSeverity = none, IAppender* appender = NULL);
static plog::ConsoleAppender<plog::TxtFormatter> consoleAppender;
plog::init(plog::debug, &consoleAppender);

如何使用多个Appender? 可以在一个单独的日志记录器中拥有多个 Appender。在这种情况下,日志消息将被写入所有这些 Appender。使用以下方法来实现这一点:

Logger& Logger::addAppender(IAppender* appender);

示例:

 // Create the 1st appender.
static plog::RollingFileAppender<plog::CsvFormatter> fileAppender("MultiAppender.csv", 8000, 3);// Create the 2nd appender.
static plog::ConsoleAppender<plog::TxtFormatter> consoleAppender;
// Initialize the logger with the both appenders.
plog::init(plog::debug, &fileAppender).addAppender(&consoleAppender); 

跨模块共享log

对于由多个二进制模块组成的应用程序,plog 实例可以是本地的(每个模块都有自己的实例)或共享的(所有模块使用相同的实例)。在共享的情况下,你只需在一个模块中初始化 plog,其他模块将重用该实例。
在 Windows 上进行共享,一个模块应该使用 PLOG_EXPORT,而其他模块应该使用 PLOG_IMPORT。此外,在 Linux/Unix 上要小心,如果不指定共享行为,它将由编译器设置(-fvisibility)来确定。

其实我觉得共享 Appender 可能操作起来比较方便,

比如在 exe 里面有一个日志:

plog::Severity maxSeverity = plog::debug;
std::string logPath = "mylog.log";
//max 5MB, loop 3 files
static plog::RollingFileAppender<plog::TxtFormatter> fileAppender(logPath.c_str(), 1024 * 1024 * 5, 3);// Create the 2nd appender.
static plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender;
// Initialize the logger with the both appenders.
plog::init(maxSeverity, &fileAppender).addAppender(&consoleAppender); mylib.init(maxSeverity , plog::get())

在lib 中定义:

void init(int logSeverity, plog::IAppender* appender)
{if (plog::get() == nullptr) {if (appender != nullptr) {if (logSeverity >= 0 && logSeverity <= 6) {plog::init((plog::Severity)logSeverity, appender);}else {plog::init(plog::Severity::verbose, appender);}}}
}

这样可能在实际开发中,可能比较好操作一点。

相关文章:

  • HTML5学习系列之网页图像
  • SELinux零知识学习十八、SELinux策略语言之类型强制(3)
  • JVM bash:jmap:未找到命令 解决
  • 验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
  • 创建一个用户test且使用testtab表空间及testtemp临时表空间并授予其权限,密码随意
  • Linux终端与交互式Bash
  • uniapp 手动调用form表单submit事件
  • C#,数值计算——插值和外推,曲线插值(Curve_interp)的计算方法与源程序
  • 【Oracle 客户端连接数据库过程解析】
  • 若依启动步骤
  • 数据采集与大数据架构分享
  • Spring Boot - filter 的顺序
  • 三十分钟学会zookeeper
  • uniapp app tabbar 页面默认隐藏
  • 【【萌新的SOC学习之 VDMA 彩条显示实验之一】】
  • 2018一半小结一波
  • CentOS 7 防火墙操作
  • CSS居中完全指南——构建CSS居中决策树
  • es6要点
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • opencv python Meanshift 和 Camshift
  • scrapy学习之路4(itemloder的使用)
  • Vultr 教程目录
  • 从tcpdump抓包看TCP/IP协议
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 关于Flux,Vuex,Redux的思考
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 使用Gradle第一次构建Java程序
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  •  一套莫尔斯电报听写、翻译系统
  • 智能网联汽车信息安全
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​学习一下,什么是预包装食品?​
  • ###C语言程序设计-----C语言学习(3)#
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #Z2294. 打印树的直径
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (Oracle)SQL优化技巧(一):分页查询
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (六)Hibernate的二级缓存
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (一)appium-desktop定位元素原理
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • *上位机的定义
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .NET 设计模式初探
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • @Autowired注解的实现原理
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [20171113]修改表结构删除列相关问题4.txt
  • [AIGC] Spring Interceptor 拦截器详解
  • [C++]Leetcode17电话号码的字母组合