c++日志系统

Logger.h

#pragma once
#include <fstream>
#include <iostream>
#include <string>
namespace yazi{
    namespace utility{

#define debug(format,...)\
        Logger::getInstance()->log(Logger::DEBUG,__FILE__,__LINE__,format,##__VA_ARGS__);
#define info(format,...)\
        Logger::getInstance()->log(Logger::INFO,__FILE__,__LINE__,format,##__VA_ARGS__);
#define warn(format,...)\
        Logger::getInstance()->log(Logger::WARN,__FILE__,__LINE__,format,##__VA_ARGS__);
#define error(format,...)\
        Logger::getInstance()->log(Logger::ERROR,__FILE__,__LINE__,format,##__VA_ARGS__);
#define fatal(format,...)\
        Logger::getInstance()->log(Logger::FATAL,__FILE__,__LINE__,format,##__VA_ARGS__);

        class Logger
        {
        public:
              enum Level
              {
                DEBUG = 0,
                INFO,
                WARN,
                ERROR,
                FATAL,
                LEVET_COUNT
              };
              void log(Level level,const char* file,int line,const char* format,...);
              static Logger* getInstance();
              void open(const std::string& filename);
              void close();
              void level(Level level);
              void max(int bytes);
        private:
        Logger();
        ~Logger();
        void rotate();
        private:
            std::string _fileName;
            std::ofstream _out;
            Level m_level;
            int _max;
            int _len;
            static const char* _level[LEVET_COUNT];
            static Logger* _instance;
        };
    }
}

Logger.cc

#include "Logger.h"
#include <time.h>
#include <string.h>
#include <stdexcept>
#include <stdarg.h>

using namespace yazi::utility;

const char* Logger::_level[LEVET_COUNT] = {"DEBUG","INFO","WARN","ERROR","FATAL"};
Logger* Logger::_instance = nullptr;
Logger::Logger():_max(0),_len(0),m_level(DEBUG)
{

}
void Logger::level(Level level)
{
    m_level = level;
}
Logger* Logger::getInstance()
{
    if(!_instance)
    {
        _instance = new Logger();
    }
    return _instance;
}
void Logger::open(const std::string& filename)
{
    _out.open(filename,std::ios::app);
    if(_out.fail())
    {
        throw std::logic_error("open file failed" + filename); 
    }
    _fileName = filename;
    _out.seekp(0,std::ios::end);
    _len = _out.tellp();
}
void Logger::close()
{
    _out.close();
}
void Logger::max(int bytes)
{
    _max = bytes;
}
void Logger::log(Level level,const char* file,int line,const char* format,...)
{
    if(m_level > level)
    {
        return;
    }
    if(_out.fail())
    {
        throw std::logic_error("open file failed" + _fileName); 
    }
    time_t ticks = time(nullptr);
    struct tm* ptn = localtime(&ticks);
    char timestamp[32];
    memset(timestamp,0,sizeof(timestamp));
    strftime(timestamp,sizeof(timestamp),"[%Y-%m-%d %H:%M:%S]",ptn);
    const char* fmt = "%s %s %s:%d ";
    int size = snprintf(nullptr,0,fmt,timestamp,_level[level],file,line);
    if(size > 0)
    {
        char* buffer = new char[size + 1];
        snprintf(buffer,size + 1,fmt,timestamp,_level[level],file,line);
        buffer[size] = 0;
        _out << buffer;
        _len += size;
        delete buffer;
    }
    _out.flush();

    va_list arg_ptr;
    va_start(arg_ptr,format);
    size = vsnprintf(nullptr,0,format,arg_ptr);
    va_end(arg_ptr);
    if(size > 0)
    {
        char* content = new char[size + 1];
        va_start(arg_ptr,format);
        vsnprintf(content,size + 1,format,arg_ptr);
        va_end(arg_ptr);
        _out << content;
        _len += size;
        delete content;
    }
    _out << "\n";
    _out.flush();
    if(_len >= _max && _max > 0)
    {
        rotate();
    }
    // std::cout << timestamp << std::endl;
}
void Logger::rotate()
{
    close();
    time_t ticks = time(nullptr);
    struct tm* ptn = localtime(&ticks);
    char timestamp[32];
    memset(timestamp,0,sizeof(timestamp));
    strftime(timestamp,sizeof(timestamp),".%Y-%m-%d_%H-%M-%S",ptn);
    std::string filename = _fileName + timestamp;
    if(rename(_fileName.c_str(),filename.c_str()) != 0)
    {
        throw std::logic_error("rename log file failed");
    }
    open(_fileName);
}
Logger::~Logger()
{
    close();
}

main.cc

#include "utility/Logger.h"
using namespace yazi::utility;


int main()
{
    Logger::getInstance()->open("./test.log");
    // Logger::getInstance()->log(Logger::DEBUG,__FILE__,__LINE__,"hello %s world %d","LT",18);
    Logger::getInstance()->max(200);
    debug("hello world");
    debug("name is %s,age is %d","jake",18);
    info("info message");
    warn("warn message");
    error("error message");
    fatal("fatal message");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值