一个简单的日志类,将打印信息写到文件

来源:互联网 发布:二叉树 java 编辑:程序博客网 时间:2024/05/17 07:21
</pre><p>因获取当前软件名字和使用互斥锁用了qt的头文件,如不想支持qt,可改成给定文件名,互斥锁可换成windows下或者linux下的互斥锁,或者boost库的锁也行。多线程下写日志会否出现错乱暂未测试,如不能正常工作,可用锁把vsprintf部分和写文件部分锁起来,应该不会再出问题。
 
log.h头文件内容如下:
#ifndef LOG_H#define LOG_H#include <QMutex>typedef enum{    LOG_EMER = 0,    LOG_ERR,    LOG_WAN,    LOG_INFO,    LOG_DEBUG}LogLevel; class Log{public:    Log(const std::string& filepath, const std::string &name ="");    ~Log();    static Log* Instance();    void WrLog(LogLevel level, const char* fmt, ...);    void SetLogLevel(LogLevel level){ m_level = level;}private:    Log(const Log& log);    Log& operator=(const Log& log);private:    FILE *m_file;    LogLevel m_level;    static Log* m_Instace;    static QMutex m_mutex;}; void WriteLog(const char* file, const char* fun, int line, LogLevel level, const char* fmt,...);#define WLog(level,fmt,...) WriteLog(__FILE__,__FUNCTION__,__LINE__,level,fmt,##__VA_ARGS__)#endif // LOG_H log.cpp文件内容如下:
<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span><pre class="cpp" name="code">#include <QCoreApplication>#include <QMutexLocker>#include <string.h>#include <stdarg.h>#include <stdio.h>#include <direct.h>#include <string>#include <time.h>#include "log.h"const char* LevelToStr(LogLevel level){    switch (level) {    case LOG_DEBUG:        return "DEB";        break;    case LOG_INFO:        return "INF";        break;    case LOG_WAN:        return "WAN";        break;    case LOG_ERR:        return "ERR";        break;    case LOG_EMER:        return "EME";        break;    default:        return "DEB";        break;    }}void WriteLog(const char* /*file*/, const char *fun, int /*line*/, LogLevel level,const char* fmt,...){    time_t t = time(NULL);    tm* tt = localtime(&t);    char tdata[32] = {0};    sprintf(tdata,"%d/%d/%d %d:%d:%d",tt->tm_year+1900,tt->tm_mon+1,tt->tm_mday,            tt->tm_hour,tt->tm_min,tt->tm_sec);    const int size = 1024*8;    char buf[size] = {0};    va_list args;    va_start(args,fmt);    vsprintf(buf,fmt,args);   // vsprintf_s(buf,size,fmt,args);    va_end(args);    Log::Instance()->WrLog(level,"[%s][%s][%s]%s\n",tdata,LevelToStr(level),fun,buf);}Log* Log::m_Instace = NULL;QMutex Log::m_mutex;Log::Log(const std::string &filepath, const std::string &name){    m_level = LOG_DEBUG;    m_file = fopen(filepath.c_str(),"a+");    if(m_file == NULL)    {        const char *path = "./log";        if(0 != access(path,F_OK)) // 判断路径是否存在        {           mkdir(path);           std::string::size_type pos = filepath.rfind("/");           std::string fileName;           if(pos != std::string::npos)           {               fileName = filepath.substr(pos);               fileName = std::string(path)+fileName;           }           else           {               fileName = std::string(path) + "/" + name;           }            m_file = fopen(fileName.c_str(),"w+");        }        else        {            m_file = fopen(filepath.c_str(),"w+");        }    }}Log::~Log(){    if(m_file != NULL)    {        fclose(m_file);    }}void Log::WrLog(LogLevel level, const char* fmt, ...){    if(m_file == NULL)    {        printf("m_file == NULL\n");        qDebug("m_file == NULL\n");        return;    }    const int size = 1024*8;    char buf[size] = {0};    va_list va;    va_start(va,fmt);    //vsprintf_s(buf,size,fmt,va);    vsprintf(buf,fmt,va);    va_end(va);    printf("%s\n",buf);    qDebug("%s\n",buf);    // 级别低于当前级别,则不输出到文件    if(level > m_level) return;    fwrite(buf,strlen(buf),1,m_file);    fflush(m_file);}Log* Log::Instance(){    if(m_Instace == NULL)    {        QMutexLocker lock(&m_mutex);        if(m_Instace == NULL)        {            const std::string name = QCoreApplication::applicationName().toStdString();            const std::string appName = std::string("./log/") + name + std::string(".log");            m_Instace = new Log(appName);        }    }    return m_Instace;}


                                             
0 0
原创粉丝点击