一个支持中文的日志类

在网上看到了这个类,稍微做了修改,支持中文日志,并且重新排版,添加了部分函数,感谢原作者的分享。

#pragma once
#include <afxdlgs.h>        //打开文件
#include <ShlObj.h>         //浏览文件夹
#include <string>            //std::string

class CLOG
{
public:
    CLOG();
    virtual ~CLOG();

public:
    //-日志文件-

    //----如果没有指定,则为exe所在路径下的log.log文件----
    static CString  GetLogFile();
    static short  SetLogFile(LPCTSTR strPath);
    static short  ViewLogFile();

    //-前缀-
    //----如果多个进程往同一个文件输出日志,可以为每个进程设置一个前缀----
    //----前缀出现在日期时间之前----
    static short  SetPrefix(LPCTSTR strPrefix);

    //-日志信息-

    //-获取日志字符串,可以另外-
    static CString  sOutV(LPCTSTR strType, LPCTSTR strFormat = NULL, va_list valist = NULL);
    static CString  sOut0(LPCTSTR strType, LPCTSTR strFormat = NULL,...);
    static CString  sOut ( LPCTSTR strFormat = NULL,...);

    //-将日志信息输出到文件-
    static short  OutV(LPCTSTR strType, LPCTSTR strFormat = NULL, va_list valist = NULL);
    static short  Out0(LPCTSTR strType, LPCTSTR strFormat = NULL,...);
    static short  Out(const char* pInfo);
    static short  Out(LPCTSTR strFormat = NULL, ...);

protected:
    static CString  s_strLogFile;
    static CString  s_strLogPrefix;
    static HANDLE  s_hWriteEvent;
};

然后是cpp文件

#include "Log.h"
// 得到可执行程序所在目录

//  BOOL bIncludeSep -- 是否包含最后的分隔符"\"
CString GetExePath(BOOL bIncludeSep)
{
    // 得到当前的文件名
    CString strFileName;
    GetModuleFileName(AfxGetInstanceHandle(),strFileName.GetBuffer(_MAX_PATH),_MAX_PATH);
    strFileName.ReleaseBuffer();
    // 得到当前目录
    strFileName=strFileName.Left(strFileName.ReverseFind(_T('\\'))+1);
    if(bIncludeSep)
        return strFileName;
    else
        return strFileName.Left(strFileName.GetLength()-1);
}

//-获取最后的文件名 如果给定文件不是全路径,就是相对于exe-
CString GetFileForExePath(LPCTSTR strCurFileName)
{
    CString strPath = strCurFileName;
    if(!strPath.IsEmpty())
    {
        //-相对路径-
        if(strPath.Find(_T(":"))<=0)     
        {    
            strPath.Format(_T("%s%s"), GetExePath(TRUE), strCurFileName);   
        }    
    }    
    return strPath; 
}

#define LOG_EVENT _T("ChyLogWrite") 
CString CLOG::s_strLogFile = _T(""); 
CString CLOG::s_strLogPrefix = _T(""); 
HANDLE CLOG::s_hWriteEvent = NULL; 

CLOG::CLOG() 
{
}   
CLOG::~CLOG() 
{
}   

short CLOG::SetLogFile(LPCTSTR strPath)
{
    if(strPath==NULL || strPath[0]==0)
        s_strLogFile = GetFileForExePath(_T("log.log"));
    else
        s_strLogFile = GetFileForExePath(strPath);
    return 1;
}

CString CLOG::GetLogFile()
{
    return s_strLogFile;
}

short CLOG::ViewLogFile()
{
    CString strLogFile = GetLogFile();
    ShellExecute(NULL, _T("open"), strLogFile, NULL, NULL, SW_SHOW);
    return strLogFile.IsEmpty()?0:1;
}

short CLOG::SetPrefix(LPCTSTR strPrefix)
{
    if(strPrefix && strPrefix[0])
    {
        s_strLogPrefix = strPrefix;
    }
    return 1;
}

CString CLOG::sOutV(LPCTSTR strType, LPCTSTR strFormat, va_list valist)
{
    CString   strPart_Prefix;
    if(!s_strLogPrefix.IsEmpty())
    {
        strPart_Prefix.Format(_T("[%s]"), s_strLogPrefix);
    }
    CString   strPart_Time;
    {
        SYSTEMTIME sysTime  = {0};
        GetLocalTime(&sysTime);
        strPart_Time.Format(_T("[%2d-%2d %2d:%2d:%2d_%3d]"),
            sysTime.wMonth, sysTime.wDay, 
            sysTime.wHour, sysTime.wMinute, sysTime.wSecond,
            sysTime.wMilliseconds); 
    }
    CString   strPart_Type;
    if(strType && strType[0])
    {
        strPart_Type.Format(_T("[%s]"), strType);
    }
    CString   strPart_Info;
    {  
        strPart_Info.FormatV(strFormat, valist);
    }
    CString str = strPart_Prefix + strPart_Time + strPart_Type+ strPart_Info;
    return str;
}

CString CLOG::sOut0(LPCTSTR strType, LPCTSTR strFormat,...)
{
    va_list  valist;
    va_start(valist, strFormat);   
    CString strInfo = sOutV(strType, strFormat, valist);
    va_end(valist);
    return strInfo;
}

CString CLOG::sOut(LPCTSTR strFormat,...)
{
    va_list  valist;
    va_start(valist, strFormat);
    CString strInfo = sOutV(NULL, strFormat, valist);
    va_end(valist);
    return strInfo;
}
short CLOG::OutV(LPCTSTR strType, LPCTSTR strFormat, va_list valist)
{
    //--
    if(s_hWriteEvent==NULL)
    {
        s_hWriteEvent = OpenEvent(0, FALSE,LOG_EVENT);
        if(s_hWriteEvent==NULL)
            s_hWriteEvent = CreateEvent(NULL, FALSE, TRUE, LOG_EVENT);
    }
    WaitForSingleObject(s_hWriteEvent, INFINITE);
    //-打开关闭文件-
    if(s_strLogFile.IsEmpty())
        SetLogFile(NULL);
    CStdioFile file;
    if(file.Open(s_strLogFile, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
    {
        setlocale(LC_CTYPE, "chs");//设定f
        CString  strPart_NewLine = _T("\n");
        CString  strInfo = sOutV(strType, strFormat, valist); 
        CString  str = strInfo + strPart_NewLine;
        file.SeekToEnd();
        file.WriteString(str);
        file.Close();
        setlocale(LC_ALL, "C"); //还原区域设定
    }
    SetEvent(s_hWriteEvent);
    return 1;
}

short CLOG::Out0(LPCTSTR strType, LPCTSTR strFormat,...)
{
    va_list  valist;
    va_start(valist, strFormat);   
    short rtn = OutV(strType, strFormat, valist);
    va_end(valist);
    return rtn;
}

short CLOG::Out(const char* pInfo)
{
    if (s_hWriteEvent == NULL)
    {
        s_hWriteEvent = OpenEvent(0, FALSE, LOG_EVENT);
        if (s_hWriteEvent == NULL)
            s_hWriteEvent = CreateEvent(NULL, FALSE, TRUE, LOG_EVENT);
    }
    WaitForSingleObject(s_hWriteEvent, INFINITE);
    //-打开关闭文件-
    if (s_strLogFile.IsEmpty())
        SetLogFile(NULL);
    CStdioFile file;
    if (file.Open(s_strLogFile, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite))
    {
        setlocale(LC_CTYPE, "chs");//设定f
        CString  strPart_NewLine = _T("\n");
        CString   strPart_Prefix;
        if (!s_strLogPrefix.IsEmpty())
        {
            strPart_Prefix.Format(_T("[%s]"), s_strLogPrefix);
        }
        CString   strPart_Time;
        {
            SYSTEMTIME sysTime = { 0 };
            GetLocalTime(&sysTime);
            strPart_Time.Format(_T("[%2d-%2d %2d:%2d:%2d_%3d]"),
                sysTime.wMonth, sysTime.wDay,
                sysTime.wHour, sysTime.wMinute, sysTime.wSecond,
                sysTime.wMilliseconds);
        }

        CString str = strPart_Prefix + strPart_Time + pInfo + strPart_NewLine;
        file.SeekToEnd();
        file.WriteString(str);
        file.Close();
        setlocale(LC_ALL, "C"); //还原区域设定
    }
    SetEvent(s_hWriteEvent);
    return 1;
}

short CLOG::Out(LPCTSTR strFormat,...)
{
    va_list  valist;
    va_start(valist, strFormat);
    short rtn = OutV(NULL, strFormat, valist);
    va_end(valist);
    return rtn;
}

使用范例:

/-设定日志文件,建议在Exe初始化时设定-
//-设置相对路径则表示exe所在路径下-
//-如果不设定则为exe所在路径下的log.log文件-
CLOG::SetLogFile("bbb.log");
//-获取日志文本串,可以自行处理,例如输出到界面-
 CString str;
 str = CLOG::sOut0("debug", "hello");
 str = CLOG::sOut0("warn5", "hello %d", 25);
 str = CLOG::sOut0("warn3", "hello %s, you have %d apples!", "libai", 10);
 str = CLOG::sOut ("hello %s, you have %d apples!", "libai", 10);
 //-输出到文件-
 CLOG::Out0("debug", "hello");
 CLOG::Out0("warn5", "hello %d", 25);
 CLOG::Out0("warn3", "hello %s, you have %d apples!", "libai", 10);
 CLOG::Out ("hello %s, you have %d apples!", "libai", 10);
 //-查看日志文件-
 CLOG::ViewLogFile();

 

 

原文地址:http://tiannanyi.blog.163.com/blog/static/1873593442013489035280/

posted @ 2018-04-12 11:26  秋月的私语  阅读(302)  评论(0编辑  收藏  举报