GitHub地址:Plog - portable, simple and extensible C++ logging library
Plog is一个C++日志库,旨在保持尽可能的简单、小巧和灵活。它被创建作为现有大型库的替代品,并提供了一些独特的功能,如CSV日志格式和宽字符串支持。
主打一个小,灵活吗?
先来一段Demo
#include // 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 most
PLOGD << "Hello log!"; // short macro
PLOG_DEBUG << "Hello log!"; // long macro
PLOG(plog::debug) << "Hello log!"; // function-style macro
// Also you can use LOG_XXX macro but it may clash with other logging libraries
LOGD << "Hello log!"; // short macro
LOG_DEBUG << "Hello log!"; // long macro
LOG(plog::debug) << "Hello log!"; // function-style macro
return 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多行就实现了,还是有点厉害啊,有机会学习一波
你需要执行以下步骤:
#include
(如果你使用了预编译头文件,将这个 include 添加到那里是一个不错的选择)。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 printed
fatal = 1,
error = 2,
warning = 3,
info = 4,
debug = 5,
verbose = 6
};
日志格式会根据 fileName
文件扩展名自动确定:
.csv
=> CSV 格式滚动行为由 maxFileSize
和 maxFiles
参数控制:
maxFileSize
- 日志文件的最大大小(以字节为单位)maxFiles
- 保留的日志文件数量如果其中一个参数的值为零,则禁用日志滚动。
示例:
plog::init(plog::warning, "c:\\logs\\log.csv", 1000000, 5);
在这里,日志记录器被初始化为将所有最高严重性为警告的消息写入以 CSV 格式存储的文件。最大日志文件大小设置为 1,000,000 字节,同时保留 5 个日志文件。
PLOG_VERBOSE << "verbose";
PLOG_DEBUG << "debug";
PLOG_INFO << "info";
PLOG_WARNING << "warning";
PLOG_ERROR << "error";
PLOG_FATAL << "fatal";
PLOG_NONE << "none";
PLOGV << "verbose";
PLOGD << "debug";
PLOGI << "info";
PLOGW << "warning";
PLOGE << "error";
PLOGF << "fatal";
PLOGN << "none";
PLOG(severity) << "msg";
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,并将其传递给 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);
对于由多个二进制模块组成的应用程序,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);
}
}
}
}
这样可能在实际开发中,可能比较好操作一点。