Poco::Logger 日志库使用示例(下)

引言

通过前面的两个章节中已经了解Poco :: Logger的基本使用方法了,下面将以企业级开发思路重新设计功能。

功能需求分析

  • 软件运行时候自动建立日志文件
  • 文件的名称包含建立的日期,每天存放在独立的文件中
  • 限制生成日志文件的个数,定为30天
  • 提供接口,接口接受不同的事件

关键代码

#include "MyLogger.h"


NutLogger  *NutLogger::m_instance=NULL;


NutLogger *NutLogger::get_instance()
{
    if(NULL==m_instance)
    {
        m_instance = new NutLogger();
    }
    return m_instance;
}

// timer(0, 2000),第一个参数默认设置为0,6000代表时间间隔为6秒
// callback的第二个参数指定定时器需要做的具体事情
NutLogger::NutLogger() : m_timer(0, 6000), callback(*this, &NutLogger::onTimer),end(false)
{
    //EpochTime 1970
    m_dateTime = Poco::Timestamp::fromEpochTime(time(NULL));
    init();

    this->startTimer();
}

NutLogger::~NutLogger()
{
    delete m_instance;
    this->stopTimer();

}

void NutLogger::Log(const Exception &ex, const std::string &logname)
{
    Poco::Logger::get(switchFileName(logname)).log(ex);
}

void NutLogger::Log(const std::string &sMsg, const std::string &logname)
{
    Poco::Logger::get(switchFileName(logname)).log(sMsg);
}

void NutLogger::Log(const Exception &ex, const std::string &fileName, const int &line, const std::string &logname)
{
    Poco::Logger::get(switchFileName(logname)).log(ex,fileName.c_str(),line);
}

void NutLogger::Log(const std::exception &ex, const std::string &logname)
{
    Poco::Logger::get(switchFileName(logname)).log(Poco::Exception(ex.what()));
}

void NutLogger::information(const std::string &msg, const std::string &logname)
{
    Poco::Logger::get(switchFileName(logname)).information(msg);
}

void NutLogger::warning(const std::string &msg, const std::string &logname)
{
    Poco::Logger::get(switchFileName(logname)).warning(msg);
}

void NutLogger::error(const std::string &msg, const std::string &logname)
{
    Poco::Logger::get(switchFileName(logname)).error(msg);
}

void NutLogger::notice(const std::string &msg, const std::string &logname)
{
    Poco::Logger::get(switchFileName(logname)).notice(msg);
}

void NutLogger::debug(const std::string &msg, const std::string &logname)
{
    Poco::Logger::get(switchFileName(logname)).debug(msg);
}

void NutLogger::initUserLog(const std::string &logFilename, const std::string &logname)
{
    m_logName2FileName[logname] =logFilename;

    ///* 1.获取 root logger */
    auto &logger = Poco::Logger::root();

    ///* 2.设置管道 */

    ///* 2.1 创建控制台管道 */
    Poco::AutoPtr<Poco::ConsoleChannel> console_channel(new Poco::ConsoleChannel);

    ///* 2.2 创建文件管道 */
    AutoPtr<FileChannel> file_channel(new FileChannel);
     file_channel->setProperty("rotation" ,"10M");   //日志文件的旋转模式
     file_channel->setProperty("archive" ,"timestamp");  //日志文件的归档模式
     file_channel->setProperty("path",switchFileName(logFilename));

    ///* 2.3 创建 Formatter */
    // 关于格式化控制符的说明可以参见 PatternFormatter.h 中的描述
    Poco::AutoPtr<Poco::PatternFormatter> patternFormatter(
        new Poco::PatternFormatter("[%Y-%m-%d  %H:%M:%S] [%s] %p: %t"));

    patternFormatter->setProperty("times", "local");  // 格式化中的时间显示为本地时间

    ///* 2.4 创建 SplitterChannel */
    AutoPtr<SplitterChannel> splitter_Channel(new SplitterChannel);
    splitter_Channel->addChannel(file_channel);
    splitter_Channel->addChannel(console_channel);

   /// /* 2.5 创建 Formatting Channel */
    Poco::AutoPtr<Poco::FormattingChannel> formattingChannel(
        new Poco::FormattingChannel(patternFormatter, splitter_Channel));

  ///* 2.56 将 Formatting Channel 设置给 logger */
    Poco::Logger::root().setChannel(formattingChannel);


    /* 3.打印日志 */
    //poco_error( Poco::Logger::get("Nut"), "This is an error message");

    Poco::Logger::create(logname,formattingChannel);


}

void NutLogger::init()
{
    std::string year;
    std::string mouth;
      std::string day;
    Poco::intToStr(m_dateTime.year(),10,year,false,4,'0 ');
    Poco::intToStr(m_dateTime.month(),10,mouth,false,2,'0 ');
    Poco::intToStr(m_dateTime.day(),10,day,false,2,'0 ');

   m_datePostfix = "."+ year + mouth +day;

   std::string slogFileDir = std::string("../Log");
   Poco::File file(slogFileDir);
   if(!file.exists())
   {
       file.createDirectory();
   }
   initUserLog(slogFileDir+"/Nut.Log","Nut");
  // initUserLog(slogFileDir+"/User.Log","User");

   checkLogFileCount();


}

std::string NutLogger::switchFileName(const std::string &filename)
{
        return (filename+m_datePostfix);
}

void NutLogger::checkLogFileCount()
{
    std::set<std::string>nuts;
    std::set<std::string>users;
    Poco::Path path("../log");
    Poco::DirectoryIterator iter(path.toString());
    Poco::DirectoryIterator end;
    while (iter!=end)
    {
        if(iter->isFile())
        {
            if(std::strstr(iter.name().c_str(),"Nut.Log")==iter.name().c_str())
            {
                nuts.insert(iter.path().toString());
            }
            if(std::strstr(iter.name().c_str(),"User.Log")==iter.name().c_str())
            {
                users.insert(iter.path().toString());
            }
        }
        ++iter;
    }
        while (nuts.size()>30)
        {
            std::set<std::string>::iterator iter=nuts.begin();
            Poco::File file(*iter);
            file.remove();
            nuts.erase(iter);
        }
        while (users.size()>30)
        {
            std::set<std::string>::iterator iter=nuts.begin();
            Poco::File file(*iter);
            file.remove();
            users.erase(iter);
        }
}

bool NutLogger::startTimer()
{
    try
    {
        m_timer.start(callback);   // 启动定时器线程
        //started = true;
    }
    catch (...)
    {
        return false;
        end = true;
    }

    return true;
}

void NutLogger::onTimer(Timer &t)
{
    this->Log("3423423423423","NUt");
    m_currentDateTime = Poco::Timestamp::fromEpochTime(time(NULL));

    Poco::Int64 sub = m_currentDateTime.year()*1000 + m_currentDateTime.month()*100 + m_currentDateTime.day() - \
            m_dateTime.year()*1000 - m_dateTime.month()*100 -m_dateTime.day();
    if(sub>0)
      {
            Poco::Logger::shutdown();

            std::string year;
            std::string mouth;
              std::string day;
            Poco::intToStr(m_currentDateTime.year(),10,year,false,4,'0 ');
            Poco::intToStr(m_currentDateTime.month(),10,mouth,false,2,'0 ');
            Poco::intToStr(m_currentDateTime.day(),10,day,false,2,'0 ');

           m_datePostfix = "."+ year + mouth +day;

           for(std::map<std::string ,std::string>::iterator iter=m_logName2FileName.begin();
               iter !=m_logName2FileName.end();iter++)
           {
               Poco::Logger::destroy(iter->first);
               initUserLog(iter->second,iter->first);
           }
           this->checkLogFileCount();

     }
}

void NutLogger::stopTimer()
{
       m_timer.stop();  // 终止定时器线程
}


猜你喜欢

转载自blog.csdn.net/osean_li/article/details/80273519