1. 程式人生 > >一個基於log4cplus的簡單日誌類

一個基於log4cplus的簡單日誌類

無聊,對log4cplus進行了簡單的封裝,我需要的功能不多,

/*   
 *    /file CloudLog.h
 *    /brief 一個簡單的日誌類CloudLog,簡單封裝log4cplus的功能,執行緒安全
 *    /date 2010-2-25
 *    /author Cloud
 *
 *    支援Windows和Linux,VS2005和Ubuntu 9.10 gcc 4.4.1測試通過
 *    Linux下連線需要新增選項-llog4cplus
 *
 *    使用舉例:
 *    CloudLog:Log("This is test log: %d",100);
 */

#ifndef _CLOUD_LOG_H_
#define _CLOUD_LOG_H_

#include <log4cplus/logger.h>
#include <log4cplus/fileappender.h>
#include <log4cplus/consoleappender.h>
#include <log4cplus/layout.h>
#include <log4cplus/configurator.h>
#include <stdarg.h>
#include <stdlib.h>
#include <memory.h>

using namespace log4cplus;
using namespace log4cplus::helpers;

#ifdef WIN32
#include <windows.h>
#ifndef _DEBUG
#pragma comment(lib,"log4cplusS.lib")
#else
#pragma comment(lib,"log4cplusSD.lib")
#endif
#endif

#ifdef __linux__
#include <pthread.h>
#define __cdecl
#endif

#define DEFAULT_LOG_CONFIGFILE    "cloudlog.cfg"

#define CLOUDLOG(level,msg) LOG4CPLUS_##level(Logger::getRoot(),msg)

class CloudMutex
{
public:
    CloudMutex()
    {
        #ifdef WIN32
            ::InitializeCriticalSection(&m_mutex);
        #else
            pthread_mutex_init(&m_mutex,0);
        #endif
    }

    ~CloudMutex()
    {
        #ifdef WIN32
            ::DeleteCriticalSection(&m_mutex);
        #else
            pthread_mutex_destroy(&m_mutex);
        #endif
    }

    inline void Acquire()
    {
        #ifdef WIN32
            ::EnterCriticalSection(&m_mutex);
        #else
            pthread_mutex_lock(&m_mutex);
        #endif
    }

    inline void Release()
    {
        #ifdef WIN32
            ::LeaveCriticalSection(&m_mutex);
        #else
            pthread_mutex_unlock(&m_mutex);
        #endif
    }

private:

#ifdef WIN32
    CRITICAL_SECTION    m_mutex;
#else
    pthread_mutex_t        m_mutex;
#endif
};

enum{
    CLOUD_TRACE,
    CLOUD_DEBUG,
    CLOUD_INFO,
    CLOUD_WARN,
    CLOUD_ERROR,
    CLOUD_FATAL
};

class CloudLog
{

public:
    CloudLog() {}
    ~CloudLog(){}

    //Initialize log system by specified config file
    static void Initialize(std::string strConfig)
    {
        printf("CloudLog::Initialize(%s)/n",strConfig.c_str());
        m_mutex.Acquire();
        m_strConfig = strConfig;
        //Logger::getRoot().shutdown();
        PropertyConfigurator::doConfigure(m_strConfig);
        m_logger = Logger::getRoot();
        m_bInited = true;
        m_mutex.Release();
    }

    static void __cdecl Log(int level,const char* format,...);

private:
    static Logger m_logger;
    static bool    m_bInited;
    static std::string m_strConfig;
    static CloudMutex    m_mutex;
};

bool CloudLog::m_bInited = false;
std::string CloudLog::m_strConfig = DEFAULT_LOG_CONFIGFILE;
CloudMutex    CloudLog::m_mutex;
Logger CloudLog::m_logger;


//實現
void CloudLog::Log(int level,const char* format,...)
{
    m_mutex.Acquire();

    if(m_bInited == false){
        printf("Initialize log4cplus system /tConfigFile:%s/n",m_strConfig.c_str());
        //Logger::getRoot().shutdown();
        PropertyConfigurator::doConfigure(m_strConfig);
        m_logger = Logger::getRoot();
        m_bInited = true;
    }

    char buf[4096] = {0};
    char *p = buf;
    memset(buf,0,4096);
    va_list args;
    int n;
   
    va_start(args,format);
#ifdef __linux__
    n = vsnprintf(p,sizeof buf - 1,format,args);
#else
    n = _vsnprintf(p,sizeof buf -1,format,args);
#endif
    va_end(args);
   
    std::string strmsg = buf;

    if(level == CLOUD_TRACE)
        LOG4CPLUS_TRACE(m_logger,strmsg);
    else if(level == CLOUD_DEBUG)
        LOG4CPLUS_DEBUG(m_logger,strmsg);
    else if(level == CLOUD_INFO)
        LOG4CPLUS_INFO(m_logger,strmsg);
    else if(level == CLOUD_WARN)
        LOG4CPLUS_WARN(m_logger,strmsg);
    else if(level == CLOUD_ERROR)
        LOG4CPLUS_ERROR(m_logger,strmsg);
    else if(level == CLOUD_FATAL)
        LOG4CPLUS_FATAL(m_logger,strmsg);

    m_mutex.Release();
}

#endif