first commit

This commit is contained in:
2026-04-29 14:10:10 +08:00
commit b28556d43d
1558 changed files with 241386 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
#include "dualfilelogger.h"
DualFileLogger::DualFileLogger(QSettings *firstSettings, QSettings* secondSettings, const int refreshInterval, QObject* parent)
:Logger(parent)
{
firstLogger=new FileLogger(firstSettings, refreshInterval, this);
secondLogger=new FileLogger(secondSettings, refreshInterval, this);
}
void DualFileLogger::log(const QtMsgType type, const QString& message, const QString &file, const QString &function, const int line)
{
firstLogger->log(type,message,file,function,line);
secondLogger->log(type,message,file,function,line);
}
void DualFileLogger::clear(const bool buffer, const bool variables)
{
firstLogger->clear(buffer,variables);
secondLogger->clear(buffer,variables);
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef DUALFILELOGGER_H
#define DUALFILELOGGER_H
#include <QString>
#include <QSettings>
#include <QtGlobal>
#include "logglobal.h"
#include "logger.h"
#include "filelogger.h"
class DECLSPEC DualFileLogger : public Logger {
Q_OBJECT
Q_DISABLE_COPY(DualFileLogger)
public:
DualFileLogger(QSettings* firstSettings, QSettings* secondSettings,
const int refreshInterval=10000, QObject *parent = nullptr);
virtual void log(const QtMsgType type, const QString& message, const QString &file="",
const QString &function="", const int line=0);
virtual void clear(const bool buffer=true, const bool variables=true);
private:
FileLogger* firstLogger;
FileLogger* secondLogger;
};
#endif // DUALFILELOGGER_H
+273
View File
@@ -0,0 +1,273 @@
#include "filelogger.h"
#include <QTime>
#include <QStringList>
#include <QThread>
#include <QtGlobal>
#include <QFile>
#include <QTimerEvent>
#include <QDir>
#include <QFileInfo>
#include <stdio.h>
#include<iostream>
#include<string>
#include<QDate>
#include "LogInfo.h"
#define LOG_FILE_PATH "/home/plg/loginfo/"
void FileLogger::refreshSettings()
{
mutex.lock();
QString oldFileName=fileName;
settings->sync();
fileName = LOG_FILE_PATH;
// fileName=settings->value("fileName").toString();
// LogInfo::setRunStatusText(tr("fileName: %1").arg(fileName));
QDate today = QDate::currentDate();
QString todayString=today.toString(Qt::ISODate);
// 计算前七天的日期
//QDate oneWeekAgo = today.addDays(-7);
fileName+=today.toString(Qt::ISODate);
fileName+="/";
fileName+="log.txt";
static QString lastDay = "";
if(lastDay!=todayString)
{
TimerDel->start(30000);
lastDay=todayString;
}
#ifdef Q_OS_WIN32
if (QDir::isRelativePath(fileName) && settings->format()!=QSettings::NativeFormat)
#else
if (QDir::isRelativePath(fileName))
#endif
{
QFileInfo configFile(settings->fileName());
fileName=QFileInfo(configFile.absolutePath(),fileName).absoluteFilePath();
}
maxSize=settings->value("maxSize",0).toLongLong();
maxBackups=settings->value("maxBackups",0).toInt();
msgFormat=settings->value("msgFormat","{timestamp} {type} {msg}").toString();
timestampFormat=settings->value("timestampFormat","yyyy-MM-dd hh:mm:ss.zzz").toString();
bufferSize=settings->value("bufferSize",0).toInt();
QByteArray minLevelStr = settings->value("minLevel","ALL").toByteArray();
if (minLevelStr=="ALL" || minLevelStr=="DEBUG" || minLevelStr=="0")
{
minLevel=QtDebugMsg;
}
else if (minLevelStr=="WARNING" || minLevelStr=="WARN" || minLevelStr=="1")
{
minLevel=QtWarningMsg;
}
else if (minLevelStr=="ERROR" || minLevelStr=="CRITICAL" || minLevelStr=="2")
{
minLevel=QtCriticalMsg;
}
else if (minLevelStr=="FATAL" || minLevelStr=="3")
{
// minLevel=QtMsgType::QtFatalMsg;
minLevel=QtFatalMsg;
}
// else if (minLevelStr=="INFO" || minLevelStr=="4")
// {
// minLevel=QtMsgType::QtInfoMsg;
// }
if (oldFileName!=fileName)
{
fprintf(stderr,"Logging to %s\n",qPrintable(fileName));
close();
open();
}
mutex.unlock();
}
FileLogger::FileLogger(QSettings *settings, const int refreshInterval, QObject* parent)
: Logger(parent)
{
TimerDel = new QTimer(this);
connect(TimerDel,SIGNAL(timeout()),this,SLOT(timeOutToDelete()));
Q_ASSERT(settings!=nullptr);
Q_ASSERT(refreshInterval>=0);
this->settings=settings;
file=nullptr;
if (refreshInterval>0)
{
refreshTimer.start(refreshInterval,this);
}
flushTimer.start(1000,this);
refreshSettings();
}
FileLogger::~FileLogger()
{
close();
}
void FileLogger::write(const LogMessage* logMessage)
{
if (file)
{
// qDebug()<<"Critical message output test\n";
// qCritical("This is a critical message of test\n");
file->write(qPrintable(logMessage->toString(msgFormat,timestampFormat)));
if (logMessage->getType()>=QtCriticalMsg)
{
file->flush();
}
if (file->error())
{
qWarning("Cannot write to log file %s: %s",qPrintable(fileName),qPrintable(file->errorString()));
close();
}
}
if (!file)
{
Logger::write(logMessage);
}
}
void FileLogger::open()
{
if (fileName.isEmpty())
{
qWarning("Name of logFile is empty");
}
else {
file=new QFile(fileName);
QFileInfo fileInfo(fileName);
// 检查文件路径是否有效
if (!fileInfo.exists()) {
// 获取文件所在的目录路径
QString dirPath = QFileInfo(fileName).absoluteDir().path();
// 检查目录是否存在
if (!QDir(dirPath).exists()) {
// 如果目录不存在,则创建目录
QDir().mkpath(dirPath);
if (!QDir(dirPath).exists()) {
// 如果创建目录失败,显示错误消息
qDebug("Cannot create directory for log file: %s", qPrintable(dirPath));
delete file;
file = nullptr;
return;
}
}
}
if (!file->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
{
qWarning("Cannot open log file %s: %s",qPrintable(fileName),qPrintable(file->errorString()));
file=nullptr;
}
}
}
void FileLogger::close()
{
if (file)
{
file->close();
delete file;
file=nullptr;
}
}
void FileLogger::rotate() {
int count=0;
forever
{
QFile bakFile(QString("%1.%2").arg(fileName).arg(count+1));
if (bakFile.exists())
{
++count;
}
else
{
break;
}
}
while (maxBackups>0 && count>=maxBackups)
{
QFile::remove(QString("%1.%2").arg(fileName).arg(count));
--count;
}
for (int i=count; i>0; --i) {
QFile::rename(QString("%1.%2").arg(fileName).arg(i),QString("%1.%2").arg(fileName).arg(i+1));
}
QFile::rename(fileName,fileName+".1");
}
void FileLogger::timerEvent(QTimerEvent* event)
{
if (!event)
{
return;
}
else if (event->timerId()==refreshTimer.timerId())
{
refreshSettings();
}
else if (event->timerId()==flushTimer.timerId() && file)
{
mutex.lock();
file->flush();
if (maxSize>0 && file->size()>=maxSize)
{
close();
rotate();
open();
}
mutex.unlock();
}
}
bool FileLogger::removeDirectory(const QString &directoryPath) {
// 检查目录是否存在
QDir dir(directoryPath);
if (dir.exists()) {
system((char *)((QString("rm -r %1").arg(directoryPath)).toLatin1().data()));
return true;
}
return false;
}
void FileLogger::timeOutToDelete(){
QDate today = QDate::currentDate();
for(int daysAgo=14;daysAgo>=7;--daysAgo){
QString needToDelFoldPath=LOG_FILE_PATH;
QDate pastDate=today.addDays(-daysAgo);
needToDelFoldPath+=pastDate.toString(Qt::ISODate);
needToDelFoldPath+="/";
if (QDir(needToDelFoldPath).exists()) {
bool result= removeDirectory(needToDelFoldPath);
if(result){
qDebug()<<"The directory and all its contents have been removed";
LogInfo::setRunStatusText(tr("The directory and all its contents have been removed"));
}else{
qDebug() << "Failed to remove the directory";
LogInfo::setRunStatusText(tr("Failed to remove the directory"));
}
}
}
TimerDel->stop();
}
+62
View File
@@ -0,0 +1,62 @@
#ifndef FILELOGGER_H
#define FILELOGGER_H
#include <QtGlobal>
#include <QSettings>
#include <QFile>
#include <QMutex>
#include <QBasicTimer>
#include "logglobal.h"
#include "logger.h"
#include <QTimer>
class DECLSPEC FileLogger : public Logger {
Q_OBJECT
Q_DISABLE_COPY(FileLogger)
public:
FileLogger(QSettings* settings, const int refreshInterval=10000, QObject* parent = nullptr);
virtual ~FileLogger();
virtual void write(const LogMessage* logMessage);
public slots:
void timeOutToDelete();
protected:
void timerEvent(QTimerEvent* event);
private:
QString fileName;
long maxSize;
int maxBackups;
QSettings* settings;
QFile* file;
QBasicTimer refreshTimer;
QBasicTimer flushTimer;
QTimer *TimerDel;
void open();
void close();
void rotate();
void refreshSettings();
bool removeDirectory(const QString &directoryPath);
};
#endif // FILELOGGER_H
+243
View File
@@ -0,0 +1,243 @@
#include "logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <QDateTime>
#include <QThread>
#include <QObject>
#include <iostream>
Logger* Logger::defaultLogger=nullptr;
QThreadStorage<QHash<QString,QString>*> Logger::logVars;
QMutex Logger::mutex;
Logger::Logger(QObject* parent)
: QObject(parent),
msgFormat("{timestamp} {type} {msg}"),
timestampFormat("dd.MM.yyyy hh:mm:ss.zzz"),
minLevel(QtDebugMsg),
bufferSize(0)
{}
Logger::Logger(const QString msgFormat, const QString timestampFormat, const QtMsgType minLevel, const int bufferSize, QObject* parent)
:QObject(parent)
{
this->msgFormat=msgFormat;
this->timestampFormat=timestampFormat;
this->minLevel=minLevel;
this->bufferSize=bufferSize;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
static QRecursiveMutex recursiveMutex;
static QMutex nonRecursiveMutex;
#else
static QMutex recursiveMutex(QMutex::Recursive);
static QMutex nonRecursiveMutex(QMutex::NonRecursive);
#endif
void Logger::msgHandler(const QtMsgType type, const QString &message, const QString &file, const QString &function, const int line)
{
recursiveMutex.lock();
if (defaultLogger && nonRecursiveMutex.tryLock())
{
defaultLogger->log(type, message, file, function, line);
nonRecursiveMutex.unlock();
}
else
{
fputs(qPrintable(message),stderr);
fflush(stderr);
}
if (type==QtFatalMsg)
{
abort();
}
recursiveMutex.unlock();
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
void Logger::msgHandler5(const QtMsgType type, const QMessageLogContext &context, const QString &message)
{
(void)(context);
msgHandler(type,message,context.file,context.function,context.line);
}
#else
void Logger::msgHandler4(const QtMsgType type, const char* message)
{
msgHandler(type,message);
}
#endif
Logger::~Logger()
{
if (defaultLogger==this)
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
qInstallMessageHandler(nullptr);
#else
qInstallMsgHandler(nullptr);
#endif
defaultLogger=nullptr;
}
}
void Logger::write(const LogMessage* logMessage)
{
fputs(qPrintable(logMessage->toString(msgFormat,timestampFormat)), stderr);
fflush(stderr);
}
void Logger::installMsgHandler()
{
defaultLogger=this;
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
qInstallMessageHandler(msgHandler5);
#else
qInstallMsgHandler(msgHandler4);
#endif
}
void Logger::set(const QString& name, const QString& value)
{
mutex.lock();
if (!logVars.hasLocalData())
{
logVars.setLocalData(new QHash<QString,QString>);
}
logVars.localData()->insert(name,value);
mutex.unlock();
}
void Logger::clear(const bool buffer, const bool variables)
{
mutex.lock();
if (buffer && buffers.hasLocalData())
{
QList<LogMessage*>* buffer=buffers.localData();
while (buffer && !buffer->isEmpty())
{
LogMessage* logMessage=buffer->takeLast();
delete logMessage;
}
}
if (variables && logVars.hasLocalData())
{
logVars.localData()->clear();
}
mutex.unlock();
}
void Logger::log(const QtMsgType type, const QString& message, const QString &file, const QString &function, const int line)
{
bool toPrint=false;
switch (type)
{
case QtDebugMsg:
if (minLevel==QtDebugMsg)
{
toPrint=true;
}
break;
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
case QtInfoMsg:
if (minLevel==QtDebugMsg ||
minLevel==QtInfoMsg)
{
toPrint=true;
}
break;
#endif
case QtWarningMsg:
if (minLevel==QtDebugMsg ||
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
minLevel==QtInfoMsg ||
#endif
minLevel==QtWarningMsg)
{
toPrint=true;
}
break;
case QtCriticalMsg:
if (minLevel==QtDebugMsg ||
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
minLevel==QtInfoMsg ||
#endif
minLevel==QtWarningMsg ||
minLevel==QtCriticalMsg)
{
toPrint=true;
}
break;
case QtFatalMsg:
toPrint=true;
break;
default:
toPrint=true;
}
mutex.lock();
LogMessage* logMessage=new LogMessage(type,message,logVars.localData(),file,function,line);
std::cout << qPrintable(logMessage->toString(msgFormat,"hh:mm:ss.zzz")) << std::flush;
if (bufferSize>0)
{
if (!buffers.hasLocalData())
{
buffers.setLocalData(new QList<LogMessage*>());
}
QList<LogMessage*>* buffer=buffers.localData();
buffer->append(logMessage);
if (buffer->size()>bufferSize)
{
delete buffer->takeFirst();
}
if (toPrint)
{
while (!buffer->isEmpty())
{
LogMessage* logMessage=buffer->takeFirst();
write(logMessage);
delete logMessage;
}
}
}
else
{
if (toPrint)
{
LogMessage logMessage(type,message,logVars.localData(),file,function,line);
write(&logMessage);
}
}
mutex.unlock();
}
+76
View File
@@ -0,0 +1,76 @@
#ifndef LOGGER_H
#define LOGGER_H
#include <QtGlobal>
#include <QThreadStorage>
#include <QHash>
#include <QStringList>
#include <QMutex>
#include <QObject>
#include "logglobal.h"
#include "logmessage.h"
#include <QDebug>
class DECLSPEC Logger : public QObject {
Q_OBJECT
Q_DISABLE_COPY(Logger)
public:
Logger(QObject* parent);
Logger(const QString msgFormat="{timestamp} {type} {msg}",
const QString timestampFormat="dd.MM.yyyy hh:mm:ss.zzz",
const QtMsgType minLevel=QtDebugMsg, const int bufferSize=0,
QObject* parent = nullptr);
virtual ~Logger();
virtual void log(const QtMsgType type, const QString& message, const QString &file="",
const QString &function="", const int line=0);
void installMsgHandler();
static void set(const QString& name, const QString& value);
virtual void clear(const bool buffer=true, const bool variables=true);
protected:
QString msgFormat;
QString timestampFormat;
QtMsgType minLevel;
int bufferSize;
static QMutex mutex;
virtual void write(const LogMessage* logMessage);
private:
static Logger* defaultLogger;
static void msgHandler(const QtMsgType type, const QString &message, const QString &file="",
const QString &function="", const int line=0);
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
static void msgHandler5(const QtMsgType type, const QMessageLogContext& context, const QString &message);
#else
static void msgHandler4(const QtMsgType type, const char * message);
#endif
static QThreadStorage<QHash<QString,QString>*> logVars;
QThreadStorage<QList<LogMessage*>*> buffers;
};
#endif // LOGGER_H
+23
View File
@@ -0,0 +1,23 @@
#ifndef LOGGLOBAL_H
#define LOGGLOBAL_H
#include <QtGlobal>
#if defined(Q_OS_WIN)
#if defined(QTWEBAPPLIB_EXPORT)
#define DECLSPEC Q_DECL_EXPORT
#elif defined(QTWEBAPPLIB_IMPORT)
#define DECLSPEC Q_DECL_IMPORT
#endif
#endif
#if !defined(DECLSPEC)
#define DECLSPEC
#endif
#if __cplusplus < 201103L
#define nullptr 0
#endif
#endif // LOGGLOBAL_H
+78
View File
@@ -0,0 +1,78 @@
#include "logmessage.h"
#include <QThread>
LogMessage::LogMessage(const QtMsgType type, const QString& message, const QHash<QString, QString> *logVars, const QString &file, const QString &function, const int line)
{
this->type=type;
this->message=message;
this->file=file;
this->function=function;
this->line=line;
timestamp=QDateTime::currentDateTime();
threadId=QThread::currentThreadId();
if (logVars)
{
this->logVars=*logVars;
}
}
QString LogMessage::toString(const QString& msgFormat, const QString& timestampFormat) const
{
QString decorated=msgFormat+"\n";
decorated.replace("{msg}",message);
if (decorated.contains("{timestamp}"))
{
decorated.replace("{timestamp}",timestamp.toString(timestampFormat));
}
QString typeNr;
typeNr.setNum(type);
decorated.replace("{typeNr}",typeNr);
switch (type)
{
case QtDebugMsg:
decorated.replace("{type}","DEBUG ");
break;
case QtWarningMsg:
decorated.replace("{type}","WARNING ");
break;
case QtCriticalMsg:
decorated.replace("{type}","CRITICAL");
break;
case QtFatalMsg:
decorated.replace("{type}","FATAL ");
break;
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
case QtInfoMsg:
decorated.replace("{type}","INFO ");
break;
#endif
}
decorated.replace("{file}",file);
decorated.replace("{function}",function);
decorated.replace("{line}",QString::number(line));
QString threadId = QString("0x%1").arg(qulonglong(QThread::currentThreadId()), 8, 16, QLatin1Char('0'));
decorated.replace("{thread}",threadId);
if (decorated.contains("{") && !logVars.isEmpty())
{
QList<QString> keys=logVars.keys();
foreach (QString key, keys)
{
decorated.replace("{"+key+"}",logVars.value(key));
}
}
return decorated;
}
QtMsgType LogMessage::getType() const
{
return type;
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef LOGMESSAGE_H
#define LOGMESSAGE_H
#include <QtGlobal>
#include <QDateTime>
#include <QHash>
#include "logglobal.h"
class DECLSPEC LogMessage
{
Q_DISABLE_COPY(LogMessage)
public:
LogMessage(const QtMsgType type, const QString& message, const QHash<QString,QString>* logVars,
const QString &file, const QString &function, const int line);
QString toString(const QString& msgFormat, const QString& timestampFormat) const;
QtMsgType getType() const;
private:
QHash<QString,QString> logVars;
QDateTime timestamp;
QtMsgType type;
Qt::HANDLE threadId;
QString message;
QString file;
QString function;
int line;
};
#endif // LOGMESSAGE_H