通过前面的两个章节中已经了解Poco :: Logger的基本使用方法了,下面将以企业级开发思路重新设计功能。
#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 console_channel(new Poco::ConsoleChannel);
///* 2.2 创建文件管道 */
AutoPtr 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 patternFormatter(
new Poco::PatternFormatter("[%Y-%m-%d %H:%M:%S] [%s] %p: %t"));
patternFormatter->setProperty("times", "local"); // 格式化中的时间显示为本地时间
///* 2.4 创建 SplitterChannel */
AutoPtr splitter_Channel(new SplitterChannel);
splitter_Channel->addChannel(file_channel);
splitter_Channel->addChannel(console_channel);
/// /* 2.5 创建 Formatting Channel */
Poco::AutoPtr 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::setstring>nuts;
std::setstring>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::setstring>::iterator iter=nuts.begin();
Poco::File file(*iter);
file.remove();
nuts.erase(iter);
}
while (users.size()>30)
{
std::setstring>::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::mapstring ,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(); // 终止定时器线程
}