新增日志重定向和运行时间记录
This commit is contained in:
65
savelog/frmsavelog.cpp
Normal file
65
savelog/frmsavelog.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmsavelog.h"
|
||||
#include "ui_frmsavelog.h"
|
||||
#include "savelog.h"
|
||||
#include "qdatetime.h"
|
||||
#include "qtimer.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
frmSaveLog::frmSaveLog(QWidget *parent) : QWidget(parent), ui(new Ui::frmSaveLog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
}
|
||||
|
||||
frmSaveLog::~frmSaveLog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmSaveLog::initForm()
|
||||
{
|
||||
timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(append()));
|
||||
timer->setInterval(1000);
|
||||
|
||||
SaveLog::Instance()->setPath(qApp->applicationDirPath());
|
||||
}
|
||||
|
||||
void frmSaveLog::append()
|
||||
{
|
||||
QString msg = QString("当前时间: %1 测试打印输出消息").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
|
||||
ui->txtMain->append(msg);
|
||||
qDebug() << msg;
|
||||
}
|
||||
|
||||
void frmSaveLog::on_btnDebug_clicked()
|
||||
{
|
||||
QString msg = QString("当前时间: %1 手动插入消息").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
|
||||
ui->txtMain->append(msg);
|
||||
qDebug() << msg;
|
||||
}
|
||||
|
||||
void frmSaveLog::on_ckTimer_stateChanged(int arg1)
|
||||
{
|
||||
if (arg1 == 0) {
|
||||
timer->stop();
|
||||
} else {
|
||||
timer->start();
|
||||
}
|
||||
}
|
||||
|
||||
void frmSaveLog::on_ckNet_stateChanged(int arg1)
|
||||
{
|
||||
SaveLog::Instance()->setToNet(arg1 != 0);
|
||||
}
|
||||
|
||||
void frmSaveLog::on_ckSave_stateChanged(int arg1)
|
||||
{
|
||||
if (arg1 == 0) {
|
||||
SaveLog::Instance()->stop();
|
||||
} else {
|
||||
SaveLog::Instance()->start();
|
||||
}
|
||||
}
|
||||
32
savelog/frmsavelog.h
Normal file
32
savelog/frmsavelog.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef FRMSAVELOG_H
|
||||
#define FRMSAVELOG_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class frmSaveLog;
|
||||
}
|
||||
|
||||
class frmSaveLog : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmSaveLog(QWidget *parent = 0);
|
||||
~frmSaveLog();
|
||||
|
||||
private:
|
||||
Ui::frmSaveLog *ui;
|
||||
QTimer *timer;
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
void append();
|
||||
void on_btnDebug_clicked();
|
||||
void on_ckTimer_stateChanged(int arg1);
|
||||
void on_ckNet_stateChanged(int arg1);
|
||||
void on_ckSave_stateChanged(int arg1);
|
||||
|
||||
};
|
||||
|
||||
#endif // FRMSAVELOG_H
|
||||
58
savelog/frmsavelog.ui
Normal file
58
savelog/frmsavelog.ui
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmSaveLog</class>
|
||||
<widget class="QWidget" name="frmSaveLog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="ckTimer">
|
||||
<property name="text">
|
||||
<string>定时器打印消息</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QCheckBox" name="ckSave">
|
||||
<property name="text">
|
||||
<string>保存日志</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="btnDebug">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>手动插入消息</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QTextEdit" name="txtMain"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="ckNet">
|
||||
<property name="text">
|
||||
<string>重定向到网络</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
31
savelog/main.cpp
Normal file
31
savelog/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmsavelog.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#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
|
||||
|
||||
frmSaveLog w;
|
||||
w.setWindowTitle("输出日志文件");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
193
savelog/savelog.cpp
Normal file
193
savelog/savelog.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
#include "savelog.h"
|
||||
#include "qmutex.h"
|
||||
#include "qfile.h"
|
||||
#include "qtcpsocket.h"
|
||||
#include "qtcpserver.h"
|
||||
#include "qdatetime.h"
|
||||
#include "qapplication.h"
|
||||
#include "qtimer.h"
|
||||
#include "qstringlist.h"
|
||||
|
||||
#define QDATE qPrintable(QDate::currentDate().toString("yyyy-MM-dd"))
|
||||
|
||||
//日志重定向
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
void Log(QtMsgType type, const char *msg)
|
||||
#else
|
||||
void Log(QtMsgType type, const QMessageLogContext &, const QString &msg)
|
||||
#endif
|
||||
{
|
||||
//加锁,防止多线程中qdebug太频繁导致崩溃
|
||||
QMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
QString content;
|
||||
|
||||
//这里可以根据不同的类型加上不同的头部用于区分
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
content = QString("%1").arg(msg);
|
||||
break;
|
||||
|
||||
case QtWarningMsg:
|
||||
content = QString("%1").arg(msg);
|
||||
break;
|
||||
|
||||
case QtCriticalMsg:
|
||||
content = QString("%1").arg(msg);
|
||||
break;
|
||||
|
||||
case QtFatalMsg:
|
||||
content = QString("%1").arg(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
SaveLog::Instance()->save(content);
|
||||
}
|
||||
|
||||
QScopedPointer<SaveLog> SaveLog::self;
|
||||
SaveLog *SaveLog::Instance()
|
||||
{
|
||||
if (self.isNull()) {
|
||||
static QMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
if (self.isNull()) {
|
||||
self.reset(new SaveLog);
|
||||
}
|
||||
}
|
||||
|
||||
return self.data();
|
||||
}
|
||||
|
||||
SaveLog::SaveLog(QObject *parent) : QObject(parent)
|
||||
{
|
||||
//必须用信号槽形式,不然提示 QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
|
||||
//估计日志钩子可能单独开了线程
|
||||
connect(this, SIGNAL(send(QString)), SendLog::Instance(), SLOT(send(QString)));
|
||||
|
||||
file = new QFile(this);
|
||||
toNet = false;
|
||||
//默认取应用程序根目录
|
||||
path = qApp->applicationDirPath();
|
||||
//默认取应用程序可执行文件名称
|
||||
QString str = qApp->applicationFilePath();
|
||||
QStringList list = str.split("/");
|
||||
name = list.at(list.count() - 1).split(".").at(0);
|
||||
fileName = "";
|
||||
}
|
||||
|
||||
SaveLog::~SaveLog()
|
||||
{
|
||||
file->close();
|
||||
}
|
||||
|
||||
//安装日志钩子,输出调试信息到文件,便于调试
|
||||
void SaveLog::start()
|
||||
{
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
qInstallMsgHandler(Log);
|
||||
#else
|
||||
qInstallMessageHandler(Log);
|
||||
#endif
|
||||
}
|
||||
|
||||
//卸载日志钩子
|
||||
void SaveLog::stop()
|
||||
{
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
qInstallMsgHandler(0);
|
||||
#else
|
||||
qInstallMessageHandler(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SaveLog::save(const QString &content)
|
||||
{
|
||||
//如果重定向输出到网络则通过网络发出去,否则输出到日志文件
|
||||
if (toNet) {
|
||||
emit send(content);
|
||||
} else {
|
||||
//方法改进:之前每次输出日志都打开文件,改成只有当日期改变时才新建和打开文件
|
||||
QString fileName = QString("%1/%2_log_%3.txt").arg(path).arg(name).arg(QDATE);
|
||||
if (this->fileName != fileName) {
|
||||
this->fileName = fileName;
|
||||
if (file->isOpen()) {
|
||||
file->close();
|
||||
}
|
||||
|
||||
file->setFileName(fileName);
|
||||
file->open(QIODevice::WriteOnly | QIODevice::Append | QFile::Text);
|
||||
}
|
||||
|
||||
QTextStream logStream(file);
|
||||
logStream << content << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void SaveLog::setToNet(bool toNet)
|
||||
{
|
||||
this->toNet = toNet;
|
||||
}
|
||||
|
||||
void SaveLog::setPath(const QString &path)
|
||||
{
|
||||
this->path = path;
|
||||
}
|
||||
|
||||
void SaveLog::setName(const QString &name)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
|
||||
//网络发送日志数据类
|
||||
QScopedPointer<SendLog> SendLog::self;
|
||||
SendLog *SendLog::Instance()
|
||||
{
|
||||
if (self.isNull()) {
|
||||
static QMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
if (self.isNull()) {
|
||||
self.reset(new SendLog);
|
||||
}
|
||||
}
|
||||
|
||||
return self.data();
|
||||
}
|
||||
|
||||
SendLog::SendLog(QObject *parent)
|
||||
{
|
||||
socket = NULL;
|
||||
server = new QTcpServer(this);
|
||||
connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
|
||||
|
||||
int listenPort = 6000;
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
|
||||
server->listen(QHostAddress::AnyIPv4, listenPort);
|
||||
#else
|
||||
server->listen(QHostAddress::Any, listenPort);
|
||||
#endif
|
||||
}
|
||||
|
||||
SendLog::~SendLog()
|
||||
{
|
||||
if (socket != NULL) {
|
||||
socket->disconnectFromHost();
|
||||
}
|
||||
|
||||
server->close();
|
||||
}
|
||||
|
||||
void SendLog::newConnection()
|
||||
{
|
||||
while (server->hasPendingConnections()) {
|
||||
socket = server->nextPendingConnection();
|
||||
}
|
||||
}
|
||||
|
||||
void SendLog::send(const QString &content)
|
||||
{
|
||||
if (socket != NULL && socket->isOpen()) {
|
||||
socket->write(content.toUtf8());
|
||||
socket->flush();
|
||||
}
|
||||
}
|
||||
84
savelog/savelog.h
Normal file
84
savelog/savelog.h
Normal file
@@ -0,0 +1,84 @@
|
||||
#ifndef SAVELOG_H
|
||||
#define SAVELOG_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QFile;
|
||||
class QTcpSocket;
|
||||
class QTcpServer;
|
||||
|
||||
#ifdef quc
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT SaveLog : public QObject
|
||||
#else
|
||||
class SaveLog : public QObject
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static SaveLog *Instance();
|
||||
explicit SaveLog(QObject *parent = 0);
|
||||
~SaveLog();
|
||||
|
||||
private:
|
||||
static QScopedPointer<SaveLog> self;
|
||||
|
||||
//文件对象
|
||||
QFile *file;
|
||||
//是否重定向到网络
|
||||
bool toNet;
|
||||
//日志文件路径
|
||||
QString path;
|
||||
//日志文件名称
|
||||
QString name;
|
||||
//日志文件完整名称
|
||||
QString fileName;
|
||||
|
||||
signals:
|
||||
void send(const QString &content);
|
||||
|
||||
public slots:
|
||||
//启动日志服务
|
||||
void start();
|
||||
//暂停日志服务
|
||||
void stop();
|
||||
//保存日志
|
||||
void save(const QString &content);
|
||||
|
||||
//设置是否重定向到网络
|
||||
void setToNet(bool toNet);
|
||||
//设置日志文件存放路径
|
||||
void setPath(const QString &path);
|
||||
//设置日志文件名称
|
||||
void setName(const QString &name);
|
||||
|
||||
};
|
||||
|
||||
class SendLog : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static SendLog *Instance();
|
||||
explicit SendLog(QObject *parent = 0);
|
||||
~SendLog();
|
||||
|
||||
private:
|
||||
static QScopedPointer<SendLog> self;
|
||||
QTcpSocket *socket;
|
||||
QTcpServer *server;
|
||||
|
||||
private slots:
|
||||
void newConnection();
|
||||
|
||||
public slots:
|
||||
//发送日志
|
||||
void send(const QString &content);
|
||||
};
|
||||
|
||||
#endif // SAVELOG_H
|
||||
23
savelog/savelog.pro
Normal file
23
savelog/savelog.pro
Normal file
@@ -0,0 +1,23 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2019-02-16T15:08:47
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui network
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = savelog
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmsavelog.cpp
|
||||
SOURCES += savelog.cpp
|
||||
|
||||
HEADERS += frmsavelog.h
|
||||
HEADERS += savelog.h
|
||||
|
||||
FORMS += frmsavelog.ui
|
||||
Reference in New Issue
Block a user