日志系统
概述
- 记录系统的运行轨迹,在这个基础上,进行跟踪分析
错误,审计系统运行流程。 - 一个日志系统根据他的过程,可以分为四个模块
- 日志来源:日志内容可以来源于任何其他系统,但对日志系统来说,这是个格式化的缓冲区
- 系统控制:系统控制的重点在于控制日志内容在日志系统中的流转过程。比如日志输出目的地,比如日志的输出级别
- 日志输出:日志在控制台输出是比较常见的,但如何考虑为系统的可靠性提供支持,以及大量日志内容的情况下,这个一般不予考虑的。在控制台输出的,只会是非常核心的内容或者是致命的错误,况且,在有些情况下,不一样会有控制台。我们一般在这种情况下,都倾向于将日志输出到文件
- 日志存储:日志存储在很多小型系统往往并不需要关注,一个可靠性要求很高的系统中,对日志存储却是极为苛刻。就是在现在的数据库系统中,也必须依赖日志的存在,来还原操作
设计思路
- 日志库的设计,一般而言要抓住最核心的一条,就是日志从产生到到达最终目的地期间的处理流程
- 一般而言,主要将日志库分为4个部分
- 记录器:负责产生日志记录的原始信息,比如(原始信息,日志等级,时间,记录的位置)等等信息
- 过滤器:负责按指定的过滤条件过滤掉我们不需要的日志(比如按日志等级过滤)
- 格式化器:负责对原始日志信息按照我们想要的格式去格式化
- 输出器:负责将将要进行记录的日志(一般经过过滤器及格式化器的处理后)记录到日志目的地(例如:输出到文件中)
日志分类
级别分类
-
取值越小,优先级越高
来源分类
Log4cpp
__FILE__ __LINE__ __ FUNCTION__
//可打印文件名,行数,函数名的宏定义
-
使用原则
- 不要手动释放 Category、Appender 和 Layout;
- 同一个 Appender 不要加入多个 Category,否则它会被释放多次从而导致程序崩溃;
- 同一个 Layout 不要附着到多个 Appender 上,否则也会被释放多次导致程序崩溃;
- log4cpp::Category::shutdown()
在不使用 log4cpp 时可调用 ,其功能如同
HierarchyMaintainer 的内存清理。
第1步:设置日志格式Layout
格式1:BasicLayout
-
时间戳+优先级+内容
-
头文件log4cpp/BasicLayout.hh
-
BasicLayout *pbl = new BasicLayout();
格式2:SimpleLayout
- 优先级+日志信息
- 头文件log4cpp/SimpleLayout.hh
- SimpleLayout *psl = new SimpleLayout();
格式3:PatternLayout
-
使用类似printf的格式化模式
-
头文件log4cpp/PatternLayout.hh
-
PatternLayout *ppl = new PatternLayout();
-
ppl->setConversionPattern(“%d %c [%p] %m %n”);
第2步:设置日志目的地Appender
方法1:OstreamAppender
-
输出到一个ostream类
-
头文件log4cpp/OstreamAppender.hh
-
OstreamAppender *poa = new OstreamAppender(“OstreamAppender”,&cout);
(参数是appender的名称,流的名称)
-
poa->setLayout(第1步指针);
方法2:StringQueueAppender
-
输出到内存中的字符串队列
-
头文件log4cpp/StringQueueAppender.hh
-
StringQueueAppender *psqa = new StringQueueAppender(“StringQueueAppender”);
(参数是appender的名称)
-
psqa->setLayout(第一步指针);
方法3:FileAppender
-
输出到文件
-
头文件log4cpp/FileAppender.hh
-
FileAppender *pfa = new FileAppender(“FileAppender”,“文件”,true,00644);
(参数是appender的名称,日志文件名,是否继续记入,文件打开方式权限)
-
pfa->setLayout(第一步指针);
方法4:RollingFileAppender
-
回滚输出到文件
-
头文件log4cpp/RollingFileAppender.hh
-
RollingFileAppender *prfa = new RollingFileAppender(“RollingFileAppender”,”文件“,maxFileSize,maxBackupIndex,true,00644);
(参数是appender的名称,日志文件名,回滚文件最大值,回滚文件所用备份文件最大个数,是否继续记入,文件打开方式权限)
-
prfa->setLayout(第一步指针);
第3步:设置格式记录器Category
-
负责向日志中写入信息
-
头文件log4cpp/Category.hh
-
Category &root = Category ::getRoot().getInstance(“”);
(Log4cpp 中有一个总是可用并实例化好的 Category,即根 Category。使用log4cpp::Category::getRoot()可以得到根 Category。
在大多数情况下,一个应用程序只需要一个日志种类(Category),但是有时也会用到多个Category,此时可以使用根 Category 的 getInstance 方法来得到子 Category。不同的子
Category 用于不同的场合。) -
root.addAppender(第二步指针);
(设置或添加appender)
-
root.setPriority(Priority::级别)
(只有当日志的优先级高于category的时候才会被记录)
第4步:设置日志优先级
-
头文件log4cpp/Priority.hh
-
root.emerg("This is an emerg message"); //emerg和fatal优先级都是0,无法识别 root.fatal("This is an fatal message"); root.alert("This is an alert message"); root.crit("This is an crit message"); root.error("This is an error message"); root.warn("This is an warn message"); root.notice("This is an notice message"); root.info("This is an info message"); root.debug("This is an debug message"); //回收 Category::shutdown();
-
每个Category都有一个优先级,该优先级可以由setPriority
方法设置,或者从其父 Category 中继承而来 -
每条日志也有一个优先级,当 Category 记录该条日志时,若日志优先级高于 Category 的优先级时,该日志被记录,否则被忽略
-
数字越小优先级越高
EMERG=0,FATAL=0,
ALERT=100,
CRIT=200,
ERROR=300,
WARN=400,
NOTICE=500,
INFO=600,
DEBUG=700,
NOTSET =800
-
Log4cpp 中 new 出来的 Category、Appender 和 Layout 都不需要手动释放,因为 Log4cpp 使用了一个内部类来管理这些对象。此类的名称是 HierarchyMaintainer,它负责管理 Category 的继承关系,在程序结束时,HierarchyMaintainer 会依次释放所有 Category,而 Category 则会依次释放拥有的有效 Appender,Appender 则会释放所有附属的 Layout。如果程序员手动释放这些对象,则会造成内存报错。
-
g++ log4test.cpp -llog4cpp -lpthread
关系,在程序结束时,HierarchyMaintainer 会依次释放所有 Category,而 Category 则会依次释放拥有的有效 Appender,Appender 则会释放所有附属的 Layout。如果程序员手动释放这些对象,则会造成内存报错。 -
g++ log4test.cpp -llog4cpp -lpthread