📄 logthread.cpp
字号:
/*********************************************************************
* 版权所有 (C)2007, 深圳市中兴通讯股份有限公司。
*
* 文件名称: LogThread.cpp
* 文件标识:
* 内容摘要: 日志线程类的实现
* 其它说明:
* 当前版本: V1.00
* 作 者:
* 完成日期: 2007/03/15
*
* 修改记录1:
* 修改日期:2005
* 版 本 号:V1.00
* 修 改 人:陈建友
* 修改内容:原始版本
* 修改记录2:
* 修改日期:2007/02/26
* 版 本 号:V1.00
* 修 改 人:王耀峰
* 修改内容:将ICE库替换为Boost库
* 修改记录3:
* 修改日期:2007/03/15
* 版 本 号:V1.00
* 修 改 人:张 帆
* 修改内容:优化代码,如下所述:
* (1)采用Boost.Threads库,“日志线程”创建即初始化,然后执行 operator ()
* (2)移除原来的Initialize()函数,相应的初始化工作全部移至构造函数
* (3)重载 operator () ,这是“日志线程”的执行逻辑
**********************************************************************/
#include "LogThread.h"
#ifdef WIN32
#include <Windows.h>
#endif
#include <sstream>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include "LSUtil.h"
#include "DebugString.h"
using namespace std;
using namespace NOP;
/**************************************************************************
* 类CLogThread的静态数据成员 *
**************************************************************************/
const string CLogThread::m_sstrLogFileNamePre = "NOP"; // 日志文件前缀
const string CLogThread::m_sstrLogFileNameSuf = ".log"; // 日志文件后缀
/**************************************************************************
* 类CLogThread实现 *
**************************************************************************/
/**************************************************************************
* 函数名称: CLogThread()
* 功能描述: 构造函数, 初始化类成员
* 输入参数: const RemarkItem& Item : 日志的备注项
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
CLogThread::CLogThread(const NOP::RemarkItem& Item,
const std::string& strLogPath,
int iMaxLine,
int iHistoryAmnt)
:m_RemarkItem(Item),
m_sstrLogPath(strLogPath),
m_siMaxLineNum(iMaxLine),
m_siHistoryAmnt(iHistoryAmnt),
m_strLogFile(m_sstrLogPath+m_sstrLogFileNamePre+Item.Remark+m_sstrLogFileNameSuf),
m_iCurHistoryLogFile(0),
m_iTotalLines(INVALID_LINENUM),
m_tid(-1)
{
}
/**************************************************************************
* 函数名称: ~CLogThread()
* 功能描述: 析构函数,关闭日志文件
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
CLogThread::~CLogThread(void)
{
if (m_LogFile.is_open())
{
m_LogFile.close();
}
}
/**************************************************************************
* 函数名称: run()
* 功能描述: 日志线程主函数, 取出日志记录并写入日志文件
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
void CLogThread::operator ()()
{
//m_tid = this->getThreadControl().id();
// !!!需要查找boost库中是否有对应的函数
#ifdef WIN32
m_tid = ::GetCurrentThreadId();
#elif
m_tid = -1;
#endif
DBG("(%d)日志文件名:%s\n", m_tid, m_strLogFile.c_str());
//若文件不存在,创建
CLSUtil::MakeSureFileExists(m_strLogFile);
//读取文件行数
m_iTotalLines = CLSUtil::GetFileLineNumber(m_strLogFile);
DBG("(%d)日志文件初始行数:%d\n", m_tid, m_iTotalLines);
assert(m_iTotalLines >= 0);
while (true)
{
//调整日志文件,并设置当前日志文件
if (ReArrangeLogFiles())
{
//从日志队列中取出一个日志记录
//若无新日志记录,则挂起
DBG("(%d)从日志队列中取出一个日志记录\n", m_tid);
LogItem item = m_synQueue.Get();
//是否日志线程的停止日志记录
if (IsStopItem(item))
{
DBG("(%d)停止日志线程\n", m_tid);
break; //停止日志线程
}
//格式化日志记录
string strFormated = FormatItem(item);
//写入日志文件
if(m_LogFile.is_open())
{
m_LogFile<<strFormated<<endl;
m_iTotalLines++;
DBG("(%d)写入日志文件, 当前行数 = %d\n", m_tid, m_iTotalLines);
}
else
{
DBG("(%d)写入日志文件, 失败\n", m_tid);
}
}
else //调整日志文件失败
{
//线程挂起等待重试
//getThreadControl().sleep(IceUtil::Time::seconds(1));
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
xt.sec += 1;
boost::thread::sleep(xt); // Sleep for 1 second
}
}
// 进入等待停止的状态
/* while (true)
{
DBG("等待线程终止!");
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
xt.sec += 1;
boost::thread::sleep(xt); // Sleep for 1 second
}
*/
DBG("线程终止!");
}
/**************************************************************************
* 函数名称: AddItem()
* 功能描述: 向日志队列中添加日志记录
* 输入参数: const LogItem& Item : 日志记录项
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
void CLogThread::AddItem(const LogItem& Item)
{
if (IsStopItem(Item) //线程停止标记
|| (IsMatchedLevelItem(Item) //日志级别匹配
&& IsMatchedRemarkItem(Item))) // 日志备注匹配
{
DBG("(%d)日志记录入队\n", m_tid);
m_synQueue.Put(Item); //日志记录入队
}
}
/**************************************************************************
* 函数名称: GetThreadID()
* 功能描述: 取日志线程ID
* 输入参数: 无
* 输出参数: m_tid : 日志线程ID
* 返 回 值: 无
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
const int CLogThread::GetThreadID(void)
{
//assert(m_tid > 0);
return m_tid;
}
/**************************************************************************
* 函数名称: IsStopItem()
* 功能描述: 检查日志线程的停止日志记录
* 输入参数: const LogItem& Item : 日志记录项
* 输出参数: 无
* 返 回 值: true : 该日志项是停止日志记录
* false : 该日志项不是停止日志记录
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
bool CLogThread::IsStopItem(const LogItem& Item)
{
DBG("(%d)检查日志线程的停止日志记录: %s\n", m_tid,
Item.Time.wYear == 0?"Yes":"No");
return (Item.Time.wYear == 0);
}
/**************************************************************************
* 函数名称: IsMatchedLevelItem()
* 功能描述: 检查日志记录的日志级别是否匹配
* 输入参数: const LogItem& Item : 日志记录项
* 输出参数: 无
* 返 回 值: true : 该日志级别匹配, 可以被记录
* false : 该日志级别不匹配, 不可以被记录
* 其它说明: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2006/07/03 V1.0 张 帆 创建
**************************************************************************/
bool CLogThread::IsMatchedLevelItem(const LogItem& Item)
{
bool bRet = false;
vector<TLogLevel>::const_iterator iter = m_RemarkItem.Levels.begin();
for (; iter != m_RemarkItem.Levels.end(); iter++)
{
if (*iter == LOGALL
|| *iter == Item.LogLevel)
{
bRet = true;
break;
}
}
DBG("(%d)检查日志记录的日志级别是否匹配(", m_tid);
vector<TLogLevel>::const_iterator iterlvl = m_RemarkItem.Levels.begin();
for (; iterlvl != m_RemarkItem.Levels.end(); iterlvl++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -