log4cplus mysql_CentOS 6.2下log4cplus的使用

2023-10-13 09:30

本文主要是介绍log4cplus mysql_CentOS 6.2下log4cplus的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、简介

log4cplus是一款优秀的基于C/C++的开源日志库。log4cplus具有线程安全,不用但心在多线程状态下写日志问题;使用灵活,可通过配置文件设置日志级别下输出位置,还可以在程序运行时动态设置日志输出级别,随心所欲掌控日志的输出;以及多粒度控制的特点。通过将信息划分优先级使其可以面向程序调试、运行、测试、和维护等全生命周期; 可以选择将信息输出到屏幕、文件、NT event log、甚至是远程服务器;通过指定策略对日志进行定期备份。可以满足大部分开发者对日志系统需求,功能全面。

二、安装

tar -xjf log4cplus-1.0.4.tar.bz2(解压缩),切换到解压缩路径下

安装:./configure;make;make install

这里已经安装成功,默认的路径lib库路径是/usr/local/lib/,头文件的位置:/usr/local/include/log4cplus

将/usr/local/lib下的和log4cplus相关的库都拷贝到/usr/lib,将头文件加到/etc/profile下的CPLUS_INCLUDE_PATH

三、使用

虽然功能强大,应该说log4cplus用起来还是比较复杂的,为了更好地使用它,先介绍一下它的基本要素。

Layouts      :布局器,控制输出消息的格式.

Appenders    :挂接器,与布局器紧密配合,将特定格式的消息输出到所挂接的设备终端

(如屏幕,文件等等)。

Logger       :记录器,保存并跟踪对象日志信息变更的实体,当你需要对一个对象进行

记录时,就需要生成一个logger。

Categories   :分类器,层次化(hierarchy)的结构,用于对被记录信息的分类,层次中

每一个节点维护一个logger的所有信息。

Priorities   :优先权,包括TRACE, DEBUG, INFO, WARNING, ERROR, FATAL。

示例1:

#include #include#include#include

using namespacestd;int main(int argc, char **argv)

{using namespacelog4cplus;

BasicConfigurator config;

config.configure();

Logger logger= Logger::getInstance("main");

LOG4CPLUS_ERROR(logger,"Hello, error!");

LOG4CPLUS_WARN(logger,"Hello, warn!");

LOG4CPLUS_INFO(logger,"Hello, info!");

LOG4CPLUS_DEBUG(logger,"Hello, debug!");return 0;

}

这个例子是最简单的,只使用到了Logger记录器。默认输出到屏幕。输出格式如下:

3542206b2067ffca4650d1ede0b098ed.png

示例二:

#include #include#include#include

using namespacestd;int main(int argc, char **argv)

{using namespacelog4cplus;

Logger logger= Logger::getInstance("main");

SharedAppenderPtr appender(newConsoleAppender());

std::string pattern = "%D{%m/%d/%y %H:%M:%S} %p - %m%n";

std::auto_ptr layout(newPatternLayout(pattern));

appender->setLayout(layout);

logger.addAppender(appender);

LOG4CPLUS_ERROR(logger,"Hello, error!");

LOG4CPLUS_WARN(logger,"Hello, warn!");

LOG4CPLUS_INFO(logger,"Hello, info!");

LOG4CPLUS_DEBUG(logger,"Hello, debug!");return 0;

}

这个例子做了改进,我们使用到了Appender,Layout。上面说过,Layout用来控制日志的输出格式,有三种Layout:SimpleLayout、PatternLayout、TTCCLayout。Appender用来控制日志输出的地方,比如:控制台、文件等。而且Layout是依附于Appender的,所以,如果我们想要自己控制日志格式,那么必须先获取一个Appender,然后吧

/**

* Set the layout for this appender. Note that some appenders have

* their own (fixed) layouts or do not use one. For example, the

* SocketAppender ignores the layout set here.*/

virtual void setLayout(std::auto_ptr layout);

这个Appender类的setLayout函数,也就是设置Layout的函数。它需要的参数是一个智能指针。

virtual void addAppender(SharedAppenderPtr newAppender);

这个是Logger类中设置Appender的函数,它需要的参数是一个SharedAppenderPtr类型。

所以如果我们要使用Appender和Layout,就需要构造这样的类型,并传入到对应的函数中去。

因为Layout是需要依附于Appender的,所以,这里我们使用了一个ConsoleAppender类以及PatternLayout类。

输出格式如下:

c370a8d8aa24c7f015f9172334629f3e.png

相比于示例1,这里的每一条日志前面都输出了时间。这就是使用Layout的效果,这里先详细介绍一个PatternLayout的使用方法,之后再介绍另外两种Layout。

PatternLayout:

可以看出通过填写特定格式的模式字符串"pattern",原始信息被包含到一堆有格式的信息当中了,这就使得

用户可以根据自身需要来定制显示内容。"pattern"可以包含普通字符串和预定义的标识符,其中:

(1)普通字符串,能够被直接显示的信息。

(2)预定义标识符,通过"%"与一个或多个字符共同构成预定义的标识符,能够产生出特定格式信息。

关于预定义标识符,log4cplus文档中提供了详细的格式说明,我每种都试了一下,以上述代码为例,根据不同

的pattern,各种消息格式使用情况列举如下:

(1)"%%",转义为%, 即,std::string pattern = "%%" 时输出: "%"

(2)"%c",输出logger名称,比如std::string pattern ="%c" 时输出: "test_logger.subtest",

也可以控制logger名称的显示层次,比如"%c{1}"时输出"test_logger",其中数字表示层次。

(3)"%D",显示本地时间,当std::string pattern ="%D" 时输出:"2004-10-16 18:55:45",%d显示标准时间,

所以当std::string pattern ="%d" 时输出 "2004-10-16 10:55:45" (因为我们是东8区,差8个小时啊)。

可以通过%d{...}定义更详细的显示格式,比如%d{%H:%M:%s}表示要显示小时:分钟:秒。大括号中可显示的

预定义标识符如下:

%a -- 表示礼拜几,英文缩写形式,比如"Fri"

%A -- 表示礼拜几,比如"Friday"

%b -- 表示几月份,英文缩写形式,比如"Oct"

%B -- 表示几月份,"October"

%c -- 标准的日期+时间格式,如 "Sat Oct 16 18:56:19 2004"

%d -- 表示今天是这个月的几号(1-31)"16"

%H -- 表示当前时刻是几时(0-23),如 "18"

%I -- 表示当前时刻是几时(1-12),如 "6"

%j -- 表示今天是哪一天(1-366),如 "290"

%m -- 表示本月是哪一月(1-12),如 "10"

%M -- 表示当前时刻是哪一分钟(0-59),如 "59"

%p --表示现在是上午还是下午, AM or PM%q -- 表示当前时刻中毫秒部分(0-999),如 "237"

%Q -- 表示当前时刻中带小数的毫秒部分(0-999.999),如 "430.732"

%S -- 表示当前时刻的多少秒(0-59),如 "32"

%U -- 表示本周是今年的第几个礼拜,以周日为第一天开始计算(0-53),如 "41"

%w -- 表示礼拜几,(0-6, 礼拜天为0),如 "6"

%W -- 表示本周是今年的第几个礼拜,以周一为第一天开始计算(0-53),如 "41"

%x -- 标准的日期格式,如 "10/16/04"

%X -- 标准的时间格式,如 "19:02:34"

%y -- 两位数的年份(0-99),如 "04"

%Y -- 四位数的年份,如 "2004"

%Z -- 时区名,比如 "GMT"

(4)"%F",输出当前记录器所在的文件名称,比如std::string pattern ="%F" 时输出: "main.cpp"

(5)"%L",输出当前记录器所在的文件行号,比如std::string pattern ="%L" 时输出: "51"

(6)"%l",输出当前记录器所在的文件名称和行号,比如std::string pattern ="%L" 时输出:

"main.cpp:51"

(7)"%m",输出原始信息,比如std::string pattern ="%m" 时输出: "teststr",即上述代码中

LOG4CPLUS_DEBUG的第二个参数,这种实现机制可以确保原始信息被嵌入到带格式的信息中。

(8)"%n",换行符,没什么好解释的

(9)"%p",输出LogLevel,比如std::string pattern ="%p" 时输出: "DEBUG"

(10)"%t",输出记录器所在的线程ID,比如std::string pattern ="%t" 时输出: "1075298944"

(11)"%x",嵌套诊断上下文NDC (nested diagnostic context) 输出,从堆栈中弹出上下文信息,NDC可以用对

不同源的log信息(同时地)交叉输出进行区分,关于NDC方面的详细介绍会在下文中提到。

(12)格式对齐,比如std::string pattern ="%-10m"时表示左对齐,宽度是10,此时会输出"teststr   ",当

然其它的控制字符也可以相同的方式来使用,比如"%-12d","%-5p"等等(刚接触log4cplus文档时还以为

"%-5p"整个字符串代表LogLevel呢,呵呵)。

SimpleLayout:

是一种简单格式的布局器,在输出的原始信息之前加上LogLevel和一个"-"。就是示例1的输出形式。

TTCCLayout:

是在PatternLayout基础上发展的一种缺省的带格式输出的布局器, 其格式由时间,线程ID,Logger和NDC 组

成(consists of time, thread, Logger and nested diagnostic context information, hence the name),

因而得名(怎么得名的?Logger里哪里有那个"C"的缩写啊!名字起得真够烂的,想扁人)。提供给那些想显示

典型的信息(一般情况下够用了)又懒得配置pattern的同志们。

示例三:

下面我们开始尝试将日志记录到文件中,这里需要用到文件相关的Appender类,log4cplus提供了三个这样的类:FileAppender类、RollingFileAppender类、DailyRollingFileAppender类。

FileAppender类:

实现了基本的文件操作,构造函数如下:

FileAppender(const log4cplus::tstring&filename,

std::ios_base::openmode mode=std::ios_base::trunc,bool immediateFlush = true);

filename : 文件名

mode : 文件类型,可选择的文件类型包括app、ate、binary、in、out、trunc,因为实际上只是对stl的一个简单包装,呵呵,这里就不多讲了。缺省是trunc,表示将先前文件删除。

immediateFlush :缓冲刷新标志,如果为true表示每向文件写一条记录就刷新一次缓存,否则直到FileAppender被关闭或文件缓存已满才更新文件,一般是要设置true的,比如你往文件写的过程中出现了错误(如程序非正常退出),即使文件没有正常关闭也可以保证程序终止时刻之前的所有记录都会被正常保存。

RollingFileAppender类:

RollingFileAppender类可以根据你预先设定的大小来决定是否转储,当超过该大小,后续log信息会另存到新

文件中,除了定义每个记录文件的大小之外,你还要确定在RollingFileAppender类对象构造时最多需要多少个

这样的记录文件(maxBackupIndex+1),当存储的文件数目超过maxBackupIndex+1时,会删除最早生成的文件,

保证整个文件数目等于maxBackupIndex+1。然后继续记录

构造函数如下:

RollingFileAppender(const log4cplus::tstring&filename,long maxFileSize = 10*1024*1024, //10 MB

int maxBackupIndex = 1,bool immediateFlush = true);

filename : 文件名

maxFileSize : 文件的最大尺寸

maxBackupIndex : 最大记录文件数

immediateFlush : 缓冲刷新标志

log4cplus中隐含定义了文件的最小尺寸是200K,只有大于200K的设置才生效,<= 200k的设置都会被认为是

200K.

DailyRollingFileAppender类:

DailyRollingFileAppender类可以根据你预先设定的频度来决定是否转储,当超过该频度,后续log信息会另存

到新文件中,这里的频度包括:MONTHLY(每月)、WEEKLY(每周)、DAILY(每日)、TWICE_DAILY(每两天)、

HOURLY(每时)、MINUTELY(每分)

构造函数如下:

DailyRollingFileAppender(const log4cplus::tstring&filename,

DailyRollingFileSchedule schedule=DAILY,bool immediateFlush = true,int maxBackupIndex = 10);

filename : 文件名

schedule : 存储频度

immediateFlush : 缓冲刷新标志

maxBackupIndex : 最大记录文件数

这里我们就使用FileAppender来将日志写入到文件中,代码如下:

#include #include#include#include

using namespacestd;int main(int argc, char **argv)

{using namespacelog4cplus;

Logger logger= Logger::getInstance("main");

SharedAppenderPtr appender(new FileAppender("example3.log"));

std::string pattern = "%D{%m/%d/%y %H:%M:%S} %p - %m%n";

std::auto_ptr layout(newPatternLayout(pattern));

appender->setLayout(layout);

logger.addAppender(appender);

LOG4CPLUS_ERROR(logger,"Hello, error!");

LOG4CPLUS_WARN(logger,"Hello, warn!");

LOG4CPLUS_INFO(logger,"Hello, info!");

LOG4CPLUS_DEBUG(logger,"Hello, debug!");return 0;

}

相比于示例2,只是修改了一下Appender的类型。

输出结果:

5b4490e97bed536e0b0464e6829d291b.png

四、优先级控制

日志系统的另一个基本功能就是能够让使用者能够按照自己的意愿控制什么时候,哪些信息可以输出。如果能够让用户在任意时刻设置允许输出的loglevel信息就好了。log4cplus通过LoglevelManager、LogLog、Filter三种方式实现了上述功能。

在研究LogLevelManager之前,首先介绍一下log4cplus中logger的存储机制,在log4cplus中,所有logger都通过一个层次化的结构(其实内部是hash表)来组织的,有一个Root级别的logger,可以通过一下方法获取。

Logger root = Logger::getRoot();

用户定义的logger都有一个名字与之对应,比如:

Logger test = Logger::getInstance("test");

可以定义该logger的子logger:

Logger subTest = Logger::getInstance("test.subtest");

注意:Root级别的logger只有通过getRoot()方法获取,Logger::getInstance("root")获得的是它的子对象而已。有了这些具有父子关系的logger之后可以分别设置其LogLevel,比如:

root.setLogLevel(...);

Test.setLogLevel(...);

subTest.setLogLevel(...);

LogLevelManager负责设置logger的优先级,各个logger可以通过setLogLevel设置自己的优先级,

当某个logger的LogLevel设置成NOT_SET_LOG_LEVEL时,该logger会继承父logger的优先级,另外,

如果定义了重名的多个logger, 对其中任何一个的修改都会同时改变其它logger。

参考:

这篇关于log4cplus mysql_CentOS 6.2下log4cplus的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/202285

相关文章

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

数据库面试必备之MySQL中的乐观锁与悲观锁

《数据库面试必备之MySQL中的乐观锁与悲观锁》:本文主要介绍数据库面试必备之MySQL中乐观锁与悲观锁的相关资料,乐观锁适用于读多写少的场景,通过版本号检查避免冲突,而悲观锁适用于写多读少且对数... 目录一、引言二、乐观锁(一)原理(二)应用场景(三)示例代码三、悲观锁(一)原理(二)应用场景(三)示例

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

SQL server配置管理器找不到如何打开它

《SQLserver配置管理器找不到如何打开它》最近遇到了SQLserver配置管理器打不开的问题,尝试在开始菜单栏搜SQLServerManager无果,于是将自己找到的方法总结分享给大家,对SQ... 目录方法一:桌面图标进入方法二:运行窗口进入方法三:查找文件路径方法四:检查 SQL Server 安

MySQL 中的 LIMIT 语句及基本用法

《MySQL中的LIMIT语句及基本用法》LIMIT语句用于限制查询返回的行数,常用于分页查询或取部分数据,提高查询效率,:本文主要介绍MySQL中的LIMIT语句,需要的朋友可以参考下... 目录mysql 中的 LIMIT 语句1. LIMIT 语法2. LIMIT 基本用法(1) 获取前 N 行数据(