前言
导出日志文件到本地文件保存,方便查看上位机操作和下位机通信数据等信息。日志文件按天数创建文件夹,每次软件打开就会创建一个日志文件,如果软件安装在C盘,必须拥有管理员全权才能成功创建日志文件。
提示:以下是本篇文章正文内容,下面案例可供参考
1.头文件
代码如下(示例):
#ifndef ST_LOGGER_H
#define ST_LOGGER_H
#include <QObject>
#include <QDateTime>
#include <QDir>
#include <QByteArray>
#include <QMutex>
#include <QDebug>
#include <QCoreApplication>
namespace STMsgLogger{
class st_logger : public QObject
{
Q_OBJECT
public:
explicit st_logger(QObject *parent = Q_NULLPTR);
void MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
QString fileName() const;
int maxFileSize() const;
int logLevel() const;
protected:
bool CreateNewLogFile(QCoreApplication * app);
QFile * m_pLogFile;
bool m_bUseLogFile;
QString m_currLogFileName;
int m_nLogLevel;
int m_nMaxFileSize;
QMutex m_mutextLogger;
Q_SIGNALS:
public Q_SLOTS:
void setMaxFileSize(int nSize);
void setLogLevel(int);
};
}
#endif // ST_LOGGER_H
2.函数实现
代码如下(示例):
#include "st_logger.h"
#include <QTextStream>
namespace STMsgLogger{
st_logger::st_logger(QObject *parent) :
QObject(parent)
{
m_pLogFile = 0;
m_bUseLogFile = true;
m_nLogLevel = 2;
m_nMaxFileSize = 256*1024*1024;
}
QString st_logger::fileName() const
{
return m_currLogFileName;
}
void st_logger::setMaxFileSize(int nSize)
{
if (nSize >=1024*1024 && nSize <=1024*1024*1024)
m_nMaxFileSize = nSize;
}
int st_logger::maxFileSize() const
{
return m_nMaxFileSize;
}
int st_logger::logLevel() const
{
return m_nLogLevel;
}
void st_logger::setLogLevel(int lv)
{
if (lv >=0 && lv <=3)
m_nLogLevel = lv;
}
bool st_logger::CreateNewLogFile(QCoreApplication * app)
{
Q_UNUSED(app);
bool res = false;
QDateTime dtmCur = QDateTime::currentDateTime();
m_currLogFileName = app->applicationDirPath() + "/Log/" + dtmCur.toString("yyyy-MM-dd") + "/";
QDir dir;
dir.mkpath(m_currLogFileName);
m_currLogFileName += dtmCur.toString("yyyy_MM_dd_HH_mm_ss_");
m_currLogFileName += app->applicationName() + QString("(%1).log").arg(app->applicationPid());
if (m_pLogFile)
{
if (m_pLogFile->isOpen()==true)
m_pLogFile->close();
m_pLogFile->deleteLater();
m_pLogFile = 0;
}
m_pLogFile = new QFile (m_currLogFileName,this);
if (m_pLogFile)
{
if (m_pLogFile->open(QIODevice::WriteOnly)==false)
{
m_pLogFile->deleteLater();
m_pLogFile = 0;
}
else
res = true;
}
return res;
}
void st_logger::MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
m_mutextLogger.lock();
switch (type) {
case QtDebugMsg:
if (m_nLogLevel < 3)
{
m_mutextLogger.unlock();
return;
}
break;
case QtWarningMsg:
if (m_nLogLevel < 2)
{
m_mutextLogger.unlock();
return;
}
break;
case QtCriticalMsg:
if (m_nLogLevel < 1)
{
m_mutextLogger.unlock();
return;
}
break;
case QtFatalMsg:
if (m_nLogLevel < 0)
{
m_mutextLogger.unlock();
return;
}
break;
default:
if (m_nLogLevel < 3)
{
m_mutextLogger.unlock();
return;
}
break;
}
if (m_pLogFile==0)
{
if (m_bUseLogFile==true)
m_bUseLogFile = CreateNewLogFile(QCoreApplication::instance());
if (m_pLogFile==0)
{
m_mutextLogger.unlock();
return;
}
}
QDateTime dtmCur = QDateTime::currentDateTime();
QString strMsgHeader = "\n";
QString strMsg ;
strMsg += dtmCur.toString("yyyy-MM-dd HH:mm:ss.zzz\t");
switch (type) {
case QtDebugMsg:
strMsg += QString("Debug :");
break;
case QtWarningMsg:
strMsg += QString("Warning :");
break;
case QtCriticalMsg:
strMsg += QString("Critical:");
break;
case QtFatalMsg:
strMsg += QString("Fatal :");
break;
default:
strMsg += QString("Unknown :");
break;
}
strMsg += "\t";
strMsg.append(msg);
// strMsgHeader += QString("\t\t\t\
// From :\t%1:%2\n").arg(context.line).arg(QString(context.function));
strMsg.append(strMsgHeader);
QTextStream stream(m_pLogFile);
stream << strMsg;
stream.flush();
if (m_pLogFile->pos()>=m_nMaxFileSize)
m_bUseLogFile = CreateNewLogFile(QCoreApplication::instance());
m_mutextLogger.unlock();
}
}
3.main.cpp中使用
代码如下(示例):
#include <QDir>
#include <QFile>
#include <QDebug>
#include <QTextStream>
#include <QApplication>
#include <QStyleFactory>
#include "st_logger.h"
#include "mainwindow.h"
void setCode();
void clearLogs(int nLogKeepDays);
STMsgLogger::st_logger g_logger;
QtMessageHandler gDefaultHandler = NULL;
void stMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
setCode();
QString strMsgHeader;
QString strMsg;
QString strFile = QString(context.file);
strFile = strFile.mid(strFile.lastIndexOf("\\") + 1);
QString strFunction = QString(context.function);
strFunction = strFunction.mid(strFunction.indexOf("::") + 2);
strFunction = strFunction.left(strFunction.indexOf("("));
strMsgHeader += QString("[%1]->[%2](%3)").arg(strFile).arg(strFunction).arg(context.line);
strMsgHeader += "\t";
strMsg.append(strMsgHeader);
switch (type) {
case QtDebugMsg:
strMsg += QString("Debug : ");
break;
case QtInfoMsg:
strMsg += QString("Info : ");
break;
case QtWarningMsg:
strMsg += QString("Warning : ");
break;
case QtCriticalMsg:
strMsg += QString("Critical: ");
break;
case QtFatalMsg:
strMsg += QString("Fatal : ");
break;
default:
strMsg += QString("Unknown : ");
break;
}
strMsg.append(msg);
//用系统原来的函数完成原来的功能. 比如输出到调试窗
if (gDefaultHandler)
{
gDefaultHandler(type, context, strMsg);
}
#ifndef _DEBUG
g_logger.MessageOutput(type, context, strMsg);
#endif // !_DEBUG
}
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
QApplication::setAttribute(Qt::AA_Use96Dpi);
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Floor);
#endif
int ret = 0;
QApplication app(argc, argv);
g_logger.setLogLevel(3);
gDefaultHandler = qInstallMessageHandler(stMessageOutput);
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
//删除过期的日志文件
clearLogs(30);
MainWindow w;
w.show();
ret = app.exec();
if (ret == 773)
{
QProcess::startDetached(qApp->applicationFilePath(), QStringList());
}
return ret;
}
void setCode()
{
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
#if _MSC_VER
QTextCodec *codec = QTextCodec::codecForName("gbk");
#else
QTextCodec *codec = QTextCodec::codecForName("utf-8");
#endif
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
#else
QTextCodec *codec = QTextCodec::codecForName("utf-8");
QTextCodec::setCodecForLocale(codec);
#endif
}
void clearLogs(int nLogKeepDays)
{
//日志过期时间
QDateTime dateTimeExpiry = QDateTime::currentDateTime();
dateTimeExpiry = dateTimeExpiry.addDays(-nLogKeepDays);
QDir dir(qApp->applicationDirPath() + "/Log/");
if (!dir.exists())
return;
dir.setFilter(QDir::Dirs | QDir::Files);
dir.setSorting(QDir::DirsFirst);
foreach (QFileInfo fileInfo, dir.entryInfoList())
{
if (fileInfo.fileName() == "." | fileInfo.fileName() == "..")
continue;
if (fileInfo.isDir() && fileInfo.created() <= dateTimeExpiry)
{
CommonlyUsed::clearFiles(fileInfo.filePath());
dir.rmdir(fileInfo.fileName());
qDebug() << "删除日志:" << fileInfo.fileName();
}
}
}
4.效果展示