⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logmanager.cpp

📁 日志模块代码
💻 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 + -