上一篇:Easylogging++入门教程(二)开始使用Easylogging++
三、Easylogging++ 配置
3.1 日志级别Level
Level | 描述/解释 |
---|---|
Global | 通用级别。用于全局配置所有级别
(Generic level that represents all levels. Useful when setting global configuration for all levels) |
Trace | Information that can be useful to back-trace
certain events – mostly useful than debug logs. |
Debug | Informational events most useful for developers to debug application.
Only applicable if NDEBUG is not defined (for non-VC++) or _DEBUG is defined (for VC++). |
Fatal | Very severe error event that will presumably lead the application to abort. |
Error | Error information but will continue application to keep running. |
Warning | Information representing errors in application but application will keep running. |
Info | Mainly useful to represent current progress of application. |
Verbose | Information that can be highly useful and vary with verbose logging level.
Verbose logging is not applicable to hierarchical logging. |
Unknown | Only applicable to hierarchical logging and is used to turn off logging completely. |
3.2 配置
Easylogging++配置方法很简单。有三种配置方式:
- 使用配置文件
- 使用 el::Configurations 类
- 使用内联配置 inline configuration
3.2.1 使用配置文件
Configurations
类可以在运行时从从文件加载配置信息。文件格式如下:
* LEVEL:
CONFIGURATION NAME = "VALUE" ## Comment
ANOTHER CONFIG NAME = "VALUE"
Level 名称以星号(*)开始,以冒号(:)结束。强烈建议在配置文件最前面添加 Global
level ,这样在文件中未找到匹配级别的日志会自动按照 Global 设置。比如,你在 Global
中设置 Filename
,所有级别的日志都可使用这一 Filename
,而无需单独对每个级别进行配置,Easylogging++库会自动使用 Global
的配置。配置文件支持的配置内容见下表:
Configuration Name | Type | Description |
---|---|---|
Enabled |
bool | Determines whether or not corresponding level for logger is enabled.
You may disable all logs by using |
To_File |
bool | Whether or not to write corresponding log to log file |
To_Standard_Output |
bool | Whether or not to write logs to standard output e.g, terminal or command prompt |
Format |
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 logger |
Milliseconds_Width |
uint | Specifies milliseconds width. Width can be within range (1-6) |
Performance_Tracking |
bool | Determines whether or not performance tracking is enabled.
This does not depend on logger or level. Performance tracking always uses ‘performance’ logger unless specified |
Max_Log_File_Size |
size_t | If log file size of corresponding level is >= specified size,
log file will be truncated. |
Log_Flush_Threshold |
size_t | Specifies number of log entries to hold until we flush pending log data |
注意:不要在注释中的任何位置使用双引号,否则可能会产生未知的结果。
配置文件样本如下:
* GLOBAL:
FORMAT = "%datetime %msg"
FILENAME = "/tmp/logs/my.log"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = true
MILLISECONDS_WIDTH = 6
PERFORMANCE_TRACKING = true
MAX_LOG_FILE_SIZE = 2097152 ## 2MB - Comment starts with two hashes (##)
LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs
* DEBUG:
FORMAT = "%datetime{%d/%M} %func %msg"
解释
上面示例代码给出的配置文件很典型。先设置 GLOBAL
级别,可以供所有级别公用设置。后续添加的子级别进行的单独设置可以覆盖 GLOBAL
的相应设置。如:除 DEBUG
以外的所有级别使用相同的 format 设置,即 datetime and log message。至于 DEBUG
level,其format 包含 date (with day and month), source function and log message。 DEBUG
的其他项目配置继承自 GLOBAL
。
注意:DEBUG
的 format 中 {%d/%M}
, 如果不指定日期格式,择使用默认日期格式: %d/%M/%Y %h:%m:%s,%g
关于格式的更多信息,请参考下面的 日期/时间 标识符 (Date/Time Format Specifier) 部分。
用法实例
#include "easylogging++.h" INITIALIZE_EASYLOGGINGPP int main(int argc, const char** argv) { // Load configuration from file el::Configurations conf("/path/to/my-conf.conf"); // Reconfigure single logger el::Loggers::reconfigureLogger("default", conf); // Actually reconfigure all loggers instead el::Loggers::reconfigureAllLoggers(conf); // Now all the loggers will use configuration from file }
就像上面的实例一样,你可以使用 el::Configurations
对象的构造函数方便的加载配置文件。
3.2.2 使用 el::Configurations 类进行配置
你可以使用 el::Configurations 类对配置进行修改和复位。
#include "easylogging++.h" INITIALIZE_EASYLOGGINGPP int main(int argc, const char** argv) { el::Configurations defaultConf; defaultConf.setToDefault(); // Values are always std::string defaultConf.set(el::Level::Info, el::ConfigurationType::Format, "%datetime %level %msg"); // default logger uses default configurations el::Loggers::reconfigureLogger("default", defaultConf); LOG(INFO) << "Log using default file"; // To set GLOBAL configurations you may use defaultConf.setGlobally( el::ConfigurationType::Format, "%date %msg"); el::Loggers::reconfigureLogger("default", defaultConf); return 0; }
只需进行一次设置,后续的日志都会按照配置进行记录。你也可以使用默认的设置。
3.2.3 使用内联方式配置
内联配置Inline configuration 是指你可以传递 std::string
参数给 el::Configurations 类的对象,该对象从字符串解析配置。记得在字符串中添加换行符,以使字符串保持配置文件内容的格式。该种方式不推荐使用,因为其容易出错。
el::Configurations c;
c.setToDefault();
c.parseFromText("*GLOBAL:\n FORMAT = %level %msg");
以上代码仅是对 Configurations 类的实例进行了设置,要应用这些配置,需要使用该类实例来配置 日志类实例。
3.3 设置默认配置
当你需要对现有的或者新创建的logger应用某一配置为默认配置时,你可以使用函数el::Loggers::setDefaultConfigurations(el::Configurations& configurations, bool configureExistingLoggers = false)
来实现。
当你在编写大型软件或调用的第三方库也使用Easylogging++时,使用上面的函数可以很方便的设置后续新建logger或者现存logger的配置。 第二个参数为 true
时,就会将后续新建logger以及现有的logger都取第一个参数作为默认配置,(第二个参数默认为 false
即不对现有logger应用此项配置,而只对后续新建logger起作用)。
3.4 全局配置
这里的全局配置和上面提到的 Level::Global
是两码事。 Level::Global
是指日志记录器logger在输出日志时使用的全局格式配置;而此处的全局配置则是指给所有或者某些指定日志记录器注册配置。相当于上面提到的多个配置文件整合到一个文件中。一次加载,对所有日志记录器均完成了配置。
全局配置文件示例:
-- LOGGER ID ## Case sensitive
## Everything else is same as configuration file
-- ANOTHER LOGGER ID
## Configuration for this logger
Logger ID 是区分大小写的,以”–“开始。一旦这个全局配置文件写好,你就可以使用一个函数完成所有的日志记录器的配置,甚至可以创建新的日志记录器。
int main(void) { // Registers new and configures it or // configures existing logger - everything in global.conf el::Loggers::configureFromGlobal("global.conf"); // .. Your prog return 0; }
注意:如果想在全局配置中注册新的logger,必须给该logger提供至少一项配置。关于其它的注册logger的方式,会在下一篇介绍。
3.5 日志格式标识符
Easylogging++提供很多格式标识符,用于自定义输出日志的格式。标识符见下表:
Specifier | Replaced By |
---|---|
%logger |
Logger ID |
%thread |
Thread ID – Uses std::thread if available, otherwise GetCurrentThreadId() on windows |
%level |
Severity level (Info, Debug, Error, Warning, Fatal, Verbose, Trace) |
%levshort |
Severity level (Short version i.e, I for Info and respectively D, E, W, F, V, T) |
%vlevel |
Verbosity level (Applicable to verbose logging) |
%datetime |
Date and/or time – Pattern is customizable – see Date/Time Format Specifiers below |
%user |
User currently running application |
%host |
Computer name application is running on |
%file |
File name of source file (Full path) |
%fbase |
File name of source file (Only base name) |
%line |
Source line number |
%func |
Logging function |
%loc |
Source filename and line number of logging (separated by colon) |
%msg |
Actual log message |
% |
Escape character (e.g, %%level will write %level) |
除了上面列出的内置的格式标识符,你还可以自己定义新的格式标识符。调用el::Helpers::installCustomFormatSpecifier
可以实现该功能。 下面的代码实例演示为 TCP 服务器程序的日志记录新增 %ip_addr
日志格式标识符。
const char* getIp(void) { return "192.168.1.1"; } int main(void) { el::Helpers::installCustomFormatSpecifier(el::CustomFormatSpecifier("%ip_addr", getIp)); el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Format, "%datetime %level %ip_addr : %msg"); LOG(INFO) << "This is request from client"; return 0; }
3.6 日期/时间 格式标识符 Date/Time Format Specifiers
你可以自定义日志输出格式中关于 date/time 的输出格式,相关标识符如下:
Specifier | Replaced By |
---|---|
%d |
Day of month (zero-padded) |
%a |
Day of the week – short (Mon, Tue, Wed, Thu, Fri, Sat, Sun) |
%A |
Day of the week – long (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday) |
%M |
Month (zero-padded) |
%b |
Month – short (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) |
%B |
Month – Long (January, February, March, April, May, June, July, August, September, October, November, December) |
%y |
Year – Two digit (13, 14 etc) |
%Y |
Year – Four digit (2013, 2014 etc) |
%h |
Hour (12-hour format) |
%H |
Hour (24-hour format) |
%m |
Minute (zero-padded) |
%s |
Second (zero-padded) |
%g |
Milliseconds (width is configured by ConfigurationType::MillisecondsWidth) |
%F |
AM/PM designation |
% |
Escape character |
注意,日期时间 date/time 最长不能超过 30 个字符。
3.7 日志标志 Logging Flags
你可以设置某些日志标志来控制日志输出的格式。
Flag | Description |
---|---|
NewLineForContainer (1) |
Makes sure we have new line for each container log entry |
AllowVerboseIfModuleNotSpecified (2) |
Makes sure if -vmodule is used and does not specifies a module, then verbose logging is allowed via that module. Say param was -vmodule=main*=3 and a verbose log is being written from a file called something.cpp then if this flag is enabled, log will be written otherwise it will be disallowed. Note: having this defeats purpose of -vmodule |
LogDetailedCrashReason (4) |
When handling crashes by default, detailed crash reason will be logged as well (Disabled by default) (issue #90) |
DisableApplicationAbortOnFatalLog (8) |
Allows to disable application abortion when logged using FATAL level. Note that this does not apply to default crash handlers as application should be aborted after crash signal is handled. (Not added by default) (issue #119) |
ImmediateFlush (16) |
Flushes log with every log-entry (performance sensative) – Disabled by default |
StrictLogFileSizeCheck (32) |
Makes sure log file size is checked with every log |
ColoredTerminalOutput (64) |
Terminal output will be colorful if supported by terminal. |
MultiLoggerSupport (128) |
Enables support for using multiple loggers to log single message. (E.g, CLOG(INFO, "default", "network") << This will be logged using default and network loggers; ) |
DisablePerformanceTrackingC
|
Disables checkpoint comparison |
DisableVModules (512) |
Disables usage of vmodules |
DisableVModulesExtensions (1024) |
Disables vmodules extension. This means if you have a vmodule -vmodule=main*=4 it will cover everything starting with main, where as if you do not have this defined you will be covered for any file starting with main and ending with one of the following extensions; .h .c .cpp .cc .cxx .-inl-.h .hxx .hpp. Please note following vmodule is not correct -vmodule=main.=4 with this macro not defined because this will check for main..c, notice double dots. If you want this to be valid, have a look at logging flag above: AllowVerboseIfModuleNotSpecified ‘?’ and ” wildcards are supported |
HierarchicalLogging (2048) |
Enables hierarchical logging. This is not applicable to verbose logging. |
CreateLoggerAutomatically (4096) |
Creates logger automatically when not available. |
AutoSpacing (8192) |
Automatically adds spaces. E.g, LOG(INFO) << "DODGE" << "THIS!"; will output “DODGE THIS!” |
FixedTimeFormat (16384) |
Applicable to performace tracking only – this prevents formatting time. E.g, 1001 ms will be logged as is, instead of formatting it as1.01 sec |
你可以使用 static 函数 el::Loggers::addFlag
和 el::Loggers::removeFlag
来设置和取消某一标志.。想要确认某一标志是否可用,可以调用函数 el::Loggers::hasFlag
,这些函数均采用强类型的枚举变量 el::LoggingFlag。
你可以通过命令行参数
--logging-flags
来设置这些标志。设置步骤:定义宏
ELPP_LOGGING_FLAGS_FROM_ARG
;使用
START_EASYLOGGINGPP(argc, argv)
进行设置。
3.8 程序参数
下表对所有可能用到的命令行参数进行了介绍。 你需要在 main(int, char**)
中调用 START_EASYLOGGINGPP(argc, argv)
对应用程序参数进行初始设置。
参数 | 描述 |
---|---|
-v |
Activates maximum verbosity |
--v=2 |
Activates verbosity upto verbose level 2 (valid range: 0-9) |
--verbose |
Activates maximum verbosity |
-vmodule=MODULE_NAME |
Activates verbosity for files starting with main to level 1, the rest of the files depend on logging flag AllowVerboseIfModuleNotSpecified Please see Logging Flags section above. Two modules can be separated by comma. Please note vmodules are last in order of precedence of checking arguments for verbose logging, e.g, if we have -v in application arguments before vmodules, vmodules will be ignored. |
--logging-flags=3 |
Sets logging flag. In example i.e, 3 , it sets logging flag to NewLineForContainer andAllowVerboseIfModuleNotSpecified . See logging flags section above for further details and values. See macros section to disable this function. |
--default-log-file=FILE |
Sets default log file for existing and future loggers. You may want to consider definingELPP_NO_DEFAULT_LOG_FILE to prevent creation of default empty log file during pre-processing. See macros section to disable this function. |
3.9 配置宏
有些日志选项可以通过宏来设定。这是一个很友好的功能,比如:我们只需定义宏 ELPP_THREAD_SAFE
,可以使所有线程安全相关的功能变为有效状态,否则为失效状态。 (making sure over-head of thread-safety goes with it).。为了方便记忆和避免和其他宏冲突,Easylogging++所有的宏以 ELPP_ 开头。
Macro Name | Description |
---|---|
ELPP_DEBUG_ASSERT_FAILURE |
Aborts application on first assertion failure. This assertion is due to invalid input e.g, invalid configuration file etc. |
ELPP_UNICODE |
Enables Unicode support when logging. Requires START_EASYLOGGINGPP |
ELPP_THREAD_SAFE |
Enables thread-safety – make sure -lpthread linking for linux. |
ELPP_FORCE_USE_STD_THREAD |
Forces to use C++ standard library for threading (Only useful when usingELPP_THREAD_SAFE |
ELPP_STACKTRACE_ON_CRASH |
Applicable to GCC only. Enables stacktrace on application crash |
ELPP_DISABLE_DEFAULT_CRASH_HANDLING |
Disables default crash handling. You can use el::Helpers::setCrashHandler to use your own handler. |
ELPP_DISABLE_LOGS |
Disables all logs – (preprocessing) |
ELPP_DISABLE_DEBUG_LOGS |
Disables debug logs – (preprocessing) |
ELPP_DISABLE_INFO_LOGS |
Disables info logs – (preprocessing) |
ELPP_DISABLE_WARNING_LOGS |
Disables warning logs – (preprocessing) |
ELPP_DISABLE_ERROR_LOGS |
Disables error logs – (preprocessing) |
ELPP_DISABLE_FATAL_LOGS |
Disables fatal logs – (preprocessing) |
ELPP_DISABLE_VERBOSE_LOGS |
Disables verbose logs – (preprocessing) |
ELPP_DISABLE_TRACE_LOGS |
Disables trace logs – (preprocessing) |
ELPP_FORCE_ENV_VAR_FROM_BASH |
If environment variable could not be found, force using alternative bash command to find value, e.g, whoami for username. (DO NOT USE THIS MACRO WITH LD_PRELOAD FOR LIBRARIES THAT ARE ALREADY USING Easylogging++ OR YOU WILL END UP IN STACK OVERFLOW FOR PROCESSES (popen ) (see issue #87 for details)) |
ELPP_DEFAULT_LOG_FILE |
Full filename where you want initial files to be created. You need to embed value of this macro with quotes, e.g, -DELPP_DEFAULT_LOG_FILE='"logs/el.gtest.log"' Note the double quotes inside single quotes, double quotes are the values for const char* and single quotes specifies value of macro |
ELPP_NO_DEFAULT_LOG_FILE |
If you dont want to initialize library with default log file, define this macro. But be sure to configure your logger with propery log filename or you will end up getting heaps of errors when trying to log to file (and TO_FILE is configured to true ) |
ELPP_DEBUG_ERRORS |
If you wish to find out internal errors raised by Easylogging++ that can be because of configuration or something else, you can enable them by defining this macro. You will get your errors on standard output i.e, terminal or command prompt. |
ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS |
Forcefully disables custom format specifiers |
ELPP_DISABLE_LOGGING_FLAGS_FROM_ARG |
Forcefully disables ability to set logging flags using command-line arguments |
ELPP_DISABLE_LOG_FILE_FROM_ARG |
Forcefully disables ability to set default log file from command-line arguments |
ELPP_WINSOCK2 |
On windows system force to use winsock2.h instead of winsock.h whenWIN32_LEAN_AND_MEAN is defined |
3.10 读取和访问日志配置信息
你可能需要获取某一日志记录器的配置信息,你可以通过调用Logger类的函数 typedConfigurations()
来实现。
el::Logger* l = el::Loggers::getLogger("default");
bool enabled = l->typedConfigurations()->enabled(el::Level::Info);
// Or to read log format/pattern
std::string format =
l->typedConfigurations()->logFormat(el::Level::Info).format();
暂无评论内容