基于Log4cpp封装的一个Log库

Log.h

cpp 复制代码
#ifndef _LOG_H_
#define _LOG_H_

#include "log_global.h"


#include <QObject>
#include "singleton.h"
class LogPrivate;

class LOG_EXPORT Log :public Singleton<Log>
{

    DEFINE_CONSTRUCT(Log)

public:
    void initLogPath(const QString& logPath);

    void warn(const char * msg,const char *filename = __FILE__,int line = __LINE__,const char *function = "warn");

    void info(const char * msg,const char *filename = __FILE__,int line = __LINE__,const char *function = "info");

    void debug(const char * msg,const char *filename = __FILE__,int line = __LINE__,const char *function = "debug");

    void error(const char * msg,const char *filename = __FILE__,int line = __LINE__,const char *function = "error");

private:

    LogPrivate* d_ptr;
};


#define LOG_DEBUG(msg)   Log::instance()->debug(msg,__FILE__,__LINE__,__FUNCTION__);
#define LOG_INFO(msg)    Log::instance()->info(msg,__FILE__,__LINE__,__FUNCTION__);
#define LOG_ERROR(msg)   Log::instance()->error(msg,__FILE__,__LINE__,__FUNCTION__);
#define LOG_WARN(msg)    Log::instance()->warn(msg,__FILE__,__LINE__,__FUNCTION__);

#endif // LOG_H

signgleton.h

cpp 复制代码
#ifndef  singleton_INC
#define  singleton_INC

#include <QMutexLocker>
#include <QMutex>
#include <QAtomicPointer>

template <typename T>
class Singleton 
{
public:
    static T *instance()
    {
        if ( s_instance.testAndSetOrdered(0,0) ) {  //若单例还未创建则进入分支,testAndSetOrdered可实现获取单例指针原子操作。
            QMutexLocker locker(s_mutex);
            if (s_instance.testAndSetOrdered(0,0)) {//再次检测,当有一个以上线程同时进入分支时可以确保唯一实例。
                s_instance.store(new T);
            }
        }
        return s_instance.load();
    }

    static void destroy()
    {
        T *tins = s_instance.fetchAndStoreOrdered(0);// Atomic fetch-and-store
        if (tins) {
            delete tins;
        }
    }
    static bool isInstanceExist() 
    {
        return !(s_instance.testAndSetOrdered(0,0));
    }

protected:
	Singleton(){}
	~Singleton(){}

private:
    Singleton(const Singleton &);
    Singleton &operator =(const Singleton &);

private:
    static QMutex *s_mutex;
    static QAtomicPointer<T> s_instance;
};

template <typename T>
QMutex *Singleton<T>::s_mutex=new QMutex;

template <typename T>
QAtomicPointer<T> Singleton<T>::s_instance;



#define  DEFINE_CONSTRUCT(CLASS_NAME) \
protected:\
    explicit CLASS_NAME();\
    ~CLASS_NAME();\
    friend class Singleton<CLASS_NAME>;

#endif   /* ----- #ifndef singleton_INC  ----- */

log.cpp

cpp 复制代码
#include "log.h"

#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp\RollingFileAppender.hh"
#include "log4cpp/Layout.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/PatternLayout.hh"
#include "log4cpp/Priority.hh"
#include <QDebug>
#include <QGuiApplication>
#include <QFileInfo>


class LogPrivate{

public:

    LogPrivate():m_Root(log4cpp::Category::getInstance("rootName")),m_logPath(""){

    }
    ~LogPrivate(){
        log4cpp::Category::shutdown();
    }
    void setLogPath(const std::string& filePath=""){
        if(!m_logPath.empty())
            return;
        m_logPath=filePath;
        init();
    }
    std::string logPath()const{
        return m_logPath;
    }
    void init(){
        if(m_logPath.empty()){
            m_logPath= QGuiApplication::applicationDirPath().toStdString()+"/"+QGuiApplication::applicationName().toStdString()+".log";
        }
        m_pLayout=new  log4cpp::PatternLayout();
        m_pLayout->setConversionPattern("[%d{%Y-%m-%d %H:%M:%S.%l}] [tid:%t] %m%n");

        m_pOsAppender=new log4cpp::OstreamAppender("IOStream",&std::cout);
        m_pOsAppender->setLayout(m_pLayout);

//        m_pLayout_File=new  log4cpp::PatternLayout();
//        m_pLayout_File->setConversionPattern("[%d{%Y-%m-%d %H:%M:%S.%l}] [tid:%t] %m%n");

//        m_pFileAppender= new log4cpp::FileAppender("fileAppender",m_logPath);
//        m_pFileAppender->setLayout(m_pLayout_File);


        m_pLayout_RollFile=new log4cpp::PatternLayout();
        m_pLayout_RollFile->setConversionPattern("[%d{%Y-%m-%d %H:%M:%S.%l}] [tid:%t] %m%n");

        m_pFileRollAppender= new log4cpp::RollingFileAppender("fileAppender",m_logPath,1024*1024*10,1);
        m_pFileRollAppender->setLayout(m_pLayout_RollFile);

        m_Root.addAppender(m_pOsAppender);
//        m_Root.addAppender(m_pFileAppender);
        m_Root.addAppender(m_pFileRollAppender);
        m_Root.setPriority(log4cpp::Priority::DEBUG);
    }

    void warn(const char * msg)
    {
        if(m_logPath.empty()){
            init();
        }
        m_Root.warn(msg);
    }
    void info(const char * msg)
    {

        if(m_logPath.empty()){
            init();
        }
        m_Root.info(msg);
    }
    void debug(const char* msg)
    {
        if(m_logPath.empty()){
            init();
        }
        m_Root.debug(msg);
    }
    void error(const char * msg)
    {
        if(m_logPath.empty()){
            init();
        }
        m_Root.error(msg);
    }



private:
    log4cpp::PatternLayout*         m_pLayout = nullptr;
    log4cpp::PatternLayout*         m_pLayout_File = nullptr;
    log4cpp::PatternLayout*         m_pLayout_RollFile = nullptr;
    log4cpp::OstreamAppender *      m_pOsAppender = nullptr;
    log4cpp::FileAppender*          m_pFileAppender = nullptr;
    log4cpp::RollingFileAppender *  m_pFileRollAppender = nullptr;
    log4cpp::Category& m_Root;
    std::string m_logPath;
};


void Log::error(const char *msg, const char *filename, int line, const char *function)
{
    QFileInfo fileInfo(filename);
    char info[4096] = {0};
    sprintf(info,"[file:%s] [line:%d] [func:%s] [msg-error]:%s",fileInfo.fileName().toStdString().c_str(),line,function,msg);
    d_ptr->error(info);
}

void Log::debug(const char *msg, const char *filename, int line, const char *function)
{

    QFileInfo fileInfo(filename);

    char info[4096] = {0};
    sprintf(info,"[file:%s] [line:%d] [func:%s] [msg-debug]:%s",fileInfo.fileName().toStdString().c_str(),line,function,msg);
    d_ptr->debug(info);
}


void Log::info(const char *msg, const char *filename, int line, const char *function)
{
    QFileInfo fileInfo(filename);
    char info[4096] = {0};
    sprintf(info,"[file:%s] [line:%d] [func:%s] [msg-info ]:%s",fileInfo.fileName().toStdString().c_str(),line,function,msg);
    d_ptr->info(info);
}

void Log::warn(const char *msg, const char *filename, int line, const char *function)
{
    QFileInfo fileInfo(filename);
    char info[4096] = {0};
    sprintf(info,"[file:%s] [line:%d] [func:%s] [msg-warn ]:%s",fileInfo.fileName().toStdString().c_str(),line,function,msg);
    d_ptr->warn(info);
}


Log::~Log()
{
    if(d_ptr!=nullptr){
        delete d_ptr;
        d_ptr=nullptr;
    }
}

//Log &Log::instance()
//{
//    static Log Instance;
//    return Instance;
//}

void Log::initLogPath(const QString &logPath)
{
    if(logPath.isEmpty())
        return;
    d_ptr->setLogPath(logPath.toStdString());
}




Log::Log():d_ptr(new LogPrivate())
{

}

日志格式为

支持回滚

相关推荐
邪修king3 小时前
UE5 进阶篇第一弹:中期架构升级 —— 组件化开发与 Gameplay 框架实战
c++·游戏·架构·ue5
知识领航员12 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
c1s2d3n4cs13 小时前
Qt模仿nlohmann::json进行序列化和反序列化
开发语言·qt·json
jf加菲猫13 小时前
第21章 Qt WebEngine
开发语言·c++·qt·ui
码农-阿杰14 小时前
深入理解 synchronized 底层实现:从 HotSpot C++ 源码看对象锁与 Monitor 机制
开发语言·c++·
Szime14 小时前
深智微IC华润微代理:MCU选型与工业控制方案推荐
c++
叼烟扛炮15 小时前
C++ 知识点18 内部类
开发语言·c++·算法·内部类
汉克老师15 小时前
GESP5级C++考试语法知识(十五、分治算法(二))
c++·算法·排序算法·分治算法·gesp5级·gesp五级
汉克老师15 小时前
GESP6级C++考试语法知识(五、格雷码)
c++·算法·位运算·异或·gesp6级·gesp六级·格雷码
程序leo源17 小时前
C语言知识总结
c语言·开发语言·c++·经验分享·笔记·青少年编程·c#