一、日志作用已集其运用场景
1.记录程序处理流程
2.记录重要系统操作状态、处理时间
3.快速定位分析诊断和解决异常的重要手段
4.多方协作时也可以明确责任
5.开发过程中的程序调试问题提供详细信息
6.性能分析、查看服务间的调用关系
7.在源码不能带到客户现场调试
8.开发环境无法复现现场异常
9.概率性异常(内存泄漏、崩溃)
10.出差成本较高
二、日志模块使用demo
#include "Logger/Logger.h" //日志模块头文件
#include<thread>
#include<future>
#include<chrono>
const static int MAX_NUMS(1000);
void Cout()
{
for (int i = 0; i < MAX_NUMS; ++i)
{
//std::this_thread::sleep_for(std::chrono::milliseconds(10));
LOGGER_DEBUG("logs test: %d, %s", MAX_NUMS, "Cout");
}
}
int main(int argc, char *argv[])
{
std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
std::future<void> testCout = std::async(std::launch::async, Cout);
for (int i = 0; i < MAX_NUMS; ++i)
{
//std::this_thread::sleep_for(std::chrono::milliseconds(10));
LOGGER_INFO("Start function: %s","main");
}
testCout.get();
std::chrono::steady_clock::time_point endTime = std::chrono::steady_clock::now();
std::chrono::milliseconds duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
LOGGER_INFO("The time for the two parallel tasks to output %d logs each was %d milliseconds", MAX_NUMS, duration.count());
return 0;
}
三、demo执行日志输出结果
2021-03-26 00:15:10,367 [Default] [INFO ] TID[0x00000bc8] [main:25] Start function: main
2021-03-26 00:15:10,367 [Default] [DEBUG] TID[0x000018e4] [Cout:13] logs test: 1000, Cout
//......
2021-03-26 00:15:10,619 [Default] [DEBUG] TID[0x000018e4] [Cout:13] logs test: 1000, Cout
2021-03-26 00:15:10,619 [Default] [INFO ] TID[0x00000bc8] [main:32] The time for the two parallel tasks to output 1000 logs each was 282 milliseconds
说明:
//输出格式(%d:时间, %c:模块名称, %p:日志级别, %t:线程号, %M:具体到函数作用域名,%L:代码行数, %m:代码中要打印的日志, %n:换行
//输出文件路径和名称可配置,名称中并可设置进程号,符号为“${CPID}”
//其他更多配置可参考Logger.properties,该文件中有示例并有注释
四、Logger的SDK的说明
demo工程以及SDK所需文件下载路径
头文件接口说明:
// 可配位置信息默认日志宏定义,可根据不同模块自行定义("Default"替换为模块名称)
#define LOGGER_TRACE(format, ...) LOGGER_TRACE_BASE("Default", format, ##__VA_ARGS__)
#define LOGGER_DEBUG(format, ...) LOGGER_DEBUG_BASE("Default", format, ##__VA_ARGS__)
#define LOGGER_INFO(format, ...) LOGGER_INFO_BASE("Default", format, ##__VA_ARGS__)
#define LOGGER_WARN(format, ...) LOGGER_WARN_BASE("Default", format, ##__VA_ARGS__)
#define LOGGER_ERROR(format, ...) LOGGER_ERROR_BASE("Default", format, ##__VA_ARGS__)
#define LOGGER_FATAL(format, ...) LOGGER_FATAL_BASE("Default", format, ##__VA_ARGS__)
// 无位置信息默认日志宏定义,可根据不同模块自行定义("Default"替换为模块名称)
#define LOGGER_TRACE_S( format, ... ) ::Tool::Logger::logTrace( "Default", format, ##__VA_ARGS__ )
#define LOGGER_DEBUG_S( format, ... ) ::Tool::Logger::logDebug( "Default", format, ##__VA_ARGS__ )
#define LOGGER_INFO_S( format, ... ) ::Tool::Logger::logInfo( "Default", format, ##__VA_ARGS__ )
#define LOGGER_WARN_S( format, ... ) ::Tool::Logger::logWarn( "Default", format, ##__VA_ARGS__ )
#define LOGGER_ERROR_S( format, ... ) ::Tool::Logger::logError( "Default", format, ##__VA_ARGS__ )
#define LOGGER_FATAL_S( format, ... ) ::Tool::Logger::logFatal( "Default", format, ##__VA_ARGS__ )
//可自重新定义宏,并且将其"Default"改为其他字符串以区分模块
五、自定义配置
# 日志配置文件
# Author: yu_cheng@dahuatech.com
# 说明:仅常用日志配置说明
#
# 定义一个子Logger:log4j.logger.子Logger名称 = [日志级别], [AppenderA], [AppenderB]
# log4j.logger.subMoudleLog = DEBUG, subMoudleLogAppender
#
# 是否继承rootLogger, true则日志会在子Logger与rootLogger中同时输出
# log4j.additivity.subMoudleLog = false
#
# 设置Appender模式
# log4j.appender.subMoudleLogAppender = org.apache.log4j.RollingFileAppender
#
# 设置日志输出文件
# log4j.appender.subMoudleLogAppender.File = ./SubMoudleLog.log
#
# 设置日志是否追加模式(true:追加模式,false:覆盖模式)
# log4j.appender.subMoudleLogAppender.Append = false
#
# 子模块日志内输出级别控制(输出最低级别)
# log4j.appender.subMoudleLogAppender.Threshold = TRACE
#
# 设置单个日志文件最大容量
# log4j.appender.subMoudleLogAppender.MaxFileSize = 40MB
#
# 设置最大Rolling文件个数
# log4j.appender.subMoudleLogAppender.MaxBackupIndex = 10
#
# 设置日志输出样式
# log4j.appender.subMoudleLogAppender.layout = org.apache.log4j.PatternLayout
#
# 设置日志输出格式(%d:时间, %c:模块名称, %p:日志级别, %t:线程号, %M:具体到函数作用域名,%L:代码行数, %m:代码中要打印的日志, %n:换行, %r:自程序启动到打印该日志时的延时(毫秒) )
# log4j.appender.subMoudleLogAppender.layout.ConversionPattern = %d [%c] [%-5p] [%t] [%M:%L] %m%n
# 配置rootLogger
log4j.rootLogger = DEBUG, default, stdout, debugstring
# 设置日志文件编码
log4j.appender.logfile.encoding = UTF-8
# 设置rootLogger Appender输出格式
log4j.appender.default = org.apache.log4j.RollingFileAppender
log4j.appender.default.File = ./Log/Default_${CPID}.log
log4j.appender.default.Append = true
log4j.appender.CustomAppender.Threshold = TRACE
log4j.appender.default.MaxFileSize = 40MB
log4j.appender.default.MaxBackupIndex = 10
log4j.appender.default.layout = org.apache.log4j.PatternLayout
log4j.appender.default.layout.ConversionPattern = %d [%c] [%-5p] TID[%t] [%M:%L] %m%n
# 标准输出,控制台输出格式
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold = TRACE
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d [%c] [%-5p] TID[%t] [%M:%L] %m%n
# OutputDebugString
log4j.appender.debugstring = org.apache.log4j.OutputDebugStringAppender
log4j.appender.debugstring.Threshold = TRACE
log4j.appender.debugstring.layout = org.apache.log4j.PatternLayout
log4j.appender.debugstring.layout.ConversionPattern = %d [%c] [%-5p] TID[%t] [%M:%L] %m%n
# 默认日志(Debug模式,输出级别DEBUG,并且OutputDebugString)
log4j.logger.Default = DEBUG, default, debugstring
log4j.additivity.Default = false
# 自定义模块输出格式(NetUtility模块)
log4j.logger.NetUtility = INFO, NetUtilityApp, debugstring
log4j.additivity.NetUtility = false
log4j.appender.NetUtilityApp = org.apache.log4j.RollingFileAppender
log4j.appender.NetUtilityApp.File = ./Log/NetUtility.log
log4j.appender.NetUtilityApp.Append = true
log4j.appender.NetUtilityApp.Threshold = TRACE
log4j.appender.NetUtilityApp.MaxFileSize = 40MB
log4j.appender.NetUtilityApp.MaxBackupIndex = 10
log4j.appender.NetUtilityApp.layout = org.apache.log4j.PatternLayout
log4j.appender.NetUtilityApp.layout.ConversionPattern = %d [%c] [%-5p] [%t] [%M:%L] %m%n
六、Logger日志模块总结
1.打印信息齐全有效(时间,模块,位置,线程等)
2.支持进程号设置在日志文件名中,文件本身及是一种记录,如记录软件崩溃时间
3.多线程安全
4.记录性能高效(两个线程各打印1000条日志,所需282ms)
5.代码中可分级编写打印的日志,但实际是否打印到哪各等级可设置,等配置都非常灵活
6.接口非常易用,不同等级接口入参风格一致(如C语言风格打印输出)
7.模块非常易用(添加.lib,.dll,.h即可,.h文件只有一个)
demo工程以及SDK所需文件下载路径:https://download.csdn.net/download/qq_43148810/16113558
SDK源码下载路径:https://download.csdn.net/download/qq_43148810/16113711
内部实现为单例,原理为另一篇文章创建型模式Creational Patterns之单例模式singleton:“三、4”
如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810