分类: LINUX
2012-09-19 17:16:10
一.问题
1.技术部总是说客户的帐套他们无能为力, 要开发部提供援助,严重的影响了开发进度.
2.测试员经常发现些偶然出现的问题, 程序员难以重现场景.
二.思路
1.程序增加往外输出的日志信息;
2.日志信息要分等级;
3.外部可以设置某些等级的内容才输出到日志文件;
三.实现
1.采用Log4cpp库.
2.需要对Log4cpp进行封装.
********************************************************
/** /file Log4cppWapper.h
* /brief 日志输出文件
*/
#ifndef LOG4CPPWAPPER_H
#define LOG4CPPWAPPER_H
#include
#include
#include
#define LogObject static_cast
#define LOG_PRIORITY_FATAL Log4CppWapper::FATAL
#define LOG_PRIORITY_ALERT Log4CppWapper::ALERT
#define LOG_PRIORITY_CRIT Log4CppWapper::CRIT
#define LOG_PRIORITY_ERROR Log4CppWapper::ERR
#define LOG_PRIORITY_WARN Log4CppWapper::WARN
#define LOG_PRIORITY_NOTICE Log4CppWapper::NOTICE
#define LOG_PRIORITY_INFO Log4CppWapper::INFO
#define LOG_PRIORITY_DEBUG Log4CppWapper::DEBUG
#define LOG_PRIORITY_NOTSET Log4CppWapper::NOTSET
#define LOGMESSAGE(P, MSG) Log4CppWapper::Log((P), (MSG), __FILE__, __FUNC__, __LINE__);
#define LOGFILENAME "sd5000.log"
/** /brief Log4Cpp外壳 */
class _export Log4CppWapper
{
public:
/** 优先权等级 */
typedef enum {
EMERG = 0,
FATAL = 0,
ALERT = 100,
CRIT = 200,
ERR = 300,
WARN = 400,
NOTICE = 500,
INFO = 600,
DEBUG = 700,
NOTSET = 800
} PriorityLevel;
/** 取得Log4CppWapper的单件实例 */
static Log4CppWapper& GetInstance()
{
static Log4CppWapper lcw;
static bool bInited;
if (!bInited)
{
lcw.InitInstance();
bInited = true;
}
return lcw;
}
/** 输出日志 */
static void Log(Log4CppWapper::PriorityLevel priority, const char* szlog);
/** 输出日志 */
static void Log(Log4CppWapper::PriorityLevel priority, const std::string& strlog);
/** 输出日志 */
static void Log(Log4CppWapper::PriorityLevel priority, const AnsiString& aslog);
/** 输出日志(包含文件名、函数名及函数) */
static void Log(Log4CppWapper::PriorityLevel priority, const char* szlog,
const char* file, const char* func, int line);
/** 输出日志(包含文件名、函数名及函数) */
static void Log(Log4CppWapper::PriorityLevel priority, const std::string& strlog,
const char* file, const char* func, int line);
/** 输出日志(包含文件名、函数名及函数) */
static void Log(Log4CppWapper::PriorityLevel priority, const AnsiString& aslog,
const char* file, const char* func, int line);
/** 初始化单件实例 */
void InitInstance();
/** 取得Log4Cpp输出对象 */
void* GetCategory(){ return sd_log; }
~Log4CppWapper();
private:
Log4CppWapper(){};
/** Log4Cpp输出对象 */
void* sd_log;
};
#endif
其中, InitInstance()的实现:
/** 初始化单件实例 */
void Log4CppWapper::InitInstance()
{
// 1. 实例化一个layout 对象
log4cpp::PatternLayout* layout =
new log4cpp::PatternLayout();
layout->setConversionPattern(std::string("%c:%d [%p] %x %m %n"));
// 2. 初始化一个appender 对象
log4cpp::Appender* appender = new
log4cpp::FileAppender("FileAppender",
AnsiString(ExtractFileDir(Application->ExeName)+"());
// 3. 把layout对象附着在appender对象上
appender->setLayout(layout);
// 4. 实例化一个category对象
sd_log =
&log4cpp::Category::getInstance("sdwarn");
// 5. 设置additivity为false,替换已有的appender
static_cast
// 5. 把appender对象附到category上
static_cast
// 6. 设置category的优先级,低于此优先级的日志不被记录
PriorityLevel priority = MatchInfo::Instance()->HadOption("SDDEBUG")?
LOG_PRIORITY_DEBUG:LOG_PRIORITY_WARN;
static_cast
}
在这函数的第6步中, 要实现的目标是从外部的文件读出设置, 决定哪些等级的日志需要往外输出.期实现代码如下:
class MatchInfo
{
public:
/** 验证版本信息函数,通过静态实例调用
* /param[in] 被验证的版本信息
调用格式例如:MatchInfo::Instance()->HadOption("SDDEBUG");
*/
bool HadOption(AnsiString str){return FOptions.find(UpperCase(str))!=FOptions.end();};
static MatchInfo* Instance(); ///<静态实例
private:
static MatchInfo* _Instance;
MatchInfo(){}; ///<构造函数
std::set
};
//---------------------------------------------------------------------------
/***********************************************************************/
#include "MatchInfo.h"
//---------------------------------------------------------------------------
MatchInfo* MatchInfo::_Instance = 0;
//---------------------------------------------------------------------------
//静态实例
MatchInfo* MatchInfo::Instance()
{
if (_Instance == 0)
{
_Instance = new MatchInfo;
//读文件并将内容放入容器
if (FileExists("license"))
{
TStringList *strList = new TStringList;
strList->LoadFromFile("license");
for (int i=0; i
{
_Instance->FOptions.insert(UpperCase(strList->Strings[i]));
}
delete strList;
}
}
return _Instance;
}
//---------------------------------------------------------------------------
3.调用代码:
try
{
//...
}
catch(Exception* E)
{
LOGMESSAGE(LOG_PRIORITY_ERROR, E->Message);
}