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

📄 superlog.cpp

📁 一个性能高
💻 CPP
字号:
//  *************************************************************
//  Copyright (C) 2000-2009,Seuu Technologies Co., Ltd.
//  
//  File name  : SuperLog.cpp
//  Description: 日志写入器实现
//  Version    : 1.0
//  Author     : Seuu
//  Created    : 2009-05-08 22:32:31
//  *************************************************************

#include "StdAfx.h"
#include "SuperLog.h"

CTime   g_tmCurTime;
CString g_strTime;

CString   CSuperLog::m_strWriteStrInfo;
int       CSuperLog::m_iWriteBinLogLen   = 0;
int       CSuperLog::m_iCurLogFileSeq = 0;

#ifdef _DEBUG
int       CSuperLog::m_iLogLevel  = CSuperLog::ENUM_LOG_LEVEL_DEBUG;
#else
int       CSuperLog::m_iLogLevel  = CSuperLog::ENUM_LOG_LEVEL_RUN;
#endif
TCHAR*   g_pszLogLevel[]          = {_T("0"), _T("1"), _T("2"), _T("3")};
HANDLE   CSuperLog::m_hMapLogFile = NULL;
LPTSTR   CSuperLog::m_psMapAddr   = NULL;  

char      g_szWriteBinInfo[MAX_BIN_LOG_INFO_LEN];
TCHAR*    g_pszLogFileName[MAX_LOG_FILE_COUNT] = {_T("log1.txt"), _T("log2.txt"), _T("log3.txt")};

HANDLE   CSuperLog::m_hThread    = NULL;
unsigned CSuperLog::m_uiThreadID = 0;
bool     CSuperLog::m_bRun       = true;

CSuperLog::enLogStatus CSuperLog::m_enStatus   = CSuperLog::ENUM_LOG_INIT;
CStdioFile*            CSuperLog::m_pFile      = NULL;
int                    CSuperLog::m_iMaxLogFileLen = MAX_LOG_FILE_LEN;
CRITICAL_SECTION       CSuperLog::m_csWriteLog;

CSuperLog g_SuperLog;

unsigned __stdcall CSuperLog::LogProcStart( void* pParam )
{
    int nCount = 1;
    CString strTemp;
    WriteLog(_T("日志线程启动."), ENUM_LOG_LEVEL_DEBUG, true);

    // 线程开始
    do 
    {
        Sleep(300);
        if (++nCount % 10 == 0 )
        {
            WriteLog(strTemp, ENUM_LOG_LEVEL_ERROR, true); // 每隔三秒写一次日志
            CheckLogLevel();
        }

        if (nCount % 40 == 0 || m_enStatus == ENUM_LOG_INVALID)
        {
            // 每12秒检查一次文件
            if (ENUM_LOG_INVALID ==  OpenLogFile())
            {
                Sleep(3000);
                OpenLogFile();
            }
        }

    } while (m_bRun);

    // 程序开始退出
    WriteLog(_T("Super logger has exited."), ENUM_LOG_LEVEL_RUN, true);
    if (m_pFile != NULL)
    {
        m_pFile->Close();
        delete m_pFile;
        m_pFile = NULL;
    }

    m_enStatus = ENUM_LOG_EXITED;
    _endthreadex( 0 );
    return 0;
} 


// *************************************************************
// Copyright (C) 2000-2009 Seuu Technologies Co., Ltd.
// Function name   : CSuperLog::CSuperLog
// Description     : 初始化函数
// Return type     : 
// Argument        : void
// Created by seuu at 2009-05-09 22:05:52
// *************************************************************
CSuperLog::CSuperLog(void)
{
    // 初始化临界区变量
    InitializeCriticalSection(&m_csWriteLog); 
    // 打开一个日志文件
    OpenLogFile();
    // 启动信息
    m_strWriteStrInfo = WELCOME_LOG_INFO;
    WriteLog(_T("Super logger start up."), ENUM_LOG_LEVEL_RUN, true);
    // 从配置文件中读取日志级别
    OperaterConfig(FALSE);
    // 同步到共离内存中
    SetLogLevelShareMem(m_iLogLevel);
    // Create the Logger thread.
    m_hThread = (HANDLE)_beginthreadex( NULL, 0, &LogProcStart, NULL, 0, &m_uiThreadID );

}

CSuperLog::~CSuperLog(void)
{
    m_bRun = false;
    m_enStatus = ENUM_LOG_EXITING;

    for (int i = 0; i < 50; i++)
    {
        Sleep(300);
        if (m_enStatus == ENUM_LOG_EXITED)
        {
            break;
        }
    }
    DeleteCriticalSection(&m_csWriteLog);
    if (m_psMapAddr != NULL)
    {
        UnmapViewOfFile(m_psMapAddr);
    }

}
int CSuperLog::OperaterConfig(BOOL bSave)
{
    TCHAR szPath[MAX_PATH];
    if( !GetModuleFileName( NULL, szPath, MAX_PATH ) )
    {
        WRITE_LOG(_T("GetModuleFileName失败。"), LOG_LEVEL_ERROR);
        return -1;
    }

    CString strDir = szPath;
    int nPos = strDir.ReverseFind(_T('\\'));
    if (nPos == -1)
    {
        WRITE_LOG(_T("GetModuleFileName取得信息异常。"), LOG_LEVEL_ERROR);
        return -1;
    }
    strDir = strDir.Left(nPos + 1);
    strDir += _T("SuperLog.ini");
    if (bSave)
    {
        WritePrivateProfileString(
            _T("SuperLog"), 
            _T("LogLevel"), 
            g_pszLogLevel[m_iLogLevel],
            strDir);

        CString temp;
        temp.Format(_T("%d"), m_iMaxLogFileLen);
        WritePrivateProfileString(
            _T("SuperLog"), 
            _T("MaxLogFileLen"), 
            (LPCTSTR)temp,
            strDir);
    } 
    else
    {
        m_iLogLevel = GetPrivateProfileInt(
            _T("SuperLog"), 
            _T("LogLevel"), 
            ENUM_LOG_LEVEL_RUN,
            strDir);
        if (m_iLogLevel > ENUM_LOG_LEVEL_ERROR || m_iLogLevel < ENUM_LOG_LEVEL_DEBUG)
        {
            WriteLog(_T("日志级别配置非法。"),LOG_LEVEL_ERROR);
            m_iLogLevel = ENUM_LOG_LEVEL_RUN;
        }

        m_iMaxLogFileLen  = GetPrivateProfileInt(
            _T("SuperLog"), 
            _T("MaxLogFileLen"), 
            MAX_LOG_FILE_LEN,
            strDir);
        if (m_iMaxLogFileLen > 1024*1024*1024 || m_iMaxLogFileLen < MAX_BIN_LOG_INFO_LEN) 
        {
            WriteLog(_T("最大文件长度配置非法。"),LOG_LEVEL_ERROR);
            m_iMaxLogFileLen = MAX_LOG_FILE_LEN;
        }
    }
    return 0;
}
int CSuperLog::CheckLogLevel()
{
    int iLevel = GetLogLevelShareMem();
    if (iLevel != m_iLogLevel)
    {
        SetLogLevelShareMem(iLevel);
        m_iLogLevel = iLevel;
        OperaterConfig(TRUE);
    }

    return 0;
}

int CSuperLog::SetLogLevelShareMem(int iLevel)
{
    if (m_hMapLogFile == NULL || m_psMapAddr == NULL)
    {
        GetLogLevelShareMem();
    }

    if (m_hMapLogFile != NULL && m_psMapAddr != NULL)
    {
        _tcscpy_s(m_psMapAddr, 1024, g_pszLogLevel[iLevel]);                  
        FlushViewOfFile(m_psMapAddr, _tcslen(g_pszLogLevel[iLevel]));
        WriteLog(_T("设置日志级别成功。"), ENUM_LOG_LEVEL_RUN);
    }
    return 0;
}

int CSuperLog::GetLogLevelShareMem(void)
{
    //打开共享的文件对象。
    if (m_hMapLogFile == NULL)
    {
        m_hMapLogFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, _T("SuperLogShareMem"));
    }
    if (m_hMapLogFile != NULL)
    {
        //显示共享的文件数据。
        if (m_psMapAddr == NULL)
        {
            m_psMapAddr = (LPTSTR)MapViewOfFile(m_hMapLogFile, FILE_MAP_ALL_ACCESS,0,0,0);
            WriteLog(m_psMapAddr, ENUM_LOG_LEVEL_DEBUG);
        }
    }
    else
    {
        //创建共享文件。
        m_hMapLogFile = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,1024, _T("SuperLogShareMem"));
        if (m_hMapLogFile != NULL)
        {
            //拷贝数据到共享文件里。
            m_psMapAddr = (LPTSTR)MapViewOfFile(m_hMapLogFile,FILE_MAP_ALL_ACCESS, 0,0,0);
            if (m_psMapAddr != NULL)
            {
                _tcscpy_s(m_psMapAddr, 1024, g_pszLogLevel[m_iLogLevel]);                  
                FlushViewOfFile(m_psMapAddr, _tcslen(g_pszLogLevel[m_iLogLevel]));
                WriteLog(_T("设置默认日志级别到共享内存中成功。"), ENUM_LOG_LEVEL_RUN);

           }
        }
        else
        {
            WriteLog(_T("创建共享内存失败。"), ENUM_LOG_LEVEL_ERROR);
        }
    }

    if (m_psMapAddr != NULL)
    {
        if (_tcscmp(m_psMapAddr, g_pszLogLevel[ENUM_LOG_LEVEL_RUN]) == 0)
        {
            return ENUM_LOG_LEVEL_RUN;
        }
        else if (_tcscmp(m_psMapAddr, g_pszLogLevel[ENUM_LOG_LEVEL_DEBUG]) == 0)
        {
            return ENUM_LOG_LEVEL_DEBUG;
        }
        else if (_tcscmp(m_psMapAddr, g_pszLogLevel[ENUM_LOG_LEVEL_ERROR]) == 0)
        {
            return ENUM_LOG_LEVEL_ERROR;
        }
        else
        {
            return ENUM_LOG_LEVEL_RUN;
        }    
    }

    return m_iLogLevel;
}


CSuperLog::enLogStatus CSuperLog::OpenLogFile(void)
{
    EnterCriticalSection(&m_csWriteLog); 
    // 写入过程中出错后需要关闭文件
    if (m_enStatus == ENUM_LOG_INVALID && m_iCurLogFileSeq != 0)
    {
        m_iCurLogFileSeq--;
        if (m_pFile != NULL)
        {
            m_pFile->Close();
            delete m_pFile;
            m_pFile = NULL;
        }
    }

    for (int iRunCount = 0; iRunCount < MAX_LOG_FILE_COUNT; iRunCount++)
    {
        if (m_pFile == NULL)
        {
            m_pFile = new CStdioFile;
            if (m_pFile == NULL)
            {
                LeaveCriticalSection(&m_csWriteLog);
                return m_enStatus = ENUM_LOG_INVALID;
            }

            BOOL bRet = m_pFile->Open(
                g_pszLogFileName[(m_iCurLogFileSeq++)%MAX_LOG_FILE_COUNT],
                CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyNone | CFile::modeNoTruncate);
            if (bRet)
            {
                WriteUnicodeHeadToFile(m_pFile);
            }
            else
            {
                delete m_pFile;
                m_pFile = NULL;
                LeaveCriticalSection(&m_csWriteLog);
                return m_enStatus = ENUM_LOG_INVALID;
            }
        }

        if (m_pFile->GetLength() > MAX_LOG_FILE_LEN)
        {
            m_pFile->Close();
            BOOL bRet = FALSE;
            // 上一个文件是最大的那个文件或是写过一遍了的。
            if (m_iCurLogFileSeq >= MAX_LOG_FILE_COUNT) 
            {
                // 所有文件都是写满了,则强制从第一个文件开始写,同时先清空文件
                bRet = m_pFile->Open(
                    g_pszLogFileName[(m_iCurLogFileSeq++)%MAX_LOG_FILE_COUNT],
                    CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyNone); 
            }
            else
            {
                // 打开第二个文件,再检查是否过了最大值
                bRet = m_pFile->Open(
                    g_pszLogFileName[(m_iCurLogFileSeq++)%MAX_LOG_FILE_COUNT],
                    CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyNone | CFile::modeNoTruncate);
            }

            if (bRet)
            {
                WriteUnicodeHeadToFile(m_pFile);
            }
            else
            {
                delete m_pFile;
                m_pFile = NULL;
                LeaveCriticalSection(&m_csWriteLog);
                return m_enStatus = ENUM_LOG_INVALID;
            }
        }
        else
        {
            break;
        }
    }

    m_pFile->SeekToEnd();
    LeaveCriticalSection(&m_csWriteLog);
    return m_enStatus = ENUM_LOG_RUN;
}


int CSuperLog::WriteLog(CString &strLog,enLogInfoLevel enLevel/* = ENUM_LOG_LEVEL_RUN*/, bool bForce /*= false*/)
{
    if (enLevel < m_iLogLevel)
    {
        return -1;
    }

    EnterCriticalSection(&m_csWriteLog); 
    if (!strLog.IsEmpty())
    {
        m_strWriteStrInfo += GetCurTimeStr();
        // add log level info
        if (enLevel == ENUM_LOG_LEVEL_ERROR)
        {
            m_strWriteStrInfo += _T("Error! ");
        }
        m_strWriteStrInfo += strLog;
        m_strWriteStrInfo += _T("\r\n");
    }

    if ( bForce
        || m_strWriteStrInfo.GetLength() > MAX_STR_LOG_INFO_LEN
        || m_iWriteBinLogLen > MAX_BIN_LOG_INFO_LEN/10)
    {
        // write info
        WriteLogToFile();
    }
    LeaveCriticalSection(&m_csWriteLog);
    return 0;
}

int CSuperLog::WriteLog(TCHAR* pstrLog, enLogInfoLevel enLevel /*= ENUM_LOG_LEVEL_RUN*/, bool bForce /*= false*/)
{
    if (pstrLog == NULL || enLevel < m_iLogLevel)
    {
        return -1;
    }

    EnterCriticalSection(&m_csWriteLog); 
    if (_tcslen(pstrLog) != 0)
    {
        m_strWriteStrInfo += GetCurTimeStr();
        if (enLevel == ENUM_LOG_LEVEL_ERROR)
        {
            m_strWriteStrInfo += _T("Error! ");
        }
        m_strWriteStrInfo += pstrLog;
        m_strWriteStrInfo += _T("\r\n");
    }

    if ( bForce
        || m_strWriteStrInfo.GetLength() > MAX_STR_LOG_INFO_LEN
        || m_iWriteBinLogLen > MAX_BIN_LOG_INFO_LEN/10)
    {
        // write info
        WriteLogToFile();
    }
    LeaveCriticalSection(&m_csWriteLog);
    return 0;
}
int CSuperLog::WriteUnicodeHeadToFile(CFile * pFile)
{
    if (pFile == NULL)
    {
        return -1;
    }
    try
    {
        if (pFile->GetLength() == 0)
        {
            m_pFile->Write("\377\376", 2);
            if (m_enStatus == ENUM_LOG_RUN)
            {
                m_pFile->WriteString(WELCOME_LOG_INFO);
            }
            m_pFile->Flush();
        }
    }
    catch (...)
    {
        return -1;
    }
    return 0;
}

CString& CSuperLog::GetCurTimeStr()
{
    g_tmCurTime = CTime::GetCurrentTime();// time(NULL);
    g_strTime = g_tmCurTime.Format(_T("%Y-%m-%d %H:%M:%S "));
    return g_strTime;
}

int CSuperLog::WriteLog(char* pszLog, int nLen,enLogInfoLevel enLevel /*= ENUM_LOG_LEVEL_RUN*/, bool bForce /*= false*/)
{
    // 待实现
    return -1;

    if (nLen >= MAX_BIN_LOG_INFO_LEN || pszLog == NULL || enLevel < m_iLogLevel)
    {
        return -1;
    }

    EnterCriticalSection(&m_csWriteLog); 
    if (nLen + m_iWriteBinLogLen >= MAX_BIN_LOG_INFO_LEN)
    {
        // write info to file 待实现

        memcpy(g_szWriteBinInfo, pszLog, nLen);
        m_iWriteBinLogLen = nLen;
    }
    else
    {
        memcpy(g_szWriteBinInfo+m_iWriteBinLogLen, pszLog, nLen);
        m_iWriteBinLogLen += nLen;
    }

    if ( bForce
        || m_strWriteStrInfo.GetLength() > MAX_STR_LOG_INFO_LEN
        || m_iWriteBinLogLen > MAX_BIN_LOG_INFO_LEN/10)
    {
        // write info to file
        WriteLogToFile();
    }

    LeaveCriticalSection(&m_csWriteLog);
    return 0;
}


int CSuperLog::WriteLogToFile()
{
    if (m_pFile == NULL 
        || (m_iWriteBinLogLen == 0 && m_strWriteStrInfo.IsEmpty()) 
        || m_enStatus == ENUM_LOG_INIT 
        || m_enStatus == ENUM_LOG_EXITED
        || m_enStatus == ENUM_LOG_INVALID
        )
    {
        return 0;
    }

    try
    {
        m_pFile->WriteString(m_strWriteStrInfo); 
        m_pFile->Flush();
    }
    catch (...)
    {
        m_enStatus = ENUM_LOG_INVALID;
    }

    m_strWriteStrInfo.Empty();
    return 0;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -