QT 线程、日志、单例模式

在线程写日志,线程支持单例模式

写日志:日志目录默认为程序目录下,”log/$DateTime“,其中$DateTime为当前日期字符串,如./log/2020-09-17/file1.txt

清除日志:可以清除指定天数之前的日志目录,比如删除2020-09-17十天前的日志,就会将2020-09-07之前的目录全部删除掉。

使用时,绑定信号槽即可。

日志信息格式:2020-09-17 15:45:26.325 info: 临兵斗者,且阵列在前!

写日志分成三种级别:info、warning、error

clog.h

#ifndef CLOG_H
#define CLOG_H

#include <QObject>
enum LOG_LEVEL{
    INFO,
    WARNING,
    ERROR
};

class QThread;
class CLog : public QObject
{
    Q_OBJECT
public:
    static CLog* getInstance();
    ~CLog();
protected:
    explicit CLog(QObject *parent = nullptr);
signals:

public slots:
    void writeLog(QString msg,QString fileName,int logLevel);// 日志文件路径:app/log/2020-09-17/fileName
    void clearLog(int day);// 删除指定目录下,指定天数前的日志
private:
    static CLog* _instance;
    QThread* pThread;
};

#endif // CLOG_H

 

clog.cpp

#include "clog.h"
#include <QMutex>
#include <QMutexLocker>
#include <QThread>
#include <QDebug>
#include <QFile>
#include <QDateTime>
#include <QCoreApplication>
#include <QDir>
#include <QStringList>
CLog* CLog::_instance = nullptr;
QMutex writeMtx;

CLog::CLog(QObject *parent) : QObject(parent)
{
    pThread = new QThread();
    this->moveToThread(pThread);
    connect(pThread,&QThread::started,[=](){
        qDebug()<<"thread started!";
    });
    connect(pThread,&QThread::finished,[](){
        qDebug()<<"thread ended!";
    });
    pThread->start();

}

CLog::~CLog()
{
    if (pThread) {
        qDebug()<<"Clog destruct!";
        pThread->quit();
        pThread->wait();
        pThread->deleteLater();
    }
}

CLog* CLog::getInstance()
{
    static QMutex mutex;
    if (!_instance) {
        QMutexLocker locker(&mutex);
        if (!_instance) {
            _instance = new CLog;
        }
    }
    return _instance;
}

void CLog::writeLog(QString msg,QString fileName,int logLevel)
{
    //qDebug()<<"log threadid:"<<QThread::currentThreadId();//判断是不是子线程
    if (fileName.isEmpty() || msg.isEmpty())
        return;
    // 打开一个文件
    QString logDir = QCoreApplication::applicationDirPath() + "/log/"+
            QDateTime::currentDateTime().toString("yyyy-MM-dd");
    QDir dir(logDir);
    if (!dir.exists())
    {
        dir.mkpath(logDir);// 如果目录不存在,则创建目录
    }
    QString filePath = logDir + "/"+fileName;
    QFile file(filePath);
    if (!file.open(QFile::WriteOnly | QFile::Append))
        return;
    QTextStream textStream(&file);
    QString logMsg = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    switch (logLevel) {
    case LOG_LEVEL::INFO:
        logMsg += " info: ";
        break;
    case LOG_LEVEL::WARNING:
        logMsg += " warning: ";
        break;
    case LOG_LEVEL::ERROR:
        logMsg += " error: ";
        break;
    default:
        logMsg += ":";
    }
    logMsg += msg;
    textStream<<logMsg<<"\r\n";
    file.flush();
    file.close();
}

void CLog::clearLog(int days)
{
    if (days <= 0)
        return;

    QDateTime dateTime = QDateTime::currentDateTime();
    QDateTime daysAgo = dateTime.addDays(-days);
    //QString strDay = dayAgo.toString("yyyy-MM-dd");
    //QDateTime fileTime = QDateTime::fromString("strDay");//获取n天前的日期

    // 获取文件夹的名字,根据名字进行比较
    QString strlogDir = QCoreApplication::applicationDirPath() + "/log";
    QDir dir(strlogDir);
    QStringList dirList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
    for(auto it:dirList) {
        QDir logDir(strlogDir+"/"+it);
        QString dirName = logDir.dirName();
        QDateTime time = QDateTime::fromString(it,"yyyy-MM-dd");
        if (time.daysTo(daysAgo) > 0){
            logDir.removeRecursively();
        }
    }
}

 

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "clog.h"
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
signals:
    void sig_writeLog(QString msg,QString filePath,int logLevel);
    void sig_clearLog(int day);
private slots:
    void on_writeLogBtn_clicked();

    void on_clearBtn_clicked();

private:
    Ui::MainWindow *ui;
    CLog* pClog = nullptr;
};

#endif // MAINWINDOW_H

 

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "clog.h"
#include <QThread>
#include <QDebug>
#include <QDir>
#include <QCoreApplication>
#include <QDateTime>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    qDebug()<<"MainThread id:"<<QThread::currentThreadId();
    pClog = CLog::getInstance();
    connect(this,&MainWindow::sig_writeLog,CLog::getInstance(),&CLog::writeLog,Qt::QueuedConnection);
    connect(this,&MainWindow::sig_clearLog,CLog::getInstance(),&CLog::clearLog,Qt::QueuedConnection);
}

MainWindow::~MainWindow()
{
    delete ui;
    delete CLog::getInstance();
}

void MainWindow::on_writeLogBtn_clicked()
{
    QString msg = ui->lineEdit->text();
    if (msg.isEmpty())
        return;
    QString fileName1 = "info.txt";
    QString fileName2 = "warning.txt";
    QString fileName3 = "error.txt";
    emit sig_writeLog(msg,fileName1,INFO);
    emit sig_writeLog(msg,fileName2,WARNING);
    emit sig_writeLog(msg,fileName3,ERROR);
}

void MainWindow::on_clearBtn_clicked()
{
//    QString filePath;
//    QString fileDir = QCoreApplication::applicationDirPath();
//    filePath = fileDir +"/";
//    QString fileName = QDateTime::currentDateTime().toString("yyyy-MM-dd")+".txt";
//    filePath += fileName;
//    qDebug()<<filePath;
//    QFileInfo info(filePath);
//    if (!info.exists())
//        qDebug()<<"file not exists!";
//    QDateTime modTime = info.lastModified();
//    qDebug()<<modTime.toString("yyyy-MM-dd hh:mm:ss");
//    if (info.isFile())
//        QFile::remove(filePath);
    emit sig_clearLog(10);// 删除10天前的日志
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值