日志库EasyLogging++学习系列(5)—— 辅助配置功能

正如前面《日志库EasyLogging++学习系列(3)—— 配置功能》文中最后提到的,在某些应用场景下,我们还需要通过其他的一些配置手段来辅助我们完成某些特殊功能,这些辅助配置手段包括设置命令行参数、设置日志标记、配置宏定义。本文中就对这几个辅助配置功能逐一进行简要介绍。

命令行参数

在 Easylogging++ 中可以通过START_EASYLOGGINGPP(argc, argv) 来完成命令行参数的设置,下面的表格列举了GitHub上给出的 Easylogging++ 支持的命令行参数:

ArgumentDescription
-vActivates maximum verbosity
--v=2Activates verbosity upto verbose level 2 (valid range: 0-9)
--verboseActivates maximum verbosity
-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 toNewLineForContainer and AllowVerboseIfModuleNotSpecified. See logging flags section above for further details and values. See macros section to disable this function.
--default-log-file=FILESets default log file for existing and future loggers. You may want to consider defining ELPP_NO_DEFAULT_LOG_FILE to prevent creation of default empty log file during pre-processing. See macros section to disable this function.

对于上述命令行参数,有必要简单说明一下:

  • 其中的 -v 、 --v 、 --verbose 、 -vmodule 都是用来设置 Verbose 详细日志的,而且这几个参数之间是有优先级顺序的,如下:-v  优先于 --verbose 优先于 --v 优先于 -vmodule。但是,在效果上 -v 和 --verbose 是一样的。请看下面的例子:

命令行参数例一:--v=2 -v ,在这里参数 --v=2 会被参数 -v 覆盖,因为 -v 优先级最高。

命令行参数例二:--verbose -vmodule=main=3 ,在这里参数 -vmodule=main=3 会被参数 --verbose 覆盖,因为 --verbose 优先于 -vmodule 。

命令行参数例三:-vmodule=main*=3 --v=5 -v --verbose ,在这里参数 -v 会覆盖其他所有的参数,因为 -v 优先级最高。

  • 其中的 --logging-flags 是用来设置日志标记的,而且必须定义 ELPP_LOGGING_FLAGS_FROM_ARG 这个宏定义。
  • 其中的 --default-log-file 是用来设置日志默认保存文件名的。如果没用这个命令行参数设置文件名,那么默认的文件名就是 logs\\myeasylog.log 。另外,我们也可以用宏定义 ELPP_DEFAULT_LOG_FILE 来达到相同的效果。如:#defineELPP_DEFAULT_LOG_FILE "logs\\tem\\test.log" 。

下面的代码演示了设置命令行参数 --v=2 ,其最终效果是 VLOG(3) 将会被屏蔽:

#include "easylogging++.h"
 
INITIALIZE_EASYLOGGINGPP
 
int main(int argc, char** argv)
{
	/// 请自行加上命令行参数 --v=2,否则达不到演示的效果
	START_EASYLOGGINGPP(argc, argv);
 
	VLOG(0);
	VLOG(1);
	VLOG(2);
	VLOG(3);
 
	system("pause");
	return 0;
}

更多关于Verbose日志的详细信息请参考《 日志库EasyLogging++学习系列(8)—— Verbose日志详解 》。

日志标记

在学习日志标记之前,我们先来看看 Easylogging++ 提供出来的三个和日志标记紧密相关的功能接口函数:

  • 增加标记函数: el::Loggers::addFlag 
  • 删除标记函数:el::Loggers::removeFlag 
  • 检查标记函数:el::Loggers::hasFlag 

下面的表格列举了GitHub上给出的 Easylogging++ 支持的日志标记:

FlagDescription
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;)
DisablePerformanceTrackingCheckpointComparison (256)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 as 1.01 sec

对于上述的日志标记,可在 Easylogging++ 源码中查看枚举值el::LoggingFlag ,每个标记的含义在表格和源码中都描述得比较清楚了,不过还是建议大家都亲自动手试一试,下面的代码演示了标记 NewLineForContainer 的作用:

#define ELPP_STL_LOGGING
#include "easylogging++.h"
 
INITIALIZE_EASYLOGGINGPP
 
int main(int argc, char** argv)
{
	std::vector<int> vecNum;
	vecNum.push_back(1);
	vecNum.push_back(2);
	vecNum.push_back(3);
 
	/// 增加标记 NewLineForContainer,注意查看输出STL容器的效果
	el::Loggers::addFlag(el::LoggingFlag::NewLineForContainer);
	LOG(INFO) << vecNum;
 
	/// 删除标记 NewLineForContainer,注意查看输出STL容器的效果
	el::Loggers::removeFlag(el::LoggingFlag::NewLineForContainer);
	LOG(INFO) << vecNum;
	
	system("pause");
	return 0;
}

配置宏定义

在 Easylogging++ 中,有些功能必须定义相应的宏定义才能开启。为了方便记忆,Easylogging++ 中所有的宏定义都是以 ELPP_ 开头的,所以可以在源码中搜索 ELPP_ 来查看都定义了哪些宏定义。下面的表格列举了GitHub上给出的 Easylogging++ 支持的宏定义(只列举了部分):

Macro NameDescription
ELPP_DEBUG_ASSERT_FAILUREAborts application on first assertion failure. This assertion is due to invalid input e.g, invalid configuration file etc.
ELPP_UNICODEEnables Unicode support when logging. RequiresSTART_EASYLOGGINGPP
ELPP_THREAD_SAFEEnables thread-safety - make sure -lpthread linking for Linux.
ELPP_FORCE_USE_STD_THREADForces to use C++ standard library for threading (Only useful when using ELPP_THREAD_SAFE
ELPP_STACKTRACE_ON_CRASHApplicable to GCC only. Enables stacktrace on application crash
ELPP_DISABLE_DEFAULT_CRASH_HANDLINGDisables default crash handling. You can use el::Helpers::setCrashHandler to use your own handler.
ELPP_DISABLE_LOGSDisables all logs - (preprocessing)
ELPP_DISABLE_DEBUG_LOGSDisables debug logs - (preprocessing)
ELPP_DISABLE_INFO_LOGSDisables info logs - (preprocessing)
ELPP_DISABLE_WARNING_LOGSDisables warning logs - (preprocessing)
ELPP_DISABLE_ERROR_LOGSDisables error logs - (preprocessing)
ELPP_DISABLE_FATAL_LOGSDisables fatal logs - (preprocessing)
ELPP_DISABLE_VERBOSE_LOGSDisables verbose logs - (preprocessing)
ELPP_DISABLE_TRACE_LOGSDisables trace logs - (preprocessing)
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_FILEFull 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_FILEIf 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 (andTO_FILE is configured to true)
ELPP_DEBUG_ERRORSIf 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_SPECIFIERSForcefully disables custom format specifiers
ELPP_DISABLE_LOGGING_FLAGS_FROM_ARGForcefully disables ability to set logging flags using command-line arguments
ELPP_DISABLE_LOG_FILE_FROM_ARGForcefully disables ability to set default log file from command-line arguments
ELPP_WINSOCK2On windows system force to use winsock2.hinstead of winsock.h when WIN32_LEAN_AND_MEANis defined

利用在上述的宏定义,可以完成一些配置文件中无法完成的配置。下面简单介绍几个比较实用的宏定义:

  • ELPP_DEBUG_ASSERT_FAILURE 宏定义,可以帮助我们检测配置文件中的配置项名称是否正确,假如配置项名称不是Easylogging++ 支持的,那么就会出现断言中断。
  • ELPP_UNICODE 宏定义,默认的日志记录是只支持多字节字符串的,同时使用这个宏定义和 START_EASYLOGGINGPP(argc, argv) 可以开启 Unicode 字符串记录日志的功能。
  • ELPP_THREAD_SAFE 宏定义,在默认情况下,考虑到性能,多线程安全功能是关闭的,使用这个宏定义则可以开启。
  • ELPP_STL_LOGGING 宏定义,使 Easylogging++ 支持STL模板和容器类型的日志输出,比如上面第二部分介绍日志标记最后给出例子。考虑到性能,每个容器最大容量是 100,可以通过修改源码改变这个限制,但不建议这么做,除非你可以无视性能和效率。

当然,其他的宏定义也很实用,建议大家也可以亲自试一试,看看其实际的作用。需要注意的是,有些宏必须在包含 Easylogging++ 头文件之前,即必须在代码 #include "easylogging++.h" 之前完成定义才有意义。下面的代码演示了宏定义 ELPP_UNICODE 的作用:

#define ELPP_UNICODE
#include "easylogging++.h"
 
INITIALIZE_EASYLOGGINGPP
 
int main(int argc, char** argv)
{
	/// 同时使用 START_EASYLOGGINGPP 才能使用Unicode 
	START_EASYLOGGINGPP(argc, argv);
 
	LOG(INFO) << L"宏定义演示。";
 
	system("pause");
	return 0;
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Easylogging是一个简单易用的日志,它可以帮助开发人员在程序运行过程中记录并追踪各种日志信息。它提供了许多便捷的方法,使开发人员能够根据实际需要对日志进行配置,并将其输出到不同的地方,如控制台、文件等。 多线程是一种在同一个进程中同时执行多个任务的方法。多线程可以提高程序的并发性和效率,但也会带来一些问题。其中一个常见的问题是内存暴涨。 内存暴涨指的是程序在运行过程中占用的内存空间急剧增加。多线程程序中,每个线程都有自己的栈空间,用于存储局部变量等数据。当多个线程同时执行时,可能会导致大量的栈帧被同时创建和销毁,从而占用大量的内存空间。此外,多线程程序还可能存在共享数据的问题,需要使用一些同步机制来保证数据的正确性,这也会增加内存的开销。 为了解决多线程程序中的内存暴涨问题,可以采取一些措施。首先,可以对线程进行优化,尽量减少线程的创建和销毁次数,减少栈空间占用。其次,可以优化共享数据的访问方式,使用一些高效的同步机制,如读写锁、原子操作等,减少内存开销。此外,还可以使用一些内存管理工具来监测和调优程序的内存使用情况,及时发现和解决内存暴涨问题。 总结来说,Easylogging可以帮助我们方便地记录和追踪日志信息,多线程能够提高程序的并发性和效率,但同时也会带来内存暴涨的问题。为了解决内存暴涨,我们可以采取一些优化措施,减少线程的创建和销毁次数,优化共享数据的访问方式,并使用内存管理工具监测和调优程序的内存使用情况。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值