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
23DPF_BEGIN_NAMESPACE
24
25namespace 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 */
123void CodeCheckTime::setLogCacheDayCount(uint dayCount)
124{
125 GlobalPrivate::dayCount = dayCount;
126}
127
128/**
129 * @brief logCacheDayCount 获取设置的日志缓存时间
130 * @return uint 日志缓存时间,默认7天
131 */
132uint CodeCheckTime::logCacheDayCount()
133{
134 return GlobalPrivate::dayCount;
135}
136
137/**
138 * @brief begin 检查点-开始
139 * @param context 日志打印上下文,可参照QMessageLogContext
140 */
141void CodeCheckTime::begin(const QMessageLogContext &context)
142{
143 GlobalPrivate::outCheck(context, "begin");
144}
145
146/**
147 * @brief end 检查点-结束
148 * @param context 日志打印上下文,可参照QMessageLogContext
149 */
150void CodeCheckTime::end(const QMessageLogContext &context)
151{
152 GlobalPrivate::outCheck(context, "end");
153}
154
155#endif // DPF_NO_CHECK_TIME
156
157DPF_END_NAMESPACE
158