一个跨平台的c++日志模块实现

     文件log.h
#ifndef __GUARD_LOG_H
#define __GUARD_LOG_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
    #include <windows.h>
#else
    #include <stdarg.h>
    #include <unistd.h>
    #include <sys/time.h>
    #include <pthread.h>
    #define  CRITICAL_SECTION   pthread_mutex_t
#endif//WIN32
#ifndef MAX_PATH
#define MAX_PATH 256
#endif
const int LOG_HIT = 0;//提示
const int LOG_WARN = 1;//警告
const int LOG_ERROR = 2;//错误
const int LOG_CRITICAL = 3;//严重错误

class AutoLock
{
    public:
        AutoLock()
        {
#ifdef WIN32
            ::InitializeCriticalSection(&section);
#endif

        }
        virtual ~AutoLock()
        {
#ifdef WIN32
            ::DeleteCriticalSection(&secion);
#endif
        }
    public:
       bool Lock()
       {
#ifdef WIN32
           ::EnterCriticalSection(&section);
#else
           pthread_mutex_lock(§ion);
#endif
           return true;
       }
       bool Unlock()
       {
#ifdef WIN32
           ::LeaveCriticalSection(&section);
#else
           pthread_mutex_unlock(&section);
#endif
           return true;
       }
    private:
    CRITICAL_SECTION section;
};



class LogFile
{
public:
    LogFile();
    virtual ~LogFile();
public:
    void Start(const char* pszFilename);
    void Write(int nErrorLevel, const char* pFormatStr, ...);
    void WriteLine(int nErrorLevel, const char* pFormatStr, ...);
    void Close();
    bool CreateDir(const char * pszLogDir);
protected:
    void CreateFile(char* pszFileName);
protected:
    char file_name_[MAX_PATH*2];
    char file_title_[MAX_PATH*2];
    FILE *pLog_;
    AutoLock lock_;
};
#endif//__GUARD_LOG_H

文件log.cc:


#include "log.h"
#include <time.h>

LogFile::LogFile()
{
    pLog_ = NULL;
    memset(file_name_, 0, MAX_PATH * 2);
    memset(file_title_, 0, MAX_PATH * 2);
}
LogFile::~LogFile()
{
    if(pLog_){
        fclose(pLog_);
        pLog_ = NULL;
    }
}
void LogFile::Start(const char* pszFilename)
{
    if (strlen(pszFilename) <= 0){
        return;
    }
    lock_.Lock();
    strcpy(file_title_, pszFilename);
    this->CreateFile(file_title_);
    lock_.Unlock();
}
void LogFile::Write(int nErrorLevel, const char* pFormatStr, ...)
{
    this->CreateFile(file_title_);
    lock_.Lock();
    if (pLog_ == NULL){
        return;
    }
    const int nBufSize = 50 * 1024;
    char Buf[nBufSize];
    const int nLevelSize = 32;
    char Level[nLevelSize];

    if (nErrorLevel == LOG_HIT){
        strcpy(Level, "HIT");
    }
    else if (nErrorLevel == LOG_WARN){
        strcpy(Level, "WARN");
    }
    else if (nErrorLevel == LOG_ERROR){
        strcpy(Level, "ERROR");
    }
    else if (nErrorLevel == LOG_CRITICAL){
        strcpy(Level, "CRITICAL");
    }
    else{
        strcpy(Level, "UNKNOW");
    }

    //输出时间
    time_t timer;
    time(&timer);
    struct tm *today = localtime(&timer);
    //[2005-03-25 11:29:16]
    sprintf(Buf,"[%04d-%02d-%02d %02d:%02d:%02d LEVEL = %s] ",
            today->tm_year + 1900,
            today->tm_mon + 1,
            today->tm_mday,
            today->tm_hour,
            today->tm_min,
            today->tm_sec,
            Level);

    //写到LOG文件.
    fwrite(Buf,strlen(Buf), 1, pLog_);
    memset(Buf, 0, nBufSize);

    //分析输入可变参数.
    va_list args;
    va_start(args, pFormatStr);
    vsprintf(Buf, pFormatStr, args);
    va_end(args);

    //写到LOG文件
    fwrite(Buf, strlen(Buf), 1, pLog_);
    //缓冲区写到文件
    fflush(pLog_);
    lock_.Unlock();
}
void LogFile::WriteLine(int nErrorLevel, const char* pFormatStr, ...)
{
    lock_.Lock();
    this->CreateFile(file_title_);
    if (pLog_ == NULL){
        return;
    }

    const int nBufSize = 50 * 1024;
    char Buf[nBufSize];

    const int nLevelSize = 32;
    char Level[nLevelSize];
    if (nErrorLevel == LOG_HIT){
        strcpy(Level, "HIT");
    }
    else if (nErrorLevel == LOG_WARN){
        strcpy(Level, "WARN");
    }
    else if (nErrorLevel == LOG_ERROR){
        strcpy(Level, "ERROR");
    }
    else if (nErrorLevel == LOG_CRITICAL){
        strcpy(Level, "CRITICAL");
    }
    else{
        strcpy(Level, "UNKNOW");
    }

    //输出时间
    time_t timer;
    time(&timer);
    struct tm *today = localtime(&timer);
    //[2005-03-25 11:29:16]
    sprintf(Buf,"[%04d-%02d-%02d %02d:%02d:%02d LEVEL = %s] ",
            today->tm_year + 1900,
            today->tm_mon + 1,
            today->tm_mday,
            today->tm_hour,
            today->tm_min,
            today->tm_sec,
            Level);

    //写到LOG文件.
    fprintf(pLog_, "%s", Buf);
    memset(Buf, 0, nBufSize);
    //分析输入可变参数.
    va_list args;
    va_start(args, pFormatStr);
    vsprintf(Buf, pFormatStr, args);
    va_end(args);

    //写到LOG文件.
    fwrite(Buf, strlen(Buf), 1, pLog_);

    //缓冲区写到文件.
    fflush(pLog_);
    lock_.Unlock();
}
void LogFile::Close(void)
{
    lock_.Lock();
    if (pLog_){
        fclose(pLog_);
        pLog_ = NULL;
    }
    lock_.Unlock();
}
void LogFile::CreateFile(char* pszFileName)
{
    lock_.Lock();
    //输出时间.
    time_t timer;
    time(&timer);
    struct tm *today = localtime(&timer);
    char chBuf[MAX_PATH] = {0};
    sprintf(chBuf, "%s%04d%02d%02d%s",
            pszFileName,
            today->tm_year + 1900,
            today->tm_mon + 1,
            today->tm_mday,
            ".log");

    if (memcmp(file_name_, chBuf, strlen(chBuf)) != 0){
        if (pLog_){
            this->Close();
            pLog_ = NULL;
        }

        memcpy(file_name_, chBuf, strlen(chBuf));
        pLog_ = fopen(file_name_, "a");
    }
    lock_.Unlock();
}






  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
QT版本 //xxxx.h //log level #define LL_DEBUG 0 #define LL_INFO 1 #define LL_WARN 2 #define LL_ERROR 3 #define LL_ALARM 4 #define GetCurFileName (__FILE__) #define GetCurCodeLine (__LINE__) #define GetCurCodeFunctionName (__FUNCTION__) #define Write_Log(LEVEL, FMTLOG) WriteLog(LEVEL, FMTLOG, GetCurFileName, GetCurCodeLine, GetCurCodeFunctionName) void WriteLog(int, QString, QString, int, QString); //xxxx.cpp void WriteLog(int loglevel, QString strlogstr, QString strfilename, int iline, QString strfunname) { QString g_logdllpath(g_runPath + "/dependences/LoggingModeDLL.dll"); HINSTANCE hDll = LoadLibrary(g_logdllpath.toStdWString().data()); typedef int (__cdecl *MYFUNC)(int, char*, char*, int, char*); MYFUNC execfunc = (MYFUNC)GetProcAddress(hDll, "WriteLog"); execfunc(loglevel, const_cast<char*>(strlogstr.toLatin1().data()), const_cast<char*>(strfilename.toLatin1().data()), iline, const_cast<char*>(strfunname.toLatin1().data())); } MFC 版本 //xxxx.h //log level #define LL_DEBUG 0 #define LL_INFO 1 #define LL_WARN 2 #define LL_ERROR 3 #define LL_ALARM 4 #define GetCurFileName (__FILE__) #define GetCurCodeLine (__LINE__) #define GetCurCodeFunctionName (__FUNCTION__) #define Write_Log(LEVEL, FMTLOG) WriteLog(LEVEL, FMTLOG, GetCurFileName, GetCurCodeLine, GetCurCodeFunctionName) void WriteLog(int, CString, CString, int, CString); void WriteLog(int loglevel, CString strlogstr, CString strfilename, int iline, CString strfunname) { CString g_logdllpath(".\\LoggingModeDLL.dll"); HINSTANCE hDll = LoadLibrary(g_logdllpath.GetBuffer()); typedef int (__cdecl *MYFUNC)(int, char*, char*, int, char*); MYFUNC execfunc = (MYFUNC)GetProcAddress(hDll, "WriteLog"); execfunc(loglevel, const_cast<char*>(strlogstr.GetBuffer()), const_cast<char*>(strfilename.GetBuffer()), iline, const_cast<char*>(strfunname.GetBuffer())); }
/****************************************************************************** Module: VC-Logger Purpose: 记录程序日志。 1. 把日志信息输出到指定文件 2. 对于 GUI 程序,可以把日志信息发送到指定窗口 3. 对于Console应用程序,可以把日志信息发往标准输出 (std::cout) Desc: 1、功能: -------------------------------------------------------------------------------------- a) 把日志信息输出到指定文件 b) 每日生成一个日志文件 c) 对于 GUI 程序,可以把日志信息发送到指定窗口 d) 对于Console应用程序,可以把日志信息发往标准输出 (std::cout) e) 支持 MBCS / UNICODE,Console / GUI,win32 / x64 程序 f) 支持动态加载和静态加载日志组件 DLL g) 支持 DEBUG/TRACE/INFO/WARN/ERROR/FATAL 等多个日志级别 2、可用性: -------------------------------------------------------------------------------------- a) 简单纯净:不依赖任何程序库或框架 b) 使用接口简单,不需复杂的配置或设置工作 c) 提供 CStaticLogger 和 CDynamicLogger 包装用于静态或动态加载以及操作日志组件,用户无需关注加载细节 d) 程序如果要记录多个日志文件只需为每个日志文件创建相应的 CStaticLogger 或 CDynamicLogger 对象 e) 只需调用 Log()/Debug()/Trace()/Info()/Warn()/Error()/Fatal() 等方法记录日志 f) 日志记录方法支持可变参数 g) 日志输出格式: 3、性能: -------------------------------------------------------------------------------------- a) 支持多线程同时发送写日志请求 b) 使用单独线程在后台写日志,不影响工作线程的正常执行 c) 采用批处理方式批量记录日志 Usage: 方法一:(静态加载 Logger DLL) -------------------------------------------------------------------------------------- 0. 应用程序包含 StaticLogger.h 头文件 1. 创建 CStaticLogger 对象(通常为全局对象) 2. 调用 CStaticLogger->Init(...) 初始化日志组件 3. 使用 CStaticLogger->Log()/Debug()/Trace()/Info()/Warn()/Error()/Fatal() 等方法写日志 4. 调用 CStaticLogger->UnInit(...) 清理日志组件(CStaticLogger 对象析构时也会自动清理日志组件) 方法二:(动态加载 Logger DLL) -------------------------------------------------------------------------------------- 0. 应用程序包含 DynamicLogger.h 头文件 1. 创建 CDynamicLogger 对象(通常为全局对象) 2. 调用 CDynamicLogger->Init(...) 初始化日志组件 3. 使用 CDynamicLogger->Log()/Debug()/Trace()/Info()/Warn()/Error()/Fatal() 等方法写日志 4. 调用 CDynamicLogger->UnInit(...) 清理日志组件(CDynamicLogger 对象析构时也会自动清理日志组件) 方法三:(直接用导出函数加载 Logger DLL) -------------------------------------------------------------------------
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值