| 1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. | 
|---|
| 2 | // | 
|---|
| 3 | // SPDX-License-Identifier: GPL-3.0-or-later | 
|---|
| 4 |  | 
|---|
| 5 | #include "codetimecheck.h" | 
|---|
| 6 |  | 
|---|
| 7 | #include "framework/log/logutils.h" | 
|---|
| 8 |  | 
|---|
| 9 | //全局模块使能宏 | 
|---|
| 10 | #ifndef DPF_NO_CHECK_TIME | 
|---|
| 11 |  | 
|---|
| 12 | #include <QString> | 
|---|
| 13 | #include <QFile> | 
|---|
| 14 | #include <QCoreApplication> | 
|---|
| 15 | #include <QStandardPaths> | 
|---|
| 16 | #include <QDebug> | 
|---|
| 17 | #include <QMutex> | 
|---|
| 18 | #include <QDateTime> | 
|---|
| 19 | #include <QDate> | 
|---|
| 20 | #include <QDir> | 
|---|
| 21 | #include <QtConcurrent> | 
|---|
| 22 |  | 
|---|
| 23 | DPF_BEGIN_NAMESPACE | 
|---|
| 24 |  | 
|---|
| 25 | namespace GlobalPrivate { | 
|---|
| 26 |  | 
|---|
| 27 | static QFile file; | 
|---|
| 28 | static uint dayCount = 7; | 
|---|
| 29 | static QMutex mutex; | 
|---|
| 30 |  | 
|---|
| 31 | #ifdef QT_NO_DEBUG | 
|---|
| 32 | const QString tcDirName = "codeTimeCheck"; | 
|---|
| 33 | const QString tcFileName = "tc_release.csv"; | 
|---|
| 34 | #else | 
|---|
| 35 | const QString tcDirName = "codeTimeCheck"; | 
|---|
| 36 | const QString tcFileName = "tc_debug.csv"; | 
|---|
| 37 | #endif | 
|---|
| 38 |  | 
|---|
| 39 | static void rmExpiredLogs() | 
|---|
| 40 | { | 
|---|
| 41 | QtConcurrent::run([=](){ | 
|---|
| 42 | QDirIterator itera(LogUtils::appCacheLogPath() | 
|---|
| 43 | + QDir::separator() + tcDirName); | 
|---|
| 44 | while(itera.hasNext()) { | 
|---|
| 45 | itera.next(); | 
|---|
| 46 | auto list = itera.fileName().split( "_"); | 
|---|
| 47 | if (itera.fileInfo().suffix() == "csv" | 
|---|
| 48 | && list.count() == 3 | 
|---|
| 49 | && !LogUtils::containLastDay( | 
|---|
| 50 | QDateTime(QDate::fromString(list[0], "yyyy-MM-dd"), | 
|---|
| 51 | QTime(0,0,0,0)), | 
|---|
| 52 | LogUtils::toDayZero(), | 
|---|
| 53 | GlobalPrivate::dayCount)) | 
|---|
| 54 | { | 
|---|
| 55 | qInfo( "remove true(%d) not last week log: %s", | 
|---|
| 56 | QDir().remove(itera.path() + QDir::separator() + itera.fileName()), | 
|---|
| 57 | itera.fileName().toLocal8Bit().data()); | 
|---|
| 58 | } | 
|---|
| 59 | } | 
|---|
| 60 | }); | 
|---|
| 61 | } | 
|---|
| 62 |  | 
|---|
| 63 | static void outCheck(const QMessageLogContext &context, const QString &msg) | 
|---|
| 64 | { | 
|---|
| 65 | //加锁保证内部函数执行时的互斥 | 
|---|
| 66 | QMutexLocker lock(&GlobalPrivate::mutex); | 
|---|
| 67 |  | 
|---|
| 68 | const QString &currAppLogName = LogUtils::appCacheLogPath() | 
|---|
| 69 | + QDir::separator() + tcDirName + QDir::separator() | 
|---|
| 70 | + LogUtils::localDate() + "_"+ tcFileName; | 
|---|
| 71 |  | 
|---|
| 72 | // "codeTimeCheck" dir | 
|---|
| 73 | LogUtils::checkAppCacheLogDir(tcDirName); | 
|---|
| 74 |  | 
|---|
| 75 | // 文件名称为空 或者当前日期不正确(跨天日志分割) | 
|---|
| 76 | if (file.fileName().isEmpty() | 
|---|
| 77 | || file.fileName() != currAppLogName) { | 
|---|
| 78 | file.setFileName(currAppLogName); | 
|---|
| 79 | qInfo() << "Current checkTime file path: "<< file.fileName(); | 
|---|
| 80 | rmExpiredLogs(); | 
|---|
| 81 | } | 
|---|
| 82 |  | 
|---|
| 83 | bool isNewFile = false; | 
|---|
| 84 | if (!file.exists()) { | 
|---|
| 85 | isNewFile = true; | 
|---|
| 86 | } | 
|---|
| 87 |  | 
|---|
| 88 | if (!file.isOpen()) { | 
|---|
| 89 | file.open(QFile::WriteOnly|QFile::Append); | 
|---|
| 90 | } | 
|---|
| 91 |  | 
|---|
| 92 | if (isNewFile) { | 
|---|
| 93 | file.write((QString( "时间") + "," | 
|---|
| 94 | + "时间"+ "," | 
|---|
| 95 | + "毫秒"+ "," | 
|---|
| 96 | + "函数名称"+ "," | 
|---|
| 97 | + "动作类型"+ "," | 
|---|
| 98 | + "文件名称"+ "," | 
|---|
| 99 | + "文件行"+ "\n").toUtf8().data()); | 
|---|
| 100 | file.flush(); | 
|---|
| 101 | } | 
|---|
| 102 |  | 
|---|
| 103 | auto fileNameList = QString(context.file).split(QDir::separator()); | 
|---|
| 104 | auto currentName = fileNameList[fileNameList.size() - 1]; | 
|---|
| 105 |  | 
|---|
| 106 | file.write((LogUtils::localDataTimeCSV() + "," | 
|---|
| 107 | + context.function + "," | 
|---|
| 108 | + msg + "," | 
|---|
| 109 | + currentName + "," | 
|---|
| 110 | + QString::number(context.line) | 
|---|
| 111 | + "\n").toUtf8().data()); | 
|---|
| 112 | file.flush(); | 
|---|
| 113 | file.close(); | 
|---|
| 114 | } | 
|---|
| 115 |  | 
|---|
| 116 | }// namespace GlobalPrivate | 
|---|
| 117 |  | 
|---|
| 118 | /** | 
|---|
| 119 | * @brief setLogCacheDayCount 设置日志缓存时间 | 
|---|
| 120 | *  需要在调用其他函数之前调用 | 
|---|
| 121 | * @param dayCount 日志缓存时间 | 
|---|
| 122 | */ | 
|---|
| 123 | void CodeCheckTime::setLogCacheDayCount(uint dayCount) | 
|---|
| 124 | { | 
|---|
| 125 | GlobalPrivate::dayCount = dayCount; | 
|---|
| 126 | } | 
|---|
| 127 |  | 
|---|
| 128 | /** | 
|---|
| 129 | * @brief logCacheDayCount 获取设置的日志缓存时间 | 
|---|
| 130 | * @return uint 日志缓存时间,默认7天 | 
|---|
| 131 | */ | 
|---|
| 132 | uint CodeCheckTime::logCacheDayCount() | 
|---|
| 133 | { | 
|---|
| 134 | return GlobalPrivate::dayCount; | 
|---|
| 135 | } | 
|---|
| 136 |  | 
|---|
| 137 | /** | 
|---|
| 138 | * @brief begin 检查点-开始 | 
|---|
| 139 | * @param context 日志打印上下文,可参照QMessageLogContext | 
|---|
| 140 | */ | 
|---|
| 141 | void CodeCheckTime::begin(const QMessageLogContext &context) | 
|---|
| 142 | { | 
|---|
| 143 | GlobalPrivate::outCheck(context, "begin"); | 
|---|
| 144 | } | 
|---|
| 145 |  | 
|---|
| 146 | /** | 
|---|
| 147 | * @brief end 检查点-结束 | 
|---|
| 148 | * @param context 日志打印上下文,可参照QMessageLogContext | 
|---|
| 149 | */ | 
|---|
| 150 | void CodeCheckTime::end(const QMessageLogContext &context) | 
|---|
| 151 | { | 
|---|
| 152 | GlobalPrivate::outCheck(context, "end"); | 
|---|
| 153 | } | 
|---|
| 154 |  | 
|---|
| 155 | #endif // DPF_NO_CHECK_TIME | 
|---|
| 156 |  | 
|---|
| 157 | DPF_END_NAMESPACE | 
|---|
| 158 |  | 
|---|