# osc-sf-log4cpp **Repository Path**: kzhuo/osc-sf-log4cpp ## Basic Information - **Project Name**: osc-sf-log4cpp - **Description**: 对log4cpp进行封装 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2017-12-30 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README


LRTSW-log4cpp模块使用手册

LRTSW-SW-2



| 编制部门
Owner | 第23事业部 | |---|---| | 适用范围
Scope | LRTS系统 | | 拟稿人
Initiated by | 卓开阔 | | 发行
Issued by | 第23事业部文档中心 | | 受控状态
Control type | □ 非受控 ■ 受控
受控号 NO.: D08 | | 秘密等级
Secret Level | □ 绝密 □ 机密
■ 秘密 □ 一般 |
Table: 修订记录Revision History | 版本 | 日期 | 修改内容 | 拟稿 | 审核 | 批准 | |---|---|---|---|---|---| | v0.0.1 | 2017-12-30 | 创建 | 卓开阔 | | |

# 1 概述 日志模块是UNIFW的重要组成部分,该模块提供调试日志相关的常用操作。该模块对基于sourceforge上最新版本的log4cpp进行封装,便于在C语言中使用。 Log4cpp是一个开源的C++类库,它提供了在C++程序中使用日志和跟踪调试的功能。使用log4cpp,可以很便利地将日志或者跟踪调试信息写入字符流、内存字符串队列、文件、回滚文件、调试器、Windows日志、本地syslog和远程syslog服务器中。 Log4cpp是个基于LGPL的开源项目,移植自Java的日志处理跟踪项目log4j,并保持了API上的一致。其类似的支持库还包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(log4p)等。 Log4cpp有如下优点: - 提供了可扩展的多种日志记录方式; - 提供了NDC(嵌套诊断上下文),可用于多线程、多场景的跟踪调试; - 提供了完整的日志动态优先级控制,可随时调整需要记录的日志优先级; - 可通过配置文件完成所有配置并动态加载; - 代码级的平台无关性,Log4cpp源代码经过编译后,适用于大多数主流的操作系统和开发工具; - 概念清晰,学习和使用方便。 ## 1.1 基本概念 Log4cpp中的概念继承自log4j,最重要的是Category(种类)、Appender(附加目的地)和Layout(布局)三个概念,此外还有Priority(优先级)和NDC(嵌套的诊断上下文)等。 简言之,Category负责向日志中写入信息,Appender负责指定日志的目的地,Layout负责设定日志的格式,Priority被用来指定Category的优先级和日志的优先级, NDC则是一种用来区分不同场景中交替出现的日志的手段。 Log4cpp记录日志的原理如下:每个Category都有一个优先级,该优先级可以由setPriority方法设置,或者从其父Category中继承而来。每条日志也有一个优先级,当Category记录该条日志时,若日志优先级高于Category的优先级时,该日志被记录,否则被忽略。系统优先级采用通用的日志级别。 ``` LOG_EMERG LOG_FATAL LOG_ALERT LOG_CRIT LOG_ERROR LOG_WARN LOG_NOTICE LOG_INFO LOG_DEBUG LOG_NOTSET ``` 注意:取值越小,优先级越高。例如一个Category的优先级为ALERT,则所有EMERG、FATAL、ALERT日志都可以记录下来,而其他则不能。 Category、Appender和Layout三者的关系如下:系统中可以有多个Category,它们都是继承自同一个根,每个Category负责记录自己的日志;每个Category可以添加多个Appender,每个Appender指定了一个日志的目的地,例如文件、字符流或者Windows日志,当Category记录一条日志时,该日志被写入所有附加到此Category的Appender;每个Append都包含一个Layout,该Layout定义了这个Appender上日志的格式。 目前主要支持以下Appender: ```cpp log4cpp::FileAppender // 输出到文件 log4cpp::DailyRollingFileAppender // 输出到日期回卷文件,即当文件到达某个时间条件后回卷 log4cpp::RollingFileAppender // 输出到回卷文件,即当文件到达某个大小后回卷 log4cpp::OstreamAppender // 输出到一个ostream类 log4cpp::SyslogAppender // 输出到syslog log4cpp::RemoteSyslogAppender // 输出到一个远程syslog log4cpp::StringQueueAppender // 内存队列 log4cpp::Win32DebugAppender // 发送到缺省系统调试器,windows专用 log4cpp::NTEventLogAppender // 发送到win事件日志,windows专用 log4cpp::IdsaAppender // 发送到IDSA,需要库支持 ``` 为了便于大家在unifw中使用,只推荐在配置文件中进行相关内容的配置,不在源代码中对相关内容进行操作。 ## 1.2 常用appender介绍 ### 1.2.1 FileAppender FileAppender和RollingFileAppender是log4cpp中最常用的两个Appender,其功能是将日志写入文件中。它们之间唯一的区别就是前者会一直在文件中记录日志(直到操作系统承受不了为止),而后者会在文件长度到达指定值时循环记录日志,文件长度不会超过指定值(默认的指定值是10Mbyte)。 一般仅使用前两个参数,即“名称”和“日志文件名”。第三个参数指示是否在日志文件后继续记入日志,还是清空原日志文件再记录。第四个参数说明文件的打开方式。 它与FileAppender的创建函数很类似,但是多了两个参数:maxFileSize指出了回滚文件的最大值;maxBackupIndex指出了回滚文件所用的备份文件的最大个数。所谓备份文件,是用来保存回滚文件中因为空间不足未能记录的日志,备份文件的大小仅比回滚文件的最大值大1kb。所以如果maxBackupIndex取值为3,则回滚文件(假设其名称是rollwxb.log,大小为100kb)会有三个备份文件,其名称分别是rollwxb.log.1,rollwxb.log.2和rollwxb.log.3,大小为101kb。另外要注意:如果maxBackupIndex取值为0或者小于0,则回滚文件功能会失效,其表现如同FileAppender一样,不会有大小的限制。 ### 1.2.2 NTEventLogAppender 该Appender可以将日志发送到windows的日志,在运行程序后可以打开windows的计算机管理->系统工具->事件查看器->应用程序。 ### 1.2.3 注意事项 在使用log4cpp时应该遵循以下几个使用原则: - 不要手动释放Category、Appender和Layout; - 同一个Appender不要加入多个Category,否则它会被释放多次从而导致程序崩溃; - 同一个Layout不要附着到多个Appender上,否则也会被释放多次导致程序崩溃; #使用方法 ## 1.3 基本使用 ```cpp #include "unifw.h" #include "log/log4cpp.h" int main(int argc, char *argv[]) { log4cpp_init(zlog_conf); VLOG_DEBUG("Get debug count %d", 1); log4cpp_close(); return 0; } ``` ## 1.4 标注配置文件解释 ``` # Set root category priority to DEBUG and its only appender to A1. log4cpp.rootCategory=INFO,rootAppender # 主category级别为INFO,使用rootAppender log4cpp.category.app=DEBUG,A3 # category "app"级别,Appender为A3 log4cpp.category.sc=DEBUG,A4 log4cpp.appender.rootAppender=ConsoleAppender # 设置根cat为终端输出 log4cpp.appender.rootAppender.threshold=INFO # 设置根cat日志级别为>=INFO log4cpp.appender.rootAppender.layout=BasicLayout log4cpp.appender.A3=RollingFileAppender # 设置app cat为回卷文件输出 log4cpp.appender.A3.fileName=APP.log # 日志文件名 log4cpp.appender.A3.maxFileSize=5000000 # 日志大小,默认为10*1024*1024 log4cpp.appender.A3.maxBackupIndex=5 # 允许保存的最大文件数量 #log4cpp.appender.A3.append=1 # 是否采用追加方式 log4cpp.appender.A3.layout=PatternLayout log4cpp.appender.A3.layout.ConversionPattern=[%d %c %p] '%m'%n # 打印格式 log4cpp.appender.A4=DailyRollingFileAppender # 设置sc cat为每日回卷文件输出 #log4cpp.appender.A4.threshold=INFO # 设置本appender的门槛报警级别为>=INFO才打印 log4cpp.appender.A4.fileName=SC.log # 设置文件 #log4cpp.appender.A4.maxDaysKeep=3 # 设置最大文件,默认为0 log4cpp.appender.A4.layout=PatternLayout # 设置布局 log4cpp.appender.A4.layout.ConversionPattern=[%d %c %p] '%m'%n log4cpp.appender.sl=SyslogAppender # 远程syslog log4cpp.appender.sl.syslogName=app # 日志名称 log4cpp.appender.sl.syslogHost=localhost # 远程日志 log4cpp.appender.sl.facility=16 # 设置syslog的facility,LOCAL1从16开始 log4cpp.appender.sl.portNumber=-1 # 设置远程syslog的端口,默认值为-1,内部转换为514 log4cpp.appender.s2=LocalSyslogAppender # 本地syslog log4cpp.appender.s2.syslogName=app # 日志名称 log4cpp.appender.sl.facility=17 # 设置syslog的facility,LOCAL1从16开始 ``` ## 1.5 日志布局layout详解 PatternLayout supports following set of format characters: ``` %% - a single percent sign %c - the category %d - the date\n Date format: The date format character may be followed by a date format specifier enclosed between braces. For example, %d{%H:%M:%S,%l} or %d{%d %m %Y %H:%M:%S,%l}. If no date format specifier is given then the following format is used: "Wed Jan 02 02:03:55 1980". The date format specifier admits the same syntax as the ANSI C function strftime, with 1 addition. The addition is the specifier %l for milliseconds, padded with zeros to make 3 digits. %m - the message %n - the platform specific line separator %p - the priority %r - milliseconds since this layout was created. %R - seconds since Jan 1, 1970 %u - clock ticks since process start %x - the NDC %t - thread name ``` By default, ConversionPattern for PatternLayout is set to "%m%n". ## 1.6 自定义category ```cpp #include "unifw.h" #include "log/log4cpp.h" int main(int argc, char *argv[]) { void *p_route_logger=NULL; log4cpp_init(zlog_conf); VLOG_DEBUG("Get debug count %d", 1); p_route_logger = log4cpp_getlogger("app.ci_route"); RTRACE(p_route_logger, "联锁进路模块初始化"); log4cpp_close(); return 0; } ``` # 2 API使用说明 ```c /** * @brief log4cpp_init 初始化函数 * * @param conf_file 配置文件名称 * @details 按照如下优先级进行配置: * 指定的conf_file, log4cpp.conf文件 * 如果指定为NULL或"",则使用默认配置 * 建议默认名称定义为app的值 * * @return >=0为成功;<0为失败 */ int16_t log4cpp_init(const char *conf_file); /** * @brief log4cpp_close 关闭日志 */ void log4cpp_close(); /** * @brief log4cpp_getlogger 获取指定的category名称 * * @param name 名称 * * @return 指定category的指针,返回值为void* */ void *log4cpp_getlogger(const char *name); /** * @brief RLOG 使用logger进行日志 * * @param r logger指针 * @param pri 优先级 * @param fmt 格式 * */ #define RLOG log4cpp_rawlog /** * @brief APPLOG 使用默认logger进行日志 * * @param pri 优先级 * @param fmt 格式 * */ #define APPLOG(pri, fmt, ...) RLOG(g_l4cpp_app, pri, fmt, ##__VA_ARGS__) /** * @brief SCLOG 使用sclogger进行日志 * * @param pri 优先级 * @param fmt 格式 * */ #define SCLOG (pri, fmt, ...) RLOG(g_l4cpp_sc, pri, fmt, ##__VA_ARGS__) /** * @brief RLOG 使用logger进行日志 * * @param r logger指针 * @param pri 优先级 * @param fmt 格式 * */ #define RLOG /** * @brief APPLOG 使用默认logger进行日志 * * @param pri 优先级 * @param fmt 格式 * */ #define APPLOG(pri, fmt, ...) RLOG(g_l4cpp_app, pri, fmt, ##__VA_ARGS__) /** * @brief VLOG 使用默认logger进行打印 * * @param pri 优先级 * @param fmt 格式 * */ #define VLOG APPLOG #define VLOG_EMERG( fmt, ...) VLOG(LOG_EMERG , fmt, ##__VA_ARGS__) #define VLOG_ALERT( fmt, ...) VLOG(LOG_ALERT , fmt, ##__VA_ARGS__) #define VLOG_CRIT( fmt, ...) VLOG(LOG_CRIT , fmt, ##__VA_ARGS__) #define VLOG_ERR( fmt, ...) VLOG(LOG_ERR , fmt, ##__VA_ARGS__) #define VLOG_WARNING(fmt, ...) VLOG(LOG_WARNING, fmt, ##__VA_ARGS__) #define VLOG_NOTICE( fmt, ...) VLOG(LOG_NOTICE , fmt, ##__VA_ARGS__) #define VLOG_INFO( fmt, ...) VLOG(LOG_INFO , fmt, ##__VA_ARGS__) #define VLOG_DEBUG( fmt, ...) VLOG(LOG_DEBUG , fmt, ##__VA_ARGS__) #define RLOG_EMERG( r, fmt, ...) RLOG(r, LOG_EMERG , fmt, ##__VA_ARGS__) #define RLOG_ALERT( r, fmt, ...) RLOG(r, LOG_ALERT , fmt, ##__VA_ARGS__) #define RLOG_CRIT( r, fmt, ...) RLOG(r, LOG_CRIT , fmt, ##__VA_ARGS__) #define RLOG_ERR( r, fmt, ...) RLOG(r, LOG_ERR , fmt, ##__VA_ARGS__) #define RLOG_WARNING(r, fmt, ...) RLOG(r, LOG_WARNING, fmt, ##__VA_ARGS__) #define RLOG_NOTICE( r, fmt, ...) RLOG(r, LOG_NOTICE , fmt, ##__VA_ARGS__) #define RLOG_INFO( r, fmt, ...) RLOG(r, LOG_INFO , fmt, ##__VA_ARGS__) #define RLOG_DEBUG( r, fmt, ...) RLOG(r, LOG_DEBUG , fmt, ##__VA_ARGS__) #define RTRACE(r, fmt, ...) RLOG(r, LOG_DEBUG, "%s:%d "fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) #define VTRACE(fmt, ...) RTRACE(g_l4cpp_app, fmt, ##__VA_ARGS__) #define SCTRACE(fmt, ...) RTRACE(g_l4cpp_sc, fmt, ##__VA_ARGS__) ```