SimpleLayout, TTCCLayout and PatternLayout. The following are the examples
SimpleLayout : DEBUG - Hello world
TTCCLayout : 225 [main] INFO Hello World
PatternLayout:INFO 21 May 2001 11:00:57,109 HELLO WORLD
Appender模块:决定了将日志输出到具体的devices。
用户自己可以根据Appender实现继承类,将log输出到socket, a shared memory buffer或者其他设备上。在1.0.2版本中, FileAppender, RollingFileAppender, and ConsoleAppender
Logger模块:实现了logging, 一个logger对象主要包括了两个主要部分appenders和 log level。
logger对象被创建的时候,其中包含了默认的appender标准输出和默认的priority with none。之后可以添加更多的appenders到指定的logger,priority的等级划分 NOT_SET_LOG_LEVEL, TRACE_LOG_LEVEL, DEBUG_LOG_LEVEL, INFO_LOG_LEVEL, WARN_LOG_LEVEL, ERROR_LOG_LEVEL, FATAL_LOG_LEVEL。Appenders类集合在Logger类中由hierarchy类负责管理。
主要使用流程:
1. 如果需要初始化一个console appender或者一个 file appender:
2. 如果需要初始化layout对象:SharedAppenderPtr myAppender(new FileAppender("myLogFile.log"));
myAppender->setName("myAppenderName");
std::auto_ptr<Layout>; myLayout = std::auto_ptr<Layout>(new log4cplus::TTCCLayout());3. 绑定layout到appender:
myAppender->setLayout( myLayout );4. 初始化logger:
Logger myLogger= Logger::getInstance("myLoggerName");5. 绑定appender到logger:
myLogger.addAppender(myAppender);6. 设置loglevel:
myLogger.setLogLevel ( INFO_LOG_LEVEL );7. 最后输出log消息到指定logger:
LOG4CPLUS_FATAL(myLogger, "logEvent");//for a fatal priority event
LOG4CPLUS_ERROR(myLogger, "logEvent");//for a error priority event
LOG4CPLUS_WARN(myLogger, "logEvent") ;//for a warn priority event
LOG4CPLUS_INFO(myLogger, "logEvent"); //for a info priority event
LOG4CPLUS_DEBUG(myLogger, "logEvent");//for a debug priority event
log4cplus在了解了几个主要模块功能之后,自己耐心解读应该不会很难
读源码的时候可以参考:
(一) http://www.cppblog.com/tx7do/articles/11715.html
(二) http://www.cppblog.com/tx7do/articles/11716.html
(三) http://www.cppblog.com/tx7do/articles/11717.html
(四) http://www.cppblog.com/tx7do/articles/11718.html
(五) http://www.cppblog.com/tx7do/articles/11719.html
(六) http://www.cppblog.com/tx7do/articles/11720.html
(七) http://www.cppblog.com/tx7do/articles/11721.html
一些收获
1. static局部变量的使用:
class Logger{
... // others
Hierarchy& Logger::getDefaultHierarchy()
{
static Hierarchy defaultHierarchy;
return defaultHierarchy;
}
}
Hierarchy类用以管理logger树,使用map来维持所有logger,并且管理父Logger和子Logger的关系。
所有的Logger类需要具有唯一的一个defaultHierarchy ,如果是我,可能会将Hierarchy设计成单例模式,或者直接在Logger类中添加成员变量static defaultHierarchy。作者采用的方法利用了static局部变量的特性,同时很好的对外隐藏了defaultHierarchy,以及更小的限定了作用域。
另例:同样以static局部变量达到了singleton的效果。
class LOG4CPLUS_EXPORT LogLevelManager {
/**
* Returns the singleton LogLevelManager.
*/
LOG4CPLUS_EXPORT LogLevelManager& getLogLevelManager() {}
}
LogLevelManager&
log4cplus::getLogLevelManager()
{
static LogLevelManager singleton;
return singleton;
}
2. 大量采用Impl设计方式( 进一步学习http://blog.csdn.net/onejian/article/details/17484283)
class LoggerImpl;
class Logger
{
...
protected:
// Data
/** This is a pointer to the implementation class. */
spi::LoggerImpl *value;
// Friends
friend class log4cplus::spi::LoggerImpl;
}
实现类中私有部分对外隐藏,同时减少编译依赖,解开使用接口和实现的耦合度。
3. Logger的实例化采用抽象Factory的设计模式:( 进一步学习http://blog.csdn.net/onejian/article/details/17484571 http://blog.csdn.net/onejian/article/details/17484565)/** * This class is used to create the default implementation of
* the Logger class */
class LOG4CPLUS_EXPORT DefaultLoggerFactory : public spi::LoggerFactory {
public:
Logger makeNewLoggerInstance(const log4cplus::tstring& name, Hierarchy& h);
};
/** * Implement this interface to create new instances of Logger or
* a sub-class of Logger.
*/
class LOG4CPLUS_EXPORT LoggerFactory {
public:
/** * Creates a new <code>Logger</code> object. */
virtual Logger makeNewLoggerInstance(const log4cplus::tstring& name,
Hierarchy& h) = 0;
virtual ~LoggerFactory(){}
};
class Logger
{
... //others
virtual Logger getInstance(const log4cplus::tstring& name, spi::LoggerFactory& factory);
}
因为只具有一个产品等级结构(即Logger),感觉使用Factory method设计模式也可以完成,但是失去了Reveal interface的效果。另外BaseFactory,AppenderFactory...本质上还是采用了抽象工厂的设计方式
4. 智能指针的设计(进步学习http://blog.csdn.net/onejian/article/details/17484153)
safe_auto_ptr类在std::auto_ptr的基础进行封装,对空指针异常进行了抛出处理。ShareObjectPtr模板类类似于Boost::shared_ptr模板类,采用引用计数方法,可以看到作者添加了access_mutex来保证了ShareObjectPtr线程安全,shared_ptr不能保证同时写线程安全。作者在头文件中也提到了,在设计此类的时候参考了More Effective C++。
// Note: Some of this code uses ideas from "More Effective C++" by Scott// Myers, Addison Wesley Longmain, Inc., (c) 1996, Chapter 29, pp. 183-213
//
5. 借鉴log4cplus,实现了一个自己的logger,线程池,后续将贴上github上的地址