windows下如何实现高效的C的log日志记录

我想要达到的结果

windows下如何实现高效的C的log日志记录

开个线程,用fprintf写文件就是了
下面是我很久之前封装的一个日记工具接口,生成dll后直接调用dll接口就可以了
MyLog.h

#ifndef _TZHYJSGLB_LOG_H_
#define _TZHYJSGLB_LOG_H_

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string>
#include <queue>
#include <string.h>
#include <Windows.h>
#include <process.h>
#include <time.h>
#ifdef LCLOG_API

#else
#define LCLOG_API _declspec(dllimport)

#endif

/**@类名:日志管理类
 * @职责:生成并管理日志
 * @功能:
 */
//日志文件模式:每天一个日志文件,每月一个日志文件,只有一个日志文件
enum EMyLogModle
{
    EL_EVERY_DAY,
    EL_EVERY_MON,
    EL_ONLYONE
};

class LCLOG_API CMyLog
{
protected:
    CMyLog();
    ~CMyLog();
public:
    /**@brief:初始化日志管理类
     * @param[in] strLogPath:日志存放路径,不含日志名称
     * @return:
     * @remark:
     */
    static void Init(std::string strLogPath);

    /**@brief:设置日志文件模式
     * @param[in] eMod:日志模式
     * @param[in] strFileName:日志文件名称,日志模式为EL_ONLYONE时,填写该参数
     * @return:
     * @remark:
     */
    static void SetLogFileModle(EMyLogModle eMod,std::string strFileName ="");

    /**@brief:写入日志
     * @param[in]:日志内容
     * @return:
     * @remark:
     */
    static std::string NewLog(std::string strLog);
    static std::string NewLog(const char* pszFormat,...);

    /**@brief:释放资源
     * @param[]
     * @return:
     * @remark:
     */
    static void Release();
private:
    static std::string LogOutQueue();                    //日志出队
    static void* CreateLogFile(void*);                   //创建日志文件
    static void GetLogFile();                            //获取日志文件指针
    static bool IsNeedNewFile(std::string strFile);      //判断是否需要新的日志文件
    static std::string GetTime();                        //获取当时时间
private:
    static std::string m_strLogPath;                     //日志文件路径
    static std::string m_strSingleLogName;               //单日志文件名称
    static std::string m_strCurrentLog;                  //当前日志文件名称
    static EMyLogModle m_eModle;                         //日志文件类型
    static std::queue<std::string>* m_pqLogManager;      //日志管理队列
    static HANDLE m_mutexQueue;                          //日志队列锁
    static FILE* m_Filelog;                              //日志文件
    //static char m_cTmp[1024];                            //缓冲区
    static HANDLE m_hWnd;                                //日志线程ID
};
#endif

MyLog.cpp

//日志管理类实现
#ifdef WIN32
#define LCLOG_API _declspec(dllexport)
#endif


#include "MyLog.h"


//////////////////////////////////////////////////////////////////////////////////////
//                                 静态变量                                         //
//////////////////////////////////////////////////////////////////////////////////////
std::string CMyLog::m_strLogPath;                     //日志文件路径
std::string CMyLog::m_strSingleLogName;               //单日志文件名称
std::string CMyLog::m_strCurrentLog;                  //当前日志文件名称
EMyLogModle CMyLog::m_eModle;                         //日志文件类型
std::queue<std::string>* CMyLog::m_pqLogManager;      //日志管理队列
HANDLE CMyLog::m_mutexQueue;                          //日志队列锁
FILE* CMyLog::m_Filelog;                              //日志文件
//char CMyLog::m_cTmp[1024];                            //缓冲区
HANDLE CMyLog::m_hWnd;                                //日志线程ID

CMyLog::CMyLog(){}
CMyLog::~CMyLog(){}

//////////////////////////////////////////////////////////////////////////////////////
//                                 对外接口                                         //
//////////////////////////////////////////////////////////////////////////////////////
//初始化日志管理类相关成员
void CMyLog::Init(std::string strLogPath)
{
    //默认为每天一个日志文件
    m_eModle = EL_EVERY_DAY;
    //清空日志队列
    m_pqLogManager = NULL;
    m_pqLogManager = new std::queue<std::string>;
    //初始化互斥锁
    m_mutexQueue = ::CreateMutex(NULL, FALSE, NULL);
    //初始化日志文件
    m_Filelog = NULL;
    m_strLogPath = strLogPath;
    m_strSingleLogName = "";
    m_strCurrentLog = " ";
    //memset(m_cTmp,0,1024);
    //启动日记线程
    m_hWnd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CreateLogFile, NULL, 0, 0);
}
//设置日志文件模式
void CMyLog::SetLogFileModle( EMyLogModle eMod ,std::string strFileName)
{
    m_eModle = eMod;
    if (eMod == EL_ONLYONE)
    {
        m_strSingleLogName = strFileName;
    }
}
//写入日志
std::string CMyLog::NewLog( std::string strLog )
{
    std::string strTime = GetTime();
    strTime += strLog;
    WaitForSingleObject(m_mutexQueue, INFINITE);
    m_pqLogManager->push(strTime);//strLog
    ::ReleaseMutex(m_mutexQueue);
    return strLog;
}
//写入日志
std::string CMyLog::NewLog( const char* pszFormat,... )
{
    //WINDOWS
    //va_list args;
    //int     len = 0;

    //// retrieve the variable arguments
    //va_start( args, pszFormat );

    //len = _vscprintf( pszFormat, args ) +1;// _vscprintf doesn't count terminating '\0'

    //char* buffer = new char[len * sizeof(char)];
    //memset(buffer,0,len * sizeof(char));
    //vsprintf( buffer, pszFormat, args ); // C4996
    //// Note: vsprintf is deprecated; consider using vsprintf_s instead
    //
    //std::string strTmp = (std::string)buffer;
    //NewLog(strTmp);
    //delete []buffer;
    //buffer = NULL;
    //LINUX
    va_list args;
    va_start( args, pszFormat );
    char cTmp[1024] ={0};
    //memset(m_cTmp,0,1024);
    int nRes = vsprintf(cTmp, pszFormat, args );
    va_end(args);
    //printf("%s\n",m_cTmp);
    std::string strTmp =(std::string)cTmp;
    NewLog(strTmp);
    return strTmp;
}
void CMyLog::Release()
{
    TerminateThread(m_hWnd, 0);//结束日志线程
    //清空队列
    if (m_pqLogManager != NULL)
    {
        WaitForSingleObject(m_mutexQueue,INFINITE);
        while(m_pqLogManager->size() > 0)
        {
            m_pqLogManager->pop();
        }
        ::ReleaseMutex(m_mutexQueue);
        delete m_pqLogManager;
        m_pqLogManager = NULL;
    }
    ::CloseHandle(m_mutexQueue);
}



//////////////////////////////////////////////////////////////////////////////////////
//                                 内部成员函数                                     //
//////////////////////////////////////////////////////////////////////////////////////
//日志出队
std::string CMyLog::LogOutQueue()
{
    std::string strLog = "";
    WaitForSingleObject(m_mutexQueue, INFINITE);
    strLog = m_pqLogManager->front();
    m_pqLogManager->pop();
    ::ReleaseMutex(m_mutexQueue);
    return strLog;
}
//创建日志文件:后台线程
void* CMyLog::CreateLogFile(void*)
{
    while(1)
    {
        if (m_pqLogManager == NULL)
        {
            return NULL;
        }
        if (m_pqLogManager->size() == 0)
        {
            Sleep(500);
        }else
        {
            //获取日志信息
            std::string strLog = LogOutQueue();
            //获取日志文件信息
            GetLogFile();
            //日志写入日志文件
            if (m_Filelog != NULL)
            {
                fwrite(strLog.c_str(),strLog.length(),1,m_Filelog);
                fflush(m_Filelog);
                /*fclose(m_Filelog);
                m_Filelog = NULL;*/
            }
        }
    }
}

//获取日志文件指针
void CMyLog::GetLogFile()
{
    if (m_eModle == EL_ONLYONE)//单一日志模式
    {
        if (m_Filelog == NULL)
        {
            std::string strFileNameOnly = m_strLogPath + m_strSingleLogName;
            m_Filelog = fopen(strFileNameOnly.c_str(),"a+");
        }else
            return;
    }else//其他模式
    {
        //获取当天日期
        time_t now;
        struct tm* timeinfo;
        time(&now);
        timeinfo = localtime(&now);
        std::string strTmp = "";
        char cTmp[15];
        memset(cTmp,0,15);
        //根据模式判断是否需要更换日志文件
        if (m_eModle == EL_EVERY_MON)
        {
            sprintf(cTmp,"%4d%02d.log",(int)1900+timeinfo->tm_year,(int)1+timeinfo->tm_mon);    
        }else if (m_eModle == EL_EVERY_DAY)
        {
            sprintf(cTmp,"%4d%02d%02d.log",(int)1900+timeinfo->tm_year,(int)1+timeinfo->tm_mon,(int)timeinfo->tm_mday);
        }else
            return;
        
        if (IsNeedNewFile(cTmp))//需要重新生成日志文件
        {
            if (m_Filelog != NULL)//如果原始日志文件未关闭
            {
                fclose(m_Filelog);
                m_Filelog = NULL;
            }
            //重新生成日志文件
            m_strCurrentLog = (std::string)cTmp;
            std::string strFileName = m_strLogPath + m_strCurrentLog;
            m_Filelog = fopen(strFileName.c_str(),"a+");
        }else
            return;
    }
    return;
}
//判断是否需要新的日志文件
bool CMyLog::IsNeedNewFile(std::string strFile)
{
    if (m_Filelog == NULL)//日志指针为空
    {
        return true;
    }else
    {
        if (m_strCurrentLog.compare(" ") == 0)//还没有生成过日志文件
        {
            return true;
        }else//生成过日志文件
        {
            if (m_strCurrentLog.compare(strFile.c_str()) == 0)//跟当前日期相同,不需要重新生成
            {
                return false;
            }else//跟当前日期不同,需要重新生成
                return true;
        }
    }
    
}

//获取时间
std::string CMyLog::GetTime()
{
    time_t tmNow = time(NULL);
    struct tm *local;
    local = localtime(&tmNow);
    char cTmp[22] = {0};
    sprintf(cTmp,"%d-%d-%d %d:%d:%d ",local->tm_year+1900,local->tm_mon+1,local->tm_mday,local->tm_hour,local->tm_min,local->tm_sec);
    return (std::string)cTmp;
}