Document directory
- Preface
- Interface Design
- Log4cxx Encapsulation
- Solve log4cxx Chinese garbled characters
- Welcome to join
C ++ open-source cross-platform OJ system question determination core freejudger (2) -- logger Design
By Ma Dongliang (cream Loki)
One man's war (http://blog.csdn.net/MDL13412)
Preface
The significance of logstore in programs of medium size or above is needless to say, especially in some parallel programs, it plays a "Debugger" role. There are many open-source logstores. Some famous projects are listed below and their features are analyzed:
Since it was previously encapsulated in LinuxLog4cxxLogstore, so in the freejudger ProjectLoggerModule usedLog4cxxAs the core.
Interface Design
The log interface must provide
Fatal, error, warn, info, debug, traceSeveral log levels, so
IloggerThe interface is designed as follows:
class JUDGER_API ILogger{public: ILogger(); virtual ~ILogger(); virtual void logFatal(const OJString &msg) const = 0; virtual void logError(const OJString &msg) const = 0; virtual void logWarn(const OJString &msg) const = 0; virtual void logInfo(const OJString &msg) const = 0; virtual void logDebug(const OJString &msg) const = 0; virtual void logTrace(const OJString &msg) const = 0;};
Because freejudger is a multi-thread question determination, each thread needs an independent log instance and outputs the log to multiple files. To facilitate management, you need to designLoggerfactoryThe interface is as follows:
class JUDGER_API LoggerFactory{public: typedef std::map<OJInt32_t, ILogger*> LoggerList; typedef std::shared_ptr<LoggerList> SharedLoggerList;public: static ILogger* getLogger(const OJInt32_t loggerId); static bool registerLogger(ILogger *logger, const OJInt32_t loggerId);private: LoggerFactory(); ~LoggerFactory();private: static SharedLoggerList loggers_;private: struct deleter { void operator()(LoggerFactory::LoggerList *pLoggerFactory) { for (LoggerFactory::LoggerList::iterator iter = LoggerFactory::loggers_->begin(); LoggerFactory::loggers_->end() != iter; ++iter) { JUDGER_SAFE_DELETE_OBJ_AND_RESET((*iter).second); } } };};
When usingIloggerInstance passedRegisterloggerRegisterLoggerfactoryThe Code is as follows:
IMUST::LoggerFactory::registerLogger( new IMUST::Log4CxxLoggerImpl(GetOJString("log.cfg"), GetOJString("logger0")), IMUST::LoggerId::AppInitLoggerId);
In the above CodeImust: loggerid: appinitloggeridIs the ID used for the program main thread log instance. For other threads, its definition is as follows:
Namespace loggerid {const primary shard = 0; const primary thread1loggerid = 1; const primary thread2loggerid = 2; const primary thread3loggerid = 3; const primary thread4loggerid = 4; const primary thread5loggerid = 5; const ojint32_t thread6loggerid = 6; const ojint32_t thread7loggerid = 7; const ojint32_t thread8loggerid = 8; // The General ID is numbered from 100 and 1-is left to the thread}
Because the specific implementation inherits fromIloggerTherefore, log instances can use different underlying implementations at the same time. The instance acquisition and usage are as follows:
ILogger *logger = LoggerFactory::getLogger(LoggerId::AppInitLoggerId); logger->logTrace(GetOJString("[Daemon] - IMUST::InitApp"));
Log4cxx Encapsulation
The complete code is provided here. The first isLogger_log4cxx.h:
# Ifndef imust_oj_logger_log4cxx_h # defineimust_oj_logger_log4cxx_h # include "logger. H "namespace imust {// log4cxx loggerptr cannot use the predeclaration, so class loggerptrwrapper; Class judger_api log4cxxloggerimpl: Public ilogger {public: consume (const ojstring & configfilename, const ojstring & logtag); Virtual ~ Log4cxxloggerimpl (); Virtual void logfatal (const ojstring & MSG) const; virtual void logerror (const ojstring & MSG) const; virtual void logwarn (const ojstring & MSG) const; virtual void loginfo (const ojstring & MSG) const; virtual void logdebug (const ojstring & MSG) const; virtual void logtrace (const ojstring & MSG) const; private: loggerptrwrapper * logger _;} ;}# endif // imust_oj_logger_log4cxx_h
NextLogger_log4cxx.cpp:
#include "Logger_log4cxx.h"#include "../../thirdpartylib/log4cxx/log4cxx.h"#include "../../thirdpartylib/log4cxx/propertyconfigurator.h"namespace IMUST{class LoggerPtrWrapper{public: log4cxx::LoggerPtr &operator ->() { return loggerPtr_; } log4cxx::LoggerPtr &operator *() { return loggerPtr_; } log4cxx::LoggerPtr &operator =(const log4cxx::LoggerPtr loggerPtr) { loggerPtr_ = loggerPtr; return loggerPtr_; }private: log4cxx::LoggerPtr loggerPtr_;};Log4CxxLoggerImpl::Log4CxxLoggerImpl(const OJString &configFileName, const OJString &logTag) : logger_(new LoggerPtrWrapper){ assert(!configFileName.empty() && "Config filename can not be empty"); log4cxx::PropertyConfigurator::configure(configFileName); *logger_ = log4cxx::Logger::getLogger(logTag);}Log4CxxLoggerImpl::~Log4CxxLoggerImpl(){}void Log4CxxLoggerImpl::logFatal(const OJString &msg) const{ (*logger_)->fatal(msg);}void Log4CxxLoggerImpl::logError(const OJString &msg) const{ (*logger_)->error(msg);}void Log4CxxLoggerImpl::logWarn(const OJString &msg) const{ (*logger_)->warn(msg);}void Log4CxxLoggerImpl::logInfo(const OJString &msg) const{ (*logger_)->info(msg);}void Log4CxxLoggerImpl::logDebug(const OJString &msg) const{ (*logger_)->debug(msg);}void Log4CxxLoggerImpl::logTrace(const OJString &msg) const{ (*logger_)->trace(msg);}}
Solve log4cxx Chinese garbled characters
Log4cxx on the Windows platform, even if Unicode is used for compilation, garbled characters will still be generated when outputting Chinese logs. In fact, the solution is very simple. You only need to start the main function, call the following code:
setlocale(LC_ALL, "");
Complete code
For the complete code, see judgerlib/logger in the freejudger project.
Project homepage https://github.com/NsLib/FreeJudger
Welcome to join
Group 117975329, Verification informationCsdn.
Main maintainer:
- Zhou Bao you_lan_hai@foxmail.com
- Ma Dongliang mdl2009@vip.qq.com