日志库EasyLogging++学习系列(3)—— 配置功能
来源:互联网 发布:条形码进销存软件 编辑:程序博客网 时间:2024/05/22 05:07
要完成 Easylogging++ 日志的配置功能,可以通过三种方法去实现,而且每一种方法都非常简单。第一种方法就是使用配置文件,这种方法的好处就是只要修改配置文件即可实现日志格式的重新配置,而不需要修改源程序代码,缺点就是发布程序时必须打包配置文件一起发布,否则程序无法正常运行。在一些小项目中,特别是在只有一个EXE运行文件的程序中,如果我们不希望程序带着一个多余的日志配置文件,那么我们可以使用另外一种方法,就是使用 el::Configurations 类提供的成员函数,这种方法和第一种方法的优缺点刚好相反。最后一种方法就是使用 Easylogging++ 的内联配置功能,但是并不推荐使用这种方法,因为它会显得配置十分凌乱。
方法一:使用配置文件
在程序运行时,可以通过使用 el::Configurations 类加载配置文件来完成 Easylogging++ 的配置功能,配置文件必须遵循下面的语法:
- * LEVEL:
- CONFIGURATION NAME = "VALUE" ## Comment
- CONFIGURATION NAME = "VALUE"
语法简要说明如下:
- *LEVEL,指的是日志级别,以星号符“*”开始,并以英文冒号“:”结束。
- CONFIGURATION NAME ,指的是配置项的名称,全部名称详见下面的表格。
- "VALUE",指的是配置项的值,各个配置项对应的值类型详见下面的表格。
- ## Comment,指的是注释,其中两个连续井号"##"表示注释,Comment是注释的内容。注释是可有可无的,但是千万不要在注释中使用双引号,否则可能会出现意想不到的错误。
编写配置文件时,强烈建议先写 Global 级别的配置,这样的好处是可以使其他任何未在配置文件中明确指出的级别都将会自动地继承并使用 Global 级别的配置。比如,如果你想把所有级别的日志都保存在同一个文件里,你只需要在 Global 级别中设置 Filename 就可以了,其他级别的日志将会默认的使用 Global 级别中的 Filename 。下面的表格列举了GitHub上给出的Easylogging++在配置文件中支持的配置项:
Enabled
boolDetermines whether or not corresponding level for logger is enabled. You may disable all logs by usingel::Level::Global
To_File
boolWhether or not to write corresponding log to log fileTo_Standard_Output
boolWhether or not to write logs to standard output e.g, terminal or command promptFormat
char*Determines format/pattern of logging for corresponding level and logger.Filename
char*Determines log file (full path) to write logs to for corresponding level and loggerMilliseconds_Width
uintSpecifies milliseconds width. Width can be within range (1-6)Performance_Tracking
boolDetermines whether or not performance tracking is enabled. This does not depend on logger or level. Performance tracking always uses 'performance' logger unless specifiedMax_Log_File_Size
size_tIf log file size of corresponding level is >= specified size, log file will be truncated.Log_Flush_Threshold
size_tSpecifies number of log entries to hold until we flush pending log data下面再回顾一下《日志库Easylogging++学习系列(1) —— 简要介绍 》这篇文章中给出的名称为 my_log.conf 的配置文件:
- * GLOBAL:
- ENABLED = true
- TO_FILE = true
- TO_STANDARD_OUTPUT = true
- FORMAT = "[%level | %datetime] | %msg"
- FILENAME = "log\\log_%datetime{%Y%M%d}.log"
- MILLISECONDS_WIDTH = 3
- PERFORMANCE_TRACKING = false
- MAX_LOG_FILE_SIZE = 1048576
- LOG_FLUSH_THRESHOLD = 0
- * TRACE:
- FILENAME = "log\\trace_log_%datetime{%Y%M%d}.log"
- * DEBUG:
- FILENAME = "log\\debug_log_%datetime{%Y%M%d}.log"
- * FATAL:
- ENABLED = false
- * ERROR:
- FILENAME = "log\\error_log_%datetime{%Y%M%d}.log"
- * WARNING:
- FILENAME = "log\\warning_log_%datetime{%Y%M%d}.log"
- * INFO:
- FILENAME = "log\\info_log_%datetime{%Y%M%d}.log"
- * VERBOSE:
- ENABLED = false
在上面的文件中,我们以 Global 级别开始,并在 Global 级别中把 Easylogging++ 支持的所有的配置项都设置好了,这样 Global 级别的配置就会被后续的日志级别所继承,一直到后续的日志级别再次明确地设置配置项才会覆盖原有的来自于 Global 级别的配置。比如这里的TRACE、DEBUG、ERROR、WARNING、INFO等级别都显式地定义了 Filename ,所以这几个级别的日志记录会各自保存在相应的文件里面。而FATAL、VERBOSE这两个级别则显式地定义了 ENABLE ,并将其值设置为false,所以这两个级别的日志记录将会被禁用。下面的代码再次演示如何使用该配置文件(注意注释的内容):
- #include "easylogging++.h"
- INITIALIZE_EASYLOGGINGPP
- int main(int argc, char** argv)
- {
- /*/////////////////////////////////////////////////////////////////////////
- 必须设置标记 LoggingFlag::StrictLogFileSizeCheck
- 否则,配置文件中MAX_LOG_FILE_SIZE = 1048576不生效
- /////////////////////////////////////////////////////////////////////////*/
- el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck);
- el::Configurations conf("my_log.conf");
- /// 可以单独设置某一个logger的配置
- el::Loggers::reconfigureLogger("default", conf);
- /// 也可以设置全部logger的配置
- el::Loggers::reconfigureAllLoggers(conf);
- LOG(INFO) << "***** info log *****";
- system("pause");
- return 0;
- }
方法二:使用 el::Configurations 类的成员函数
在 Easylogging++ 日志库中,封装了配置类 el::Configurations,该类提供了完成日志配置功能的全部接口,建议参考该类的源码,可以查看和了解更多更详细和更全面的功能接口。下面的代码演示了几个常用接口的用法:
- #include "easylogging++.h"
- INITIALIZE_EASYLOGGINGPP
- int main(int argc, const char** argv)
- {
- /// 使用默认配置
- el::Configurations defaultConf;
- defaultConf.setToDefault();
- LOG(INFO) << "Using el::Configurations class";
- /// 重新设置INFO级别的配置项FORMAT的值
- defaultConf.set(el::Level::Info,
- el::ConfigurationType::Format, "%datetime %level %msg");
- /// 重新设置配置
- el::Loggers::reconfigureLogger("default", defaultConf);
- LOG(INFO) << "Using el::Configurations class";
- // 重新设置GLOBAL级别的配置项FORMAT的值
- defaultConf.setGlobally(
- el::ConfigurationType::Format, "%datetime %msg");
- /// 重新设置配置
- el::Loggers::reconfigureLogger("default", defaultConf);
- LOG(INFO) << "Using el::Configurations class";
- system("pause");
- return 0;
- }
方法三:使用内联配置功能
所谓的内联配置功能,就是说你可以通过使用 std::string 字符串来完成日志的配置功能,但是要注意在 std::string 字符串中加上换行符保证字符串的格式遵循配置文件中的格式。比如,如果要使用内联配置功能实现和方法二中一样的输出格式,那么实现代码必须像下面这样:
- #include "easylogging++.h"
- INITIALIZE_EASYLOGGINGPP
- int main(int argc, const char** argv)
- {
- /// 使用默认配置
- el::Configurations defaultConf;
- defaultConf.setToDefault();
- LOG(INFO) << "Using inline configuration";
- /// 重新设置INFO级别的配置项FORMAT的值
- defaultConf.parseFromText("*INFO:\n FORMAT = %datetime %level %msg");
- /// 重新设置配置
- el::Loggers::reconfigureLogger("default", defaultConf);
- LOG(INFO) << "Using inline configuration";
- // 重新设置GLOBAL级别的配置项FORMAT的值
- defaultConf.parseFromText("*INFO:\n FORMAT = %datetime %msg");
- /// 重新设置配置
- el::Loggers::reconfigureLogger("default", defaultConf);
- LOG(INFO) << "Using inline configuration";
- system("pause");
- return 0;
- }
默认配置功能
如果你希望为现有的或者将来新建的日志记录器设置一个默认的配置,你可以使用下面的这个函数:
- el::Loggers::setDefaultConfigurations(el::Configurations& configurations, bool configureExistingLoggers = false)
- #include "easylogging++.h"
- INITIALIZE_EASYLOGGINGPP
- int main(void)
- {
- el::Configurations defaultConf;
- defaultConf.setGlobally(el::ConfigurationType::Format, "[%logger] %level: %msg");
- /// 只为新建的日志记录器设置默认配置
- el::Loggers::setDefaultConfigurations(defaultConf);
- LOG(INFO) << "Set default configuration but existing loggers not updated yet";
- /// 新建日志记录器 testDefaultConf1
- el::Loggers::getLogger("testDefaultConf1");
- CLOG(INFO, "testDefaultConf1") << "Logging using new logger 1";
- // 为现有的日志记录器设置默认配置
- el::Loggers::setDefaultConfigurations(defaultConf, true);
- LOG(INFO) << "Existing loggers updated as well";
- /// 新建日志记录器 testDefaultConf2
- el::Loggers::getLogger("testDefaultConf2");
- CLOG(INFO, "testDefaultConf2") << "Logging using new logger 2";
- system("pause");
- return 0;
- }
全局配置并不是指 Global 级别,而是指利用全局配置文件为全部或部分,甚至是为新建的日志记录器注册配置。全局配置文件必须遵循下面的语法:
- -- LOGGER ID ## Case sensitive
- ## Everything else is same as configuration file
- -- ANOTHER LOGGER ID
- ## Configuration for this logger
- LOGGER ID ,指的是记录器 ID,大小写敏感,并以两个破折号开始。
- 其余部分的语法规则和本文中方法一的配置文件的语法规则完全一样。
- #include "easylogging++.h"
- INITIALIZE_EASYLOGGINGPP
- int main(void)
- {
- LOG(INFO) << "Info log before using global configuration";
- /// 只需一个函数即可实现全局配置功能
- el::Loggers::configureFromGlobal("global.conf");
- LOG(INFO) << "Info log AFTER using global configuration";
- LOG(ERROR) << "Error log AFTER using global configuration";
- /// 用全局配置文件中新建的日志记录器 testGlobalConf 来记录日志
- CLOG(TRACE, "testGlobalConf") << "TRACE Logging using new logger";
- CLOG(DEBUG, "testGlobalConf") << "DEBUG Logging using new logger";
- CLOG(WARNING, "testGlobalConf") << "WARNING Logging using new logger";
- CLOG(ERROR, "testGlobalConf") << "ERROR Logging using new logger";
- CLOG(INFO, "testGlobalConf") << "INFO Logging using new logger";
- system("pause");
- return 0;
- }
- -- default
- *INFO:
- FORMAT = "%level %msg"
- FILENAME = "/tmp/logs/wow.log"
- *ERROR:
- FORMAT = "%levshort %fbase:%line %msg"
- -- testGlobalConf
- *GLOBAL:
- FORMAT = "[%level | %datetime] | %msg"
- ENABLED = true
- TO_FILE = true
- TO_STANDARD_OUTPUT = true
- MILLISECONDS_WIDTH = 3
- el::Logger* defaultLogger = el::Loggers::getLogger("default");
- /// 记录器default是否被禁用
- bool enabled = defaultLogger->typedConfigurations()->enabled(el::Level::Info);
- /// 记录器default的INFO级别的日志输出格式
- std::string format = defaultLogger->typedConfigurations()->logFormat(el::Level::Info).format();
- 日志库EasyLogging++学习系列(3)—— 配置功能
- 日志库EasyLogging++学习系列(3)—— 配置功能
- 日志库EasyLogging++学习系列(5)—— 辅助配置功能
- 日志库EasyLogging++学习系列(5)—— 辅助配置功能
- 日志库EasyLogging++学习系列(9)—— 性能跟踪功能
- 日志库EasyLogging++学习系列(9)—— 性能跟踪功能
- 日志库EasyLogging++学习系列(11)—— 共享日志库
- 日志库EasyLogging++学习系列(11)—— 共享日志库
- 日志库EasyLogging++学习系列(2)—— 日志级别
- 日志库EasyLogging++学习系列(6)—— 日志记录器
- 日志库EasyLogging++学习系列(8)—— Verbose日志详解
- 日志库EasyLogging++学习系列(10)—— 日志文件滚动
- 日志库EasyLogging++学习系列(2)—— 日志级别
- 日志库EasyLogging++学习系列(6)—— 日志记录器
- 日志库EasyLogging++学习系列(8)—— Verbose日志详解
- 日志库EasyLogging++学习系列(10)—— 日志文件滚动
- 日志库EasyLogging++学习系列(1)—— 简要介绍
- 日志库EasyLogging++学习系列(4)—— 格式说明符
- php查询数据库的数据已存在
- 关于oracle的将字符串转换成多行
- C语言也有大学问——free()函数详解
- triplet loss layer原理
- 工具类之SpannableStringUtils(相信你会爱上它)
- 日志库EasyLogging++学习系列(3)—— 配置功能
- Android产品研发(十二)-->App长连接实现
- Redis事务与主从复制(笔记)
- day03
- vi(vim)的常用快捷键
- AC算法
- jQuery事件对象---常见属性
- SMTP邮件发送不成功(所有文件留在Queue)
- day04