qt里面用log4qt日志库

Posted wushuang443

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qt里面用log4qt日志库相关的知识,希望对你有一定的参考价值。

1,下载链接,

项目地址:GitHub - devbean/log4qt: Logger for Qt.
注意:log4qt网上有多个项目,比如Log4Qt - Logging for C++/Qt download | SourceForge.net(已迁移到GitHub - MEONMedical/Log4Qt: Log4Qt - Logging for the Qt cross-platform application framework),此项目用的人多,但是多个版本下载下来测试,都编译不过去,然后才找到上面那个项目,没有问题。

2,使用方式

2.1编译成第三方库,在此不做介绍,自行百度

2.2 把它作为自己源代码继承进来

# 定义所需的宏
DEFINES += LOG4QT_LIBRARY

## 定义 Log4Qt 源码根目录
LOG4QT_ROOT_PATH = $$PWD/Log4Qt-master

# 指定编译项目时应该被搜索的 #include 目录
INCLUDEPATH += $$LOG4QT_ROOT_PATH/src \\
               $$LOG4QT_ROOT_PATH/src/log4qt \\
               $$LOG4QT_ROOT_PATH/include \\
               $$LOG4QT_ROOT_PATH/include/log4qt

## 将 Log4Qt 源代码添加至项目中
include($$LOG4QT_ROOT_PATH/src/log4qt/log4qt.pri)
include($$LOG4QT_ROOT_PATH/build.pri)
include($$LOG4QT_ROOT_PATH/g++.pri)

3,代码使用,比如

//Log4Qt的使用
    QString outpath = QCoreApplication::applicationDirPath() + "/xxx.log";
    QString configPath = QApplication::applicationDirPath() + "/xxx.conf";
    if(QFile::exists(outpath) && QFile::exists(configPath))
   
        QFile::remove(outpath);
        QFile::remove(configPath);

   
    if(!QFile::exists(configPath))//不存在配置文件 创建默认配配置文件
        QSettings configSet(configPath,QSettings::IniFormat);
        configSet.setIniCodec("UTF-8");
      
        configSet.setValue("log4j.rootLogger",QStringList()<<"DEBUG"<<"A2");
        //file
        //configSet.setValue("log4j.logger.A2","A2");
        configSet.setValue("log4j.appender.A2","org.apache.log4j.FileAppender");
        configSet.setValue("log4j.appender.A2","org.apache.log4j.RollingFileAppender");
        configSet.setValue("log4j.appender.A2.File",outpath);
        configSet.setValue("log4j.appender.A2.AppendFile","true");
        configSet.setValue("log4j.appender.A2.MaxFileSize","4096KB");
        configSet.setValue("log4j.appender.A2.MaxBackupIndex","3");
        configSet.setValue("log4j.appender.A2.layout","org.apache.log4j.PatternLayout");
        configSet.setValue("log4j.appender.A2.layout.ConversionPattern","%dyyyy-MM-dd HH:mm:ss %m%n");
        configSet.sync();
    else// 存在修改日志保存路径
        QSettings configSet(configPath,QSettings::IniFormat);
        configSet.setIniCodec("UTF-8");
        configSet.setValue("log4j.appender.A2.File",outpath);
        configSet.sync();
   

    Log4Qt::PropertyConfigurator::configure(configPath);
    Log4Qt::LogManager::setHandleQtMessages(true);
    qDebug("start used log4qt!");

Qt自定义控件之日志控件

摘要

一般的应用程序都需要在界面上显示日志信息, glog是google的轻量级日志库,本文结合glog,实现了一个简单的线程安全的日志控件。

正文

关于glog的使用,网上有好多介绍的资料,本文参考里面列出了一些,这里就不介绍了。下面列出日志控件的实现要点:

1、日志控件继承自google::LogSink,重新实现其virtual send()函数,自定义日志处理逻辑。

2、调用google::AddLogSink(this),将日志控件添加到glog的转发容器中;

3、日志控件使用QplainTextEdit来显示日志信息;

4、日志控件维护一个线程安全的日志的vector,使用定时器定时从vector中取出日志,并在QplainTextEdit中显示;

 本文代码在vs2015和qt5.7.1的64位编译下进行测试。

下载地址:https://github.com/binbinneu/qt_practice

 实现代码如下:

class LogWidget : public QWidget, public google::LogSink
{
    Q_OBJECT;

public:
    LogWidget(QWidget *parent = 0);
    virtual ~LogWidget();

public:
    virtual void send(google::LogSeverity severity, const char* full_filename, 
        const char* base_filename, int line, const struct ::tm* tm_time, const char* message, size_t message_len);

public Q_SLOTS:
    void refresh();

private:
    QPlainTextEdit *log_widget_;
    QTimer timer_;
    std::mutex mutex_;

    typedef std::pair<std::string, google::LogSeverity> MessageType;
    std::vector<MessageType> message_vec_;

    const int MAXIMUM_BLOCK_COUNT;
    const int REFESH_TIME;
};
LogWidget::LogWidget(QWidget *parent /*= 0*/) : QWidget(parent), 
    MAXIMUM_BLOCK_COUNT(10000), REFESH_TIME(100)
{
    QHBoxLayout *layout = new QHBoxLayout();
    layout->setMargin(0);
    setLayout(layout);

    //采用QPlainTextEdit显示日志信息
    log_widget_ = new QPlainTextEdit(this);
    log_widget_->setMaximumBlockCount(MAXIMUM_BLOCK_COUNT);
    log_widget_->setReadOnly(true);
    layout->addWidget(log_widget_);

    //定时器,定时刷新日志
    QObject::connect(&timer_, SIGNAL(timeout()), this, SLOT(refresh()));
    timer_.start(REFESH_TIME);

    //添加到glog的转发容器中
    google::AddLogSink(this);
}

LogWidget::~LogWidget()
{
    timer_.stop();
    QObject::disconnect(&timer_, SIGNAL(timeout()), this, SLOT(refresh()));

    google::RemoveLogSink(this);
}

void LogWidget::refresh()
{
    std::lock_guard<std::mutex> lock(mutex_);
    if (!message_vec_.empty())
    {
        for (const auto &message : message_vec_)
        {
            log_widget_->appendPlainText(QString::fromLocal8Bit(message.first.c_str()));
        }
    }
    message_vec_.clear();
}

void LogWidget::send(google::LogSeverity severity, const char* full_filename,
    const char* base_filename, int line, const struct ::tm* tm_time, const char* message, size_t message_len)
{
    std::ostringstream message_stream;
    message_stream.fill(0);

    message_stream << "[" << google::LogSeverityNames[severity][0]
        << std::setw(2) << 1 + tm_time->tm_mon
        << std::setw(2) << tm_time->tm_mday
        <<  
        << std::setw(2) << tm_time->tm_hour << :
        << std::setw(2) << tm_time->tm_min << :
        << std::setw(2) << tm_time->tm_sec
        <<  
        << full_filename << : << line << "] ";

    message_stream << std::string(message, message_len);
    std::string message_str = message_stream.str();

    std::lock_guard<std::mutex> lock(mutex_);
    message_vec_.push_back(MessageType(message_str, severity));
}

测试代码:

void thread_fun()
{
    for (int i=0; i<1000000; ++i)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));

        LOG(INFO) << "INFO";
        LOG(WARNING) << "WARNING";
        LOG(ERROR) << "ERROR";
    }
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    LogWidget w;
    w.show();

    QString log_path = QCoreApplication::applicationDirPath() + "/";

    google::InitGoogleLogging(argv[0]);
    google::SetLogDestination(google::INFO, log_path.toStdString().c_str());
    google::SetLogDestination(google::WARNING, log_path.toStdString().c_str());
    google::SetLogDestination(google::ERROR, log_path.toStdString().c_str());
    google::SetLogDestination(google::FATAL, log_path.toStdString().c_str());

    for (int i=0; i<10; ++i)
    {
        std::thread t(thread_fun);
        t.detach();
    }

    int b = a.exec();

    google::ShutdownGoogleLogging();

    return b;
}

 输出结果:

技术分享

参考

1、http://blog.csdn.net/breaksoftware/article/details/51363353

2、http://www.cnblogs.com/davidyang2415/p/3861109.html

 

以上是关于qt里面用log4qt日志库的主要内容,如果未能解决你的问题,请参考以下文章

Qt教程 : 用Log4Qt自定义日志系统

Log4Qt快速入门——Log4Qt日志格式化源码解析

Log4Qt快速入门——Log4Qt日志输出重定向源码解析

log4qt内存泄露问题,heob内存检测工具的使用

Log4Qt 日志格式化(PatternLayout)

请教log4qt的日志分类问题