在线程写日志,线程支持单例模式
写日志:日志目录默认为程序目录下,”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天前的日志
}