📄 logmanager.cpp
字号:
/*********************************************************************
* 版权所有 (C)2007, 深圳市中兴通讯股份有限公司。
*
* 文件名称: LogManager.cpp
* 文件标识:
* 内容摘要: 日志线程管理类实现
* 其它说明:
* 当前版本: V1.00
* 作 者:
* 完成日期: 2007/03/15
*
* 修改记录1:
* 修改日期:2005
* 版 本 号:V1.00
* 修 改 人:陈建友
* 修改内容:原始版本
* 修改记录2:
* 修改日期:2007/02/26
* 版 本 号:V1.00
* 修 改 人:王耀峰
* 修改内容:将ICE库替换为Boost库
* 修改记录3:
* 修改日期:2007/03/15
* 版 本 号:V1.00
* 修 改 人:张 帆
* 修改内容:优化代码
**********************************************************************/
#include "LogManager.h"
#include "NOPError.h"
#include "LSUtil.h"
#include "DebugString.h"
using namespace std;
using namespace NOP;
/**************************************************************************
* 类CLogManager的静态数据成员 *
**************************************************************************/
CLogManager CLogManager::m_sLogManager; // 日志线程管理类的单实例对象
/**************************************************************************
* 类CLogManager实现 *
**************************************************************************/
/**************************************************************************
* 函数名称: CLogManager()
* 功能描述: 构造函数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
CLogManager::CLogManager()
{
m_bInitialized = false;
m_bFinalized = false;
}
/**************************************************************************
* 函数名称: ~CLogManager()
* 功能描述: 析构函数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
CLogManager::~CLogManager()
{
}
/**************************************************************************
* 函数名称: GetInstance()
* 功能描述: 获取对象唯一实例
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 日志线程管理类的单实例
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
CLogManager& CLogManager::GetInstance()
{
return m_sLogManager;
}
/**************************************************************************
* 函数名称: Initialize()
* 功能描述: 初始化
* 输入参数: 无
* 输出参数: 无
* 返 回 值: OP_SUCCESS 成功
* 其他返回值参见NOPError.h文件
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
int CLogManager::Initialize()
{
// 获得互斥锁
lock lk(m_mutex);
if (m_bInitialized)
{
return OP_SUCCESS;
}
DBG("Initialize the logger manager! \n");
int rv = 0;
// 初始化配置文件
rv = m_UserProperties.Init("Config\\NOP.conf");
if (rv != OP_SUCCESS)
{
return rv;
}
// 从配置文件中得到配置值
string strLogPath = GetLogPath(); int iMaxLine = GetMaxLine(); int iHistoryAmnt = GetHistoryAmnt();
vector<RemarkItem> vRemarkItems; vector<string> vRemark = GetRemark();
vector<string>::iterator iterRemark = vRemark.begin();
for (; iterRemark != vRemark.end(); ++iterRemark)
{
RemarkItem item;
item.Remark = *iterRemark;
item.Levels = GetLogLevel(item.Remark);
vRemarkItems.push_back(item);
}
// 创建并启动日志线程
vector<RemarkItem>::iterator iter = vRemarkItems.begin();
for (; iter != vRemarkItems.end(); iter++)
{
LogThreadPtr t(
new CLogThread(*iter, strLogPath, iMaxLine, iHistoryAmnt) );
assert(t != NULL);
m_vLogThread.push_back(t);
// 创建即启动
m_threads.create_thread( boost::ref(*t) );
//boost::thread thrd( boost::ref(*t) );
DBG("创建并启动日志线程:%s\n", iter->Remark==""?
"系统日志":(string("备注日志:")+iter->Remark).c_str());
vector<TLogLevel>::iterator iterlvl = iter->Levels.begin();
for (; iterlvl != iter->Levels.end(); iterlvl++)
{
DBG("\t%s\n", CLSUtil::GetLevelString(*iterlvl).c_str());
}
}
m_bInitialized = true;
return OP_SUCCESS;
}
/**************************************************************************
* 函数名称: Finalize()
* 功能描述: 清理并停止
* 输入参数: 无
* 输出参数: 无
* 返 回 值: OP_SUCCESS 成功
* 其他返回值参见NOPError.h文件
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
int CLogManager::Finalize(void)
{
// 获得互斥锁
lock lk(m_mutex);
if (m_bFinalized)
{
return OP_SUCCESS;
}
DBG("Terminate the logger manager! \n");
StopAndWait();
m_bFinalized = true;
return OP_SUCCESS;
}
/**************************************************************************
* 函数名称: AddItem()
* 功能描述: 日志记录派发
* 输入参数: const LogItem& item : 需要记录的日志项
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
void CLogManager::AddItem(const LogItem& item)
{
// lazy initialize ?
/* int rv = Initialize();
if (rv != OP_SUCCESS)
{
DBG("日志管理者初始化失败!");
return;
}
*/
DBG("CLogManager::AddItem, 日志记录派发:\n\t%s\t%s\n\t%s",
item.Remark.c_str(),
CLSUtil::GetLevelString(item.LogLevel).c_str(),
item.Message.c_str());
vector<LogThreadPtr>::const_iterator iter = m_vLogThread.begin();
for (; iter != m_vLogThread.end(); iter++)
{
(*iter)->AddItem(item);
}
}
/**************************************************************************
* 函数名称: GetLogPath()
* 功能描述: 提取日志路径
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 日志文件的路径
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
string CLogManager::GetLogPath(void)
{
string strDefPath = CLSUtil::GetDefaultPath() + DEFPATH + PATHSEP;
string strLogPath = m_UserProperties.GetStrProperty(PATH); DBG("日志路径0: %s\n", strLogPath.c_str()); if (strLogPath != "") //设置了路径
{
if ( strLogPath.find(':') == string::npos) //没有':',相对路径
{
strLogPath = CLSUtil::GetDefaultPath() + strLogPath;
} }
else //没有设置路径,使用默认路径
{
strLogPath = strDefPath;
} //确认以'\\'结尾 if (strLogPath.at(strLogPath.length()-1) != PATHSEP)
{
strLogPath += PATHSEP;
strLogPath = CLSUtil::FullPath(strLogPath);
DBG("日志路径(FULL): %s\n", strLogPath.c_str()); } //创建路径 if (!CLSUtil::make_sure_path_exists(strLogPath.c_str()))
{
//用户设置路径不能创建,使用默认路径
strLogPath = strDefPath;
CLSUtil::make_sure_path_exists(strLogPath.c_str());
} DBG("日志路径: %s\n", strLogPath.c_str()); return strLogPath;
}
/**************************************************************************
* 函数名称: GetMaxLine()
* 功能描述: 从配置文件中获得记录的日志文件最大行数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 日志文件最大行数
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
int CLogManager::GetMaxLine(void)
{
int iMaxLine = m_UserProperties.GetIntProperty(MAXLINE, DEFMAXLINE); DBG("日志最大行数0: %d\n", iMaxLine); if (iMaxLine <= 0)
{
iMaxLine = DEFMAXLINE;
} DBG("日志最大行数: %d\n", iMaxLine);
return iMaxLine;
}
/**************************************************************************
* 函数名称: GetRemark()
* 功能描述: 从配置文件中获得允许记录的备注
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 允许记录的备注
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
vector<string> CLogManager::GetRemark(void)
{
map<string, string> Remarks = m_UserProperties.GetPrefixProperty(LOGREMARK); vector<string> vRemark; vRemark.push_back("");//添加空备注,系统日志记录 //提取备注,忽略非法和重复备注 map<string, string>::const_iterator iter = Remarks.begin();
for (; iter != Remarks.end(); iter++)
{
DBG("新备注:%s\n", iter->second.c_str());
if (!CLSUtil::IsNoCaseStrEqual(iter->second, SYSTEM) //System 保留
&& CLSUtil::IsAllowedFileName(iter->second) //做文件名 检查
&& !CLSUtil::IsExist(vRemark, iter->second)) //重复
{
vRemark.push_back(iter->second);
}
}
return vRemark;
}
/**************************************************************************
* 函数名称: GetLogLevel()
* 功能描述: 从配置文件中获得允许记录的日志级别
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 允许记录的日志级别
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
vector<TLogLevel> CLogManager::GetLogLevel(const string& strRemark)
{
string strLvlPre = LOGLVLPRE;
if (strRemark == "")
{
//系统日志级别前缀
strLvlPre = strLvlPre + SYSTEM + DOT;
}
else
{
//备注日志级别前缀
strLvlPre = strLvlPre + strRemark + DOT;
}
map<string, string> LogLevels =
m_UserProperties.GetPrefixProperty(strLvlPre);
vector<TLogLevel> vLogLvl;
TLogLevel Level;
//提取日志等级,忽略非法等级
map<string, string>::const_iterator iter = LogLevels.begin();
for (; iter != LogLevels.end(); iter++)
{
DBG("(%s)新日志等级:%s\n", strRemark.c_str(), iter->second.c_str());
if (CLSUtil::IsAllowedLogLevel(iter->second, Level))
{
vLogLvl.push_back(Level);
}
}
//设置默认值
if (vLogLvl.size() == 0)
{
vLogLvl.push_back(LOGERROR);
vLogLvl.push_back(LOGFATAL);
}
return vLogLvl;
}
/**************************************************************************
* 函数名称: GetHistoryAmnt()
* 功能描述: 从配置文件中获得允许记录的历史日志文件个数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 允许的历史日志文件的个数
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
int CLogManager::GetHistoryAmnt(void)
{
int iAmount = m_UserProperties.GetIntProperty(HISTORYAMNT, DEFHISTORYAMNT);
DBG("配置文件中读取的历史日志文件的个数为: %d\n", iAmount);
if (iAmount <= 0)
{
iAmount = DEFHISTORYAMNT;
} DBG("系统中将使用的历史日志文件的个数为: %d\n", iAmount);
return iAmount;
}
/**************************************************************************
* 函数名称: StopAndWait()
* 功能描述: 关闭所有日志线程
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
void CLogManager::StopAndWait(void)
{
//为每个日志线程派发时间为0的日志记录,停止标记。
DBG("为每个日志线程派发时间为0的日志记录,停止标记\n");
LogItem item;
item.Time.wYear = 0;
AddItem(item);
//等待所有日志线程停止
vector<LogThreadPtr>::const_iterator iter = m_vLogThread.begin();
for (; iter != m_vLogThread.end(); iter++)
{
DBG("等待日志线程停止:%d\n", (*iter)->GetThreadID());
//(*iter)->getThreadControl().join();
}
// 停止所有线程
m_threads.join_all();
DBG("所有日志线程停止\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -