easyloggingpp库使用

简介

适用于V9.97

项目的开源地址在这里

该Log库只需包含一个头文件一个源文件即可,轻量且易于融入项目中。需要c++11

简单使用

#include "easylogging++.h"

INITIALIZE_EASYLOGGINGPP

int main(int argc, char* argv[]) {
   LOG(INFO) << "My first info log using default logger";
   return 0;
}

只需要包含头文件并使用宏INITIALIZE_EASYLOGGING初始化,使用LOG(INFO)即可。

INITIALIZE_EASYLOGGING的作用是初始化一些变量,全局只能使用一次。因此可以考虑在main函数的文件中去声明。

通过传递启动参数指定功能

int main(int argc, char* argv[]) {
   START_EASYLOGGINGPP(argc, argv);
   ...
}

功能待补充。。。

等级标签

等级描述
Global表示所有级别的通用级别。在为所有级别设置全局配置时很有用
Trace可用于回溯某些事件的信息-----比Debug日志更有用
Debug普通的Debug级别
Fatal导致应用程序终止的严重的事件
Error是错误,但是程序会继续运行
Warning是小点的错误,程序会继续运行
Info当前应用程序走到哪了的一些信息
Verbose随详细日志记录级别的不同而变化的信息
Unknown仅用于分等级日志记录,用于关闭日志记录

配置

可以通过三种方式进行配置:

  1. 配置文件

  2. el::Configurations 类

  3. 内联配置

配置文件

配置文件可以通过Configurations类在运行时加载的文件来完成。此文件具有以下格式:

* LEVEL:
  CONFIGURATION NAME  = "VALUE" ## Comment
  ANOTHER CONFIG NAME = "VALUE"

级别名称以*号开头以:结尾,通常建议以Global级别作为开头进行配置,以便对为配置的级别,在代码中可以使用Global的配置进行加载。

下表为相应的CONFIGURATION NAME

Configuration Name类型描述
Enabledbool确定是否启用记录器的相应级别。您可以使用el::Level::Global禁用所有日志
To_Filebool是否将相应的日志写到日志文件
To_Standard_Outputbool是否输出到终端
Formatchar*定义日志输出格式
Filenamechar*不同级别和不同记录器写入文件的文件名,需要完整路径
Subsecond_Precisionuint指定亚秒精度(以前称为“毫秒宽度”)。值可以在(1-6)范围内
Performance_Trackingbool确定是否启用性能跟踪。这并不取决于记录器或级别。除非指定,否则性能跟踪始终使用“性能”记录器
Max_Log_File_Sizesize_t如果相应级别的日志文件大小>=指定大小,则日志文件将被截断。
Log_Flush_Thresholdsize_t指定在刷新挂起的日志数据之前要保留的日志条目数

例子:

* GLOBAL:
   FORMAT               =  "%datetime %msg"
   FILENAME             =  "/tmp/logs/my.log"
   ENABLED              =  true
   TO_FILE              =  true
   TO_STANDARD_OUTPUT   =  true
   SUBSECOND_PRECISION  =  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进行全局配置,再单独对DEBUG级别的Log记录输出时间、日期、年份默认的%daratime是包括年月日时分秒,再对DEBUG进行单独配置,将输出格式中只显示日月 函数 消息

加载

可以使用如下方式对配置文件进行加载:

#include "easylogging++.h"

INITIALIZE_EASYLOGGINGPP

int main(int argc, const char** argv) {
    // 从文件加载配置文件
    el::Configurations conf("/path/to/my-conf.conf");
    // 为单独一个级别的Logger配置
    el::Loggers::reconfigureLogger("default", conf);
    // 为全部的Logger配置
    el::Loggers::reconfigureAllLoggers(conf);
    // Now all the loggers will use configuration from file
    // 也可直接将加载的配置文件设置为默认的配置
    el::Loggers::setDefaultConfigurations( conf );
    // 这样后注册的所有Logger,都是默认配置,而无需重复配置
}

el::Configuration类

对加载的进程序的文件进行二次修改:

#include "easylogging++.h"

INITIALIZE_EASYLOGGINGPP

int main(int argc, const char** argv) {
   el::Configurations defaultConf;
   defaultConf.setToDefault();
    // 通过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;
}

直接在代码中进行配置,需要好多换行符,不推荐,不直观

el::Configurations c;
c.setToDefault();
c.parseFromText("*GLOBAL:\n FORMAT = %level %msg");

日志输出格式

可以通过配置文件的FORMAT标签进行输出格式的配置

标签描述
%loggerLogger ID
%threadThread ID – 如果可用,则使用std::thread,否则在windows上使用GetCurrentThreadId()
%thread_name使用Helpers::setThreadName设置当前线程的名称
%level日志级别
%levshort日志级别简写
%vlevel日志级别详细
%datetime时间
%user当前的user,/home/user,指的是这个user
%host当前ip
%file*源文件名称,需要支持__FILE__宏,会打印全完整路径+文件名
%fbase*源文件名称,不包含完整路径
%line*源文件行号,需支持__line__
%func*运行的函数
%loc*源文件:行号,其中源文件为完整路径+文件名
%msg要打印的日志信息
%转义符,如:%%level 输出的内容是 %level

要使用%host需要做如下设置:

const char* getIp(const el::LogMessage*) {
    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;
}

日期格式

标签描述
%d日期(0填充)
%a周,缩写 (Mon, Tue, Wed, Thu, Fri, Sat, Sun)
%A周,全称 (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
%M月(0填充)
%b月,缩写 (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)
%B月,全称 (January, February, March, April, May, June, July, August, September, October, November, December)
%y年,只是后两位 (13, 14 etc)
%Y年,四位 (2013, 2014 etc)
%h小时,12小时制
%H小时,24小时制
%m分钟(0填充)
%s秒(0填充)
%gSubsecond part (precision is configured by ConfigurationType::SubsecondPrecision)
%FAM/PM
%转义符

请注意,日期/时间最多限制为30个字符。

日志标签

以下是支持的标志:

标签描述
NewLineForContainer (1)确保每个容器日志条目都有新行
AllowVerboseIfModuleNotSpecified (2)确保如果使用了-vmodule并且没有指定模块,则允许通过该模块进行详细日志记录。假设param was-vmodule=main*=3,并且正在从名为something.cpp的文件中写入详细日志,则如果启用了此标志,则将写入日志,否则将不允许写入。注意:这样做违背了-vmodule的目的
LogDetailedCrashReason (4)在默认情况下处理崩溃时,还会记录详细的崩溃原因(默认情况下已禁用) (issue #90)
DisableApplicationAbortOnFatalLog (8)允许在使用FATAL级别登录时禁用应用程序中止。请注意,这不适用于默认的崩溃处理程序,因为在处理崩溃信号后应用程序应该中止(默认情况下不添加) (issue #119)
ImmediateFlush (16)使用每个日志条目刷新日志(性能敏感)-默认情况下禁用
StrictLogFileSizeCheck (32)确保与每个日志一起检查日志文件大小
ColoredTerminalOutput (64)如果终端支持,终端输出将是彩色。
MultiLoggerSupport (128)支持使用多个记录器记录单个消息。(例如,CLOG(INFO,“default”,“network”)<<This will be logged using default and network loggers;
DisablePerformanceTrackingCheckpointComparison (256)禁用检查点比较
DisableVModules (512)禁用vmodules的使用
DisableVModulesExtensions (1024)禁用vmodules扩展。这意味着,如果您有一个vmodule-vmodule=main*=4,它将覆盖以main开头的所有内容,其中,如果您没有定义它,则将覆盖以main开头并以以下扩展名之一结尾的任何文件.h.c.cpp.cc.cxx.-inl-.h.xxx.hpp。请注意以下vmodule不正确-vmodule=main=4未定义此宏,因为这将检查main..c、 注意双点。如果要使其有效,请查看上面的日志记录标志:AllowVerboseIfModuleNotSpecified``?和``通配符受支持
HierarchicalLogging (2048)启用分层日志记录。这不适用于详细日志记录。
CreateLoggerAutomatically (4096)当禁止时自动创建log记录器
AutoSpacing (8192)自动添加空格E.g, LOG(INFO) << "DODGE" << "THIS!"; 输出"DODGE THIS!"
FixedTimeFormat (16384)仅适用于性能跟踪-这样可以防止格式化时间。例如,1001毫秒将按原样记录,而不是将其格式化为1.01秒
IgnoreSigInt (32768)应用程序崩溃时忽略中断信号

以上标签可以通过el::Loggers::addFlag进行设置,也可以通过el::Loggers::removeFlag解除设置,可以通过el::Loggers::hasFlag检查标签是否设置,所有这些函数都采用强类型枚举el::LoggingFlag

可以使用--logging flags命令行arg设置这些标志。需要通过定义宏ELPP_LOGGING_FLAGS_FROM_ARG来启用此功能(需要确保使用START_EASYLOGGINGPP(argc,argv)来接收配置参数)。

也可以使用ELPP_default_LOGGING_flags设置默认(初始)标志,并设置初始标志的数值

必须设置标记LoggingFlag::StrictLogFileSizeCheck否则,配置文件中MAX_LOG_FILE_SIZE = 1048576不生效

应用程序参数

下表将解释您可以用来定义某些行为的所有命令行参数;您需要在main(int,char**)函数中使用START_EASYLOGGINGPP(argc,argv)来初始化应用程序参数。

参数描述
-v激活最大详细log记录
--v=2激活详细程度2以下的 (可取范围: 0-9)
--verbose-v
-vmodule=MODULE_NAMEActivates 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=3Sets logging flag. In example i.e, 3, it sets logging flag to NewLineForContainer and AllowVerboseIfModuleNotSpecified. See logging flags section above for further details and values. See macros section to disable this function.
--default-log-file=FILE设置现有和未来记录器的默认日志文件。您可能需要考虑定义ELPP_NO_DEFAULT_LOG_FILE,以防止在预处理期间创建默认的空日志文件。请参阅宏部分禁用此功能。

配置宏

一些日志记录选项可以由宏设置,这是一个深思熟虑的决定,例如,如果我们定义了ELPP_THREAD_SAFE,则所有线程安全功能都会被启用否则禁用(确保线程安全性与此相关)。为了便于记忆并防止可能的冲突,所有宏都以ELPP_开头

注意:所有宏都可以通过以下方式之一定义:

  1. 使用编译器的-D选项定义宏,例如在g++的情况下,您将执行g++ source.cpp…-DELPP_SYSLOG-DELPP_THREAD_SAFE(推荐方式)

  2. 在“easylogging++.h”中定义宏(在其他文件中定义宏不起作用)

宏名称描述
ELPP_DEBUG_ASSERT_FAILURE第一次断言失败时中止应用程序。此断言是由于无效的输入,例如无效的配置文件等
ELPP_UNICODE在日志记录时启用Unicode支持。需要START_ASYLOGGINGPP
ELPP_THREAD_SAFE为linux启用线程安全-确保-lpthread链接。
ELPP_FORCE_USE_STD_THREAD强制使用C++标准库进行线程处理(仅在使用ELPP_THREAD_SAFE时有用
ELPP_FEATURE_CRASH_LOG仅适用于GCC。在应用程序崩溃时启用堆栈跟踪
ELPP_DISABLE_DEFAULT_CRASH_HANDLING禁用默认故障处理。您可以使用el::Helpers::setCrashHandler来使用自己的处理程序。
ELPP_DISABLE_LOGS禁用所有日志-(预处理)
ELPP_DISABLE_DEBUG_LOGS禁用DEBUG日志-(预处理)
ELPP_DISABLE_INFO_LOGS禁用INFO日志-(预处理)
ELPP_DISABLE_WARNING_LOGS禁用WARING日志-(预处理)
ELPP_DISABLE_ERROR_LOGS禁用ERROR日志-(预处理)
ELPP_DISABLE_FATAL_LOGS禁用FATAL日志-(预处理)
ELPP_DISABLE_VERBOSE_LOGS禁用VERBOSE日志-(预处理)
ELPP_DISABLE_TRACE_LOGS禁用TRACE日志-(预处理)
ELPP_FORCE_ENV_VAR_FROM_BASHIf 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要创建初始文件的完整文件名。您需要用引号嵌入这个宏的值, e.g, -DELPP_DEFAULT_LOG_FILE='"logs/el.gtest.log"' 注意单引号中的双引号,双引号是const char*的值,单引号指定宏的值
ELPP_NO_LOG_TO_FILE最初禁用对文件的日志记录
ELPP_NO_DEFAULT_LOG_FILE若不想用默认的日志文件初始化库,请定义这个宏。这将记录到unixwindowsnull设备。在其他平台中,您可能会遇到错误,需要使用ELPP_DEFAULT_LOG_FILE
ELPP_FRESH_LOG_FILE无论是否创建了log文件,都不续写
ELPP_DEBUG_ERRORS打开easylogging++库的log
ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS强制禁用自定义格式说明符
ELPP_DISABLE_LOGGING_FLAGS_FROM_ARG强制禁用使用命令行参数设置日志记录标志的功能
ELPP_DISABLE_LOG_FILE_FROM_ARG强制禁用从命令行参数设置默认日志文件的功能
ELPP_WINSOCK2在windows系统上,当定义WIN32_EAN_AND_MEAN时,强制使用winsock2.h而不是winsock.h
ELPP_CUSTOM_COUT (advanced)Resolves to a value e.g, #define ELPP_CUSTOM_COUT qDebug() or #define ELPP_CUSTOM_COUT std::cerr. This will use the value for standard output (instead of using std::cout
ELPP_CUSTOM_COUT_LINE (advanced)Used with ELPP_CUSTOM_COUT to define how to write a log line with custom cout. e.g, #define ELPP_CUSTOM_COUT_LINE(msg) QString::fromStdString(msg).trimmed()
ELPP_NO_CHECK_MACROS不要定义CHECK
ELPP_NO_DEBUG_MACROS不要定义DEBUG
ELPP_UTC_DATETIME使用UTC时间而不是当地时间
ELPP_NO_GLOBAL_LOCKDo not lock the whole storage on dispatch. This should be used with care. See issue #580

读取配置

通过代码读取某一个logger的配置,可以通过:

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();

记录日志

普通日志记录

可以使用这两个宏记录日志:

  • LOG(LEVEL)
  • CLOG(LEVEL, logger ID)

LOG使用的默认的记录器,CLOG可以选择使用用户自定义的记录器,可以让不同的Logger有不同的配置。

通常在使用CLOG前应该先对Logger进行注册

例子如下:

LOG(INFO) << "This is info log";
el::Loggers::getLogger( "performance" );
CLOG(ERROR, "performance") << "This is info log using performance logger";

还可以通过修改LOG宏的默认Logger,以达到自定义效果,需要在.cc文件中定义。

#ifndef ELPP_DEFAULT_LOGGER
#   define ELPP_DEFAULT_LOGGER "update_manager"
#endif
#ifndef ELPP_DEFAULT_PERFORMANCE_LOGGER
#   define ELPP_DEFAULT_PERFORMANCE_LOGGER ELPP_DEFAULT_LOGGER
#endif
#include "easylogging++.h"
UpdateManager::UpdateManager {
    _TRACE; // Logs using LOG(TRACE) provided logger is already registered - i.e, update_manager
    LOG(INFO) << "This will log using update_manager logger as well";
}
#include "easylogging++.h"
UpdateManager::UpdateManager {
    _TRACE; // Logs using LOG(TRACE) using default logger because no `ELPP_DEFAULT_LOGGER` is defined unless you have it in makefile
}

条件日志记录

  1. 每多少次记录1次

例如每10次、第100次或第2次,就会写入日志。帮助程序宏以_EVERY_N结尾;

  • LOG_EVERY_N(n, LEVEL)
  • CLOG_EVERY_N(n, LEVEL, logger ID)
for ( int i = 0; i < 10; i++ )
{
    CLOG_EVERY_N( 6, ERROR, "map" ) << "This is a CLOG_IF ERROR log for map logger = " << i;
}
// 输出:This is a CLOG_EVERY_N ERROR log for map logger = 5
  1. 多少次之后开始记录
  • LOG_AFTER_N(n, LEVEL)
  • CLOG_AFTER_N(n, LEVEL, logger ID)
for ( int i = 0; i < 10; i++ )
{
    CLOG_AFTER_N( 6, ERROR, "map" ) << "This is a CLOG_AFTER_N ERROR log for map logger = " << i;
}
// 输出:
// This is a CLOG_AFTER_N ERROR log for map logger = 6
// This is a CLOG_AFTER_N ERROR log for map logger = 7
// This is a CLOG_AFTER_N ERROR log for map logger = 8
// This is a CLOG_AFTER_N ERROR log for map logger = 9
  1. 从开始记录多少次
  • LOG_N_TIMES(n, LEVEL)
  • CLOG_N_TIMES(n, LEVEL, logger ID)
for ( int i = 0; i < 10; i++ )
{
    CLOG_N_TIMES( 6, ERROR, "map" ) << "This is a CLOG_N_TIMES ERROR log for map logger = " << i;
}

// 输出:
// This is a CLOG_N_TIMES ERROR log for map logger = 0
// This is a CLOG_N_TIMES ERROR log for map logger = 1
// This is a CLOG_N_TIMES ERROR log for map logger = 2
// This is a CLOG_N_TIMES ERROR log for map logger = 3
// This is a CLOG_N_TIMES ERROR log for map logger = 4
// This is a CLOG_N_TIMES ERROR log for map logger = 5

类似printf的记录

需要c++11支持,与printf唯一的区别是所有的传入类型占位符为%v,并且消息格式输出中%file, %func %line and %loc就都不好用了。不推荐

  • info(const char*, const T&, const Args&...)
  • warn(const char*, const T&, const Args&...)
  • error(const char*, const T&, const Args&...)
  • debug(const char*, const T&, const Args&...)
  • fatal(const char*, const T&, const Args&...)
  • trace(const char*, const T&, const Args&...)
  • verbose(int vlevel, const char*, const T&, const Args&...)
el::Logger *mapLogger = el::Loggers::getLogger( "map" );
mapLogger->info( "Use map logger printf = %v | %v", "Hello map!", 1111111 );
// 输出:
// Use map logger printf = Hello map! | 1111111

Verbose 日志

可以摆脱设置日志输出级别的限制,即脱离DEBUG、INFO等级别的门阀限制,可以指定单个文件的Vervose输出。

Verbose 日志可以理解为详细日志记录,可以记录比平时更多的信息。对故障排除非常有用。以下是详细的日志记录特定宏:

  • VLOG(verbose-level)
  • CVLOG(verbose-level, logger ID)
 CVLOG( 0, "map" ) << "This is a CVLOG with level 0";
 // 输出:
 // This is a CVLOG with level 0

同样支持条件记录

  • VLOG_IF(condition, verbose-level)
  • CVLOG_IF(condition, verbose-level, loggerID)
  • VLOG_EVERY_N(n, verbose-level)
  • CVLOG_EVERY_N(n, verbose-level, loggerID)
  • VLOG_AFTER_N(n, verbose-level)
  • CVLOG_AFTER_N(n, verbose-level, loggerID)
  • VLOG_N_TIMES(n, verbose-level)
  • CVLOG_N_TIMES(n, verbose-level, loggerID)

Vervise日志的等级0-9,可以通过Loggers::setVerboseLevel(base::type::VerboseLevel)或者Loggers::setVerboseLevel(int)在程序中动态设置输出等级门阀,使用Loggers::verboseLevel()查看当前门阀等级,其中0等级的不会被门阀限制

注册新Logger

Logger ID是获取一个Logger的唯一标识符

默认情况下,系统初始化时会生成三个默认的记录器:

  • Default logger (ID: default)
  • Performance logger (ID: performance)
  • Syslog logger (if ELPP_SYSLOG macro is defined) (ID: syslog)

如果想注册新的Logger

el::Logger* businessLogger = el::Loggers::getLogger("business");

即可获得一个IDbusinessLogger

其中:

el::Loggers::getLogger(const std::string& identity, bool registerIfNotAvailable = true)

函数的第二个参数默认为true,这种情况下getLogger("business")调用后,如果businessLogger存在,即返回一个Logger的对象指针,如果不存在,即创建一个相应的Logger并返回对象指针。

当通过getLogger("business",false)调用的时候,如果存在,返回对象指针,如果不存在,返回nullptr

注:ID区分大小写

注销Logger

除了上述3个默认创建的Logger无法注销之外

通过调用el::Loggers::unregisterLogger("logger-id")注销。

注:小心使用该函数,有可能出现这种情况,你有一个第三方库使用了easylogging++,并且他使用的ID为myLog,当你自己注册一个Logger的时候也使用了ID为myLog(实际上并不是由你自己创建的,但是你误认为是你自己创建的),当你注销的时候有可能会导致程序崩溃

查询Logger ID

通过调用函数

el::Loggers::populateAllLoggerIds(std::vector<std::string>* v)

该函数会清空传入的vector并将Logger ID填充进去

如果定义ELPP_SYSLOG即可查看到syslog

设置库共享easylogging

额外功能

可以通过使用 ELPP_FEATURE_ALL来启用全部功能

性能跟踪

定义宏ELPP_FEATURE_PERFORMANCE_TRACKING,用于记录运行时间

  • TIMED_FUNC(obj-name):主要用来检测整个函数的性能,一般放在函数首行。
  • TIMED_SCOPE(obj-name, block-name):主要用来检测一定范围内的代码性能。
  • TIMED_BLOCK(obj-name, block-name):主要用来检测某一段代码块的性能。

例子如下:

void performHeavyTask(int iter) {
   TIMED_FUNC(timerObj);
   // Some initializations
   // Some more heavy tasks
   usleep(5000);
   while (iter-- > 0) {
       TIMED_SCOPE(timerBlkObj, "heavy-iter");
       // Perform some heavy task in each iter
       usleep(10000);
   }
}

输出如下:

06:22:31,368 INFO Executed [heavy-iter] in [10 ms]
06:22:31,379 INFO Executed [heavy-iter] in [10 ms]
06:22:31,389 INFO Executed [heavy-iter] in [10 ms]
06:22:31,399 INFO Executed [heavy-iter] in [10 ms]
06:22:31,409 INFO Executed [heavy-iter] in [10 ms]
06:22:31,419 INFO Executed [heavy-iter] in [10 ms]
06:22:31,429 INFO Executed [heavy-iter] in [10 ms]
06:22:31,440 INFO Executed [heavy-iter] in [10 ms]
06:22:31,450 INFO Executed [heavy-iter] in [10 ms]
06:22:31,460 INFO Executed [heavy-iter] in [10 ms]
06:22:31,460 INFO Executed [void performHeavyTask(int)] in [106 ms]

暂时没试出来

日志文件轮转

通过日志配置Max_Log_File_Size关键字进行配置

通过添加

el::Loggers::addFlag( el::LoggingFlag::StrictLogFileSizeCheck );

使得配置生效。

通过注册el::Helpers::installPreRollOutCallback(const PreRollOutCallback& handler)使得其生效,其中PreRollOutCallbackstd::function<void(const char*, std::size_t)>的typedef

一套简易的代码如下:

#include "easylogging++.h"

INITIALIZE_EASYLOGGINGPP

static unsigned int idx;

void rolloutHandler( const char *filename, std::size_t size ) {
    // SHOULD NOT LOG ANYTHING HERE BECAUSE LOG FILE IS CLOSED!
    std::cout << "************** Rolling out [" << filename << "] because it reached [" << size << " bytes]"
              << std::endl;

    // BACK IT UP
    std::stringstream ss;
    system( "mkdir bak" );
    ss << "mv ./" << filename << " bak/log-backup.log";
    std::cout << ss.str() << std::endl;
    system( ss.str().c_str() );
}

int main( int, char ** ) {
    idx = 0;
    el::Configurations conf( "/home/cat/code/test/easylogging_usage/config/configLog.conf" );
    el::Loggers::reconfigureAllLoggers( conf );
    el::Loggers::addFlag( el::LoggingFlag::DisableApplicationAbortOnFatalLog );
    el::Loggers::addFlag( el::LoggingFlag::HierarchicalLogging );
    el::Loggers::addFlag( el::LoggingFlag::StrictLogFileSizeCheck );
    el::Helpers::installPreRollOutCallback( rolloutHandler );

    for ( int i = 0; i < 10000; ++i )
        LOG( INFO ) << "Test";

    el::Helpers::uninstallPreRollOutCallback();
    return 0;
}

注:不能在该函数中使用LOG记录

崩溃记录

添加宏ELPP_FEATURE_CRASH_LOG

Easylogg++GCC编译器提供了处理意外崩溃的能力。默认情况下,这是活动的,可以通过定义宏ELPP_DISABLE_default_CRASH_DHANDLING来禁用。这样做是在告诉库不要处理任何崩溃。稍后,如果您希望自己处理崩溃,可以指定类型为void func(int)的崩溃处理程序,其中int是捕获信号的

以下的退出信号是能够被easylogging检测到的

  • SIGABRT (需定义宏ELPP_HANDLE_SIGABRT )
  • SIGFPE
  • SIGILL
  • SIGSEGV
  • SIGINT

只有当定义了ELPP_FEATURE_CRASH_LOG宏后才打印堆栈信息

堆栈信息是通过default的logger id打印出来的

以下是一些有用的宏,您可以定义这些宏来更改行为

宏名称描述
ELPP_DISABLE_DEFAULT_CRASH_HANDLING禁用默认故障处理。
ELPP_HANDLE_SIGABRT启用处理SIGABRT。默认情况下,这是禁用的,以防止在您希望中止时出现恼人的CTRL+C行为。

多线程

需要定义宏ELPP_THREAD_SAFE,确保easylogging是线程安全的,一用就挂!!!!

STL日志

定义宏ELPP_STL_LOGGING

如前所述,使用easylogging++,您可以记录STL模板,包括大多数容器。为此,您需要定义ELPP_STL_LOGGING宏。这允许包含所有必要的标头并定义所有必要的函数。为了提高性能,容器最多只能记录100个条目。这种行为可以通过更改头文件(base::consts::kMaxLogPerContainer)来改变,但不建议这样做,因为为了进行日志记录,写入程序必须遍历每个条目,这可能会导致延迟。但是,如果您并不真正关心性能,您可能会更改此值。

Boost日志

定义宏ELPP_BOOST_LOGGING

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值