上次和大家分享了log4cplus控制台实时输出以及全局调用的应用。我们在实际使用过程中一般在各个类中都会调用,这时我们自然是希望只包含一个头文件,然后直接调用相关的日志接口,而不是像之前一样要包含一大堆头文件还要再获取一下日志的实例化。为了达到我们的目的,我们可以自己再对日志封装一下,并且可以让日志既能实时输出到文件又可以实时输出到控制台。
程序运行平台:ubuntu qt log4cplus1.2.2
1. 封装Mylog
Mylog是一个单例类。
① 以追加方式输出到文件配置
开始时使能内部输出。接下来配置追加到文件,newRollingFileAppender需要的几
个参数分别是日志名称、单个日志文件最大尺寸、最大文件备份数目(超过部分被冲掉)。之后设置布局器也就是日志输出的格式。挂接器设置名称、设置布局器格式。控制台输出设置不做详细介绍。最后是log对象添加Appender。
最后我们看到的设置其实不多,最主要是从0到1的过程。我开始从网上查到的配置一种是使用配置文件的方式,另一种就是我使用的程序配置的方式。配置文件需要单独设置一个配置文件的目录,有一点麻烦。程序配置的方式几乎使用的都是默认的配置方式,那样是无法实时输出的,需要到缓存区达到一定大小才会输出,显然那并不是我想要的效果。
Logger Mylog::initLog4cplus()
{
helpers::LogLog::getLogLog()->setInternalDebugging(true);
SharedFileAppenderPtrappend_file(newRollingFileAppender(
LOG4CPLUS_TEXT("logs/test.log"),2*1024*1024, 5,true, true));
std::string pattern = "%D{%m/%d/%y %H:%M:%S,%q} [%-5t] [%-5p] - %m%n";
std::auto_ptr<Layout> appendFileLayout(new PatternLayout(pattern));
append_file->setName(LOG4CPLUS_TEXT("append_file"));
append_file->setLayout( appendFileLayout );
append_file->getloc();
SharedObjectPtr<Appender> append_console(new ConsoleAppender(false,true));
append_console->setName(LOG4CPLUS_TEXT("Console"));
append_console->setLayout( std::auto_ptr<Layout>(new PatternLayout(pattern)) );
this->_logger = Logger::getInstance(LOG4CPLUS_TEXT("camera"));
this->_logger.addAppender(append_console);
this->_logger.addAppender(SharedAppenderPtr(append_file.get ()));
return this->_logger;
}
②全局简化调用 封装
#define TRACE(p) LOG4CPLUS_TRACE(Mylog::instance()->getLog(), p)
#define DEBUG(p) LOG4CPLUS_DEBUG(Mylog::instance()->getLog(), p)
#define INFO(p) LOG4CPLUS_INFO(Mylog::instance()->getLog(), p)
#define WARN(p) LOG4CPLUS_WARN(Mylog::instance()->getLog(), p)
#define ERROR(p) LOG4CPLUS_ERROR(Mylog::instance()->getLog(), p)
#define FATAL(p) LOG4CPLUS_FATAL(Mylog::instance()->getLog(), p)
2.使用测试
①线程中测试
使用的是moveToThread实现的线程,这块不再多说。有兴趣的同志可以看下之前的线程中使用socket关于moveToThread的使用
void ThreadFunction::slot_testLog()
{
while(!m_stopThread)
{
INFO("I am in thread ------- ");
QThread::msleep(500);
}
}
主UI启动
m_thread = new QThread();
m_threadFunction.moveToThread(m_thread);
connect(m_thread, SIGNAL(started()), &m_threadFunction, SLOT(slot_testLog()));
m_thread->start();
停止正在运行的线程:
m_stopUIThread = true;
m_threadFunction.stopThread(true);
m_thread->quit();
bool quitRet = m_thread->wait(2000);
②主线程使用日志测试
void Widget::on_pbn_mainThreadStart_clicked()
{
while(!m_stopUIThread)
{
QApplication::processEvents(); //prevent blocking UI
INFO("main ui thread test");
QThread::msleep(500);
}
}
Mylog没有设置日志输出等级,则会全部输出。
运行效果:
输出到文件
输出到控制台