利用qt线程,实现日志模块
作者:互联网
思路结构
- 利用线程实现日志模块
- 日志默认写入当前路径,也可指定路径
- 记录时间,模块名,内容
- 日志文件数量最多为三个,循环覆盖写入,可追加写入
- 接收到的内容使用队列接收,需要加锁防止崩溃
- 尽量使用qt的库,方便更换平台编译
源代码
common.h
#ifndef COMMON_H
#define COMMON_H
enum Event
{
EV_LOGPATH_ERROR = 0,
EV_LOGFILE_ERROR
};
#endif // COMMON_H
mylogheader.h
#ifndef MYLOGHEADER_H
#define MYLOGHEADER_H
#define LOG_SIZE 1024*1024
#include <QThread>
#include <QTextStream>
#include <QQueue>
#include <QMutex>
#include <QFile>
#include <QFileInfo>
#include <QTime>
#include <QDebug>
#include <QDir>
#include "common.h"
class MyLogHeader : public QThread
{
Q_OBJECT
public:
explicit MyLogHeader(QObject *parent = nullptr);
void RecvData(QString, QString);
void RecvPath(QString);
void TaskOver();
QString GetLogPath(QString, int);
signals:
void SendEvent(Event);
protected:
void run() override;
private:
QQueue<QString> m_QueData;
QMutex m_DataLock;
QFile* m_LogFile;
QString m_strLogPath;
QString m_strLogFile;
QStringList m_FileList; // log name
QList<QString>::iterator m_ptrLog;
int m_LogTmp;
bool m_bOpen;
bool m_bEnable;
bool m_bOver;
};
#endif // MYLOGHEADER_H
mylogheader.cpp
#include "mylogheader.h"
MyLogHeader::MyLogHeader(QObject *parent) : QThread(parent)
{
m_QueData.clear();
m_LogFile = new QFile(this);
m_bOpen = true;
m_bEnable = false;
m_bOver = false;
m_LogTmp = 0;
m_FileList<<"1-log.txt"<<"2-log.txt"<<"3-log.txt";
m_strLogPath = QDir::currentPath();
}
void MyLogHeader::run()
{
while(1)
{
QThread::msleep(10);
// init log
if(m_bOpen)
{
m_bOpen = false;
if(m_bEnable)
{
m_LogFile->close();
}
m_strLogFile = GetLogPath(m_strLogPath, m_LogTmp);
m_LogFile->setFileName(m_strLogFile);
bool res = m_LogFile->open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Append);
if(!res)
{
emit SendEvent(EV_LOGFILE_ERROR);
continue;
}
m_bEnable = true;
}
if(false == m_bEnable)
{
continue;
}
if(m_bOver)
{
return;
}
// write log
QMutexLocker mutex(&m_DataLock);
while(!m_QueData.isEmpty())
{
QTextStream stream(m_LogFile);
stream<<m_QueData.dequeue()<<"\n";
}
// next log
QFileInfo info(*m_LogFile);
if(info.size() >= LOG_SIZE)
{
if(m_LogTmp == m_FileList.size())
{
m_LogTmp = 1;
}
else
{
m_LogTmp ++;
}
m_LogFile->close();
m_bOpen = true;
m_bEnable = false;
}
}
}
// time [ type ] info
void MyLogHeader::RecvData(QString type, QString info)
{
QDateTime dateTime(QDateTime::currentDateTime());
QString strBuf = dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz") + " [" + type + "] " + info;
QMutexLocker mutex(&m_DataLock);
m_QueData.enqueue(strBuf);
}
void MyLogHeader::RecvPath(QString path)
{
QDir dir;
if(!dir.exists(path))
{
if(false == dir.mkpath(path))
{
emit SendEvent(EV_LOGPATH_ERROR);
return;
}
}
m_strLogPath = path;
qDebug()<<"RecvPath:"<<m_strLogPath;
m_bOpen = true;
}
QString MyLogHeader::GetLogPath(QString path, int LogTmp)
{
QDir dir;
QString LogFile = "";
int tmp = 1;
if(0 == LogTmp)
{
for(m_ptrLog = m_FileList.begin(); m_ptrLog != m_FileList.end(); m_ptrLog ++)
{
LogFile = path + "/" + (*m_ptrLog);
if(dir.exists(LogFile))
{
QFileInfo info(LogFile);
if(info.size() >= LOG_SIZE)
{
if((++ m_ptrLog) == m_FileList.end())
{
m_ptrLog = m_FileList.begin();
LogFile = path + "/" + (*m_ptrLog);
QFile::remove(LogFile);
break;
}
m_ptrLog --;
tmp ++;
continue;
}
break;
}
break;
}
m_LogTmp = tmp;
m_bOpen = true;
}
else
{
m_ptrLog = m_FileList.begin();
for(int i = 1; i < m_LogTmp; i ++)
{
m_ptrLog ++;
}
LogFile = path + "/" + (*m_ptrLog);
if(dir.exists(LogFile))
{
QFile::remove(LogFile);
}
}
return LogFile;
}
void MyLogHeader::TaskOver()
{
m_bOver = true;
}
效果图
标签:include,qt,ptrLog,LogTmp,FileList,线程,QString,日志,LogFile 来源: https://blog.csdn.net/seaeress/article/details/122809025