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 | |