Qt編寫軟體執行時間記錄(開源)
阿新 • • 發佈:2019-03-11
在早期開發的軟體中,尤其是初學者入門者寫的軟體,軟體執行久了,難免遇到意外崩潰的時候,可是大部分的執行裝置可能在現場客戶那,需要記住每一次從軟體啟動後到軟體意外關閉前的執行時間,需要記錄的資訊包括:編號+開始時間+結束時間+已執行時間,每次完整的執行過程只產生一條記錄,每次執行時間改變以後更新當前這條記錄即可。這樣就可以確切的瞭解到軟體在現場的真實執行情況是否糟糕,如果沒有這個記錄(當然可以選擇記錄儲存到資料庫),程式又重啟恢復了,也不知道到底每次運行了多久,從幾點到幾點。
為了寫的簡單點,不干擾原有的資料庫檔案,我一般選擇輸出到文字檔案。
完整程式碼下載:
完整程式碼:
#ifndef SAVERUNTIME_H
#define SAVERUNTIME_H
#include <QObject>
#include <QDateTime>
class QTimer;
#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif
class QDESIGNER_WIDGET_EXPORT SaveRunTime : public QObject
#else
class SaveRunTime : public QObject
#endif
{
Q_OBJECT
public:
static SaveRunTime *Instance();
explicit SaveRunTime(QObject *parent = 0);
private:
static QScopedPointer<SaveRunTime> self;
QString path; //日誌檔案路徑
QString name; //日誌檔名稱
int lastID;
int saveInterval;
QDateTime startTime;
QString logFile;
QTimer *timerSave;
private:
void getDiffValue(const QDateTime &startTime, const QDateTime &endTime, int &day, int &hour, int &minute);
signals:
public slots:
void start(); //啟動服務
void stop(); //停止服務
void initLog(); //初始化日誌檔案
void appendLog(); //追加一條記錄到日誌檔案
void saveLog(); //儲存執行時間到日誌檔案
void setPath(const QString &path);
void setName(const QString &name);
void setSaveInterval(int saveInterval);
};
#endif // SAVERUNTIME_H
#include "saveruntime.h"
#include "qmutex.h"
#include "qapplication.h"
#include "qtimer.h"
#include "qfile.h"
#include "qtextstream.h"
#include "qstringlist.h"
#include "qdebug.h"
#ifdef Q_OS_WIN
#define NEWLINE "\r\n"
#else
#define NEWLINE "\n"
#endif
QScopedPointer<SaveRunTime> SaveRunTime::self;
SaveRunTime *SaveRunTime::Instance()
{
if (self.isNull()) {
QMutex mutex;
QMutexLocker locker(&mutex);
if (self.isNull()) {
self.reset(new SaveRunTime);
}
}
return self.data();
}
SaveRunTime::SaveRunTime(QObject *parent) : QObject(parent)
{
path = qApp->applicationDirPath();
QString str = qApp->applicationFilePath();
QStringList list = str.split("/");
name = list.at(list.count() - 1).split(".").at(0);
saveInterval = 1 * 60 * 1000;
startTime = QDateTime::currentDateTime();
timerSave = new QTimer(this);
timerSave->setInterval(saveInterval);
connect(timerSave, SIGNAL(timeout()), this, SLOT(saveLog()));
}
void SaveRunTime::start()
{
timerSave->start();
initLog();
appendLog();
saveLog();
}
void SaveRunTime::stop()
{
timerSave->stop();
}
void SaveRunTime::getDiffValue(const QDateTime &startTime, const QDateTime &endTime, int &day, int &hour, int &minute)
{
qint64 sec = startTime.secsTo(endTime);
day = hour = minute = 0;
int seconds = 0;
while (sec > 0) {
seconds++;
if (seconds == 60) {
minute++;
seconds = 0;
}
if (minute == 60) {
hour++;
minute = 0;
}
if (hour == 24) {
day++;
hour = 0;
}
sec--;
}
}
void SaveRunTime::initLog()
{
//判斷當前年份的記事本檔案是否存在,不存在則新建並且寫入標題
//存在則自動讀取最後一行的id號 記事本檔案格式內容
//編號 開始時間 結束時間 已執行時間
//1 2016-01-01 12:33:33 2016-02-05 12:12:12 day: 0 hour: 0 minute: 0
logFile = QString("%1/%2_runtime_%3.txt").arg(path).arg(name).arg(QDate::currentDate().year());
QFile file(logFile);
if (file.size() == 0) {
if (file.open(QFile::WriteOnly | QFile::Text)) {
QString strID = QString("%1\t").arg("編號");
QString strStartTime = QString("%1\t\t").arg("開始時間");
QString strEndTime = QString("%1\t\t").arg("結束時間");
QString strRunTime = QString("%1").arg("已執行時間");
QString line = strID + strStartTime + strEndTime + strRunTime;
QTextStream stream(&file);
stream << line << NEWLINE;
file.close();
lastID = 0;
}
} else {
if (file.open(QFile::ReadOnly)) {
QString lastLine;
while (!file.atEnd()) {
lastLine = file.readLine();
}
file.close();
QStringList list = lastLine.split("\t");
lastID = list.at(0).toInt();
}
}
lastID++;
}
void SaveRunTime::appendLog()
{
logFile = QString("%1/%2_runtime_%3.txt").arg(path).arg(name).arg(QDate::currentDate().year());
QFile file(logFile);
//寫入當前首次執行時間
if (file.open(QFile::WriteOnly | QFile::Append | QFile::Text)) {
QString strID = QString("%1\t").arg(lastID);
QString strStartTime = QString("%1\t").arg(startTime.toString("yyyy-MM-dd HH:mm:ss"));
QString strEndTime = QString("%1\t").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
int day, hour, minute;
getDiffValue(startTime, QDateTime::currentDateTime(), day, hour, minute);
QString strRunTime = QString("%1 天 %2 時 %3 分").arg(day).arg(hour).arg(minute);
QString line = strID + strStartTime + strEndTime + strRunTime;
QTextStream stream(&file);
stream << line << NEWLINE;
file.close();
}
}
void SaveRunTime::saveLog()
{
//每次儲存都是將之前的所有文字讀取出來,然後替換最後一行即可
logFile = QString("%1/%2_runtime_%3.txt").arg(path).arg(name).arg(QDate::currentDate().year());
QFile file(logFile);
//如果日誌檔案不存在,則初始化一個日誌檔案
if (file.size() == 0) {
initLog();
appendLog();
return;
}
if (file.open(QFile::ReadWrite)) {
//一行行讀取到連結串列
QStringList content;
while (!file.atEnd()) {
content.append(file.readLine());
}
//重新清空檔案
file.resize(0);
//如果行數小於2則返回
if (content.count() < 2) {
file.close();
return;
}
QString lastLine = content.last();
QStringList list = lastLine.split("\t");
//計算已執行時間
int day, hour, minute;
getDiffValue(startTime, QDateTime::currentDateTime(), day, hour, minute);
QString strRunTime = QString("%1 天 %2 時 %3 分").arg(day).arg(hour).arg(minute);
//重新拼接最後一行
list[2] = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
list[3] = strRunTime;
lastLine = list.join("\t");
//重新替換最後一行並寫入新的資料
content[content.count() - 1] = lastLine;
QTextStream stream(&file);
stream << content.join("") << NEWLINE;
file.close();
}
}
void SaveRunTime::setPath(const QString &path)
{
if (this->path != path) {
this->path = path;
}
}
void SaveRunTime::setName(const QString &name)
{
if (this->name != name) {
this->name = name;
}
}
void SaveRunTime::setSaveInterval(int saveInterval)
{
if (this->saveInterval != saveInterval) {
this->saveInterval = saveInterval;
timerSave->setInterval(saveInterval);
}
}