1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "file_ageing_utils.h"
17
18 #include <set>
19
20 #include "hilog/log.h"
21
22 #include "common_utils.h"
23 #include "trace_file_utils.h"
24 #include "trace_json_parser.h"
25
26 #ifdef LOG_DOMAIN
27 #undef LOG_DOMAIN
28 #define LOG_DOMAIN 0xD002D33
29 #endif
30 #ifdef LOG_TAG
31 #undef LOG_TAG
32 #define LOG_TAG "HitraceUtils"
33 #endif
34
35 namespace {
36 using namespace OHOS::HiviewDFX::Hitrace;
37
38 class FileAgeingChecker {
39 public:
40 virtual bool ShouldAgeing(const TraceFileInfo& traceFileInfo) = 0;
41 virtual ~FileAgeingChecker() = default;
42
43 static std::shared_ptr<FileAgeingChecker> CreateFileChecker(const TraceDumpType traceType);
44 };
45
46 class FileNumberChecker : public FileAgeingChecker {
47 public:
FileNumberChecker(int64_t count)48 explicit FileNumberChecker(int64_t count) : maxCount_(count) {};
49
ShouldAgeing(const TraceFileInfo & traceFileInfo)50 bool ShouldAgeing(const TraceFileInfo& traceFileInfo) override
51 {
52 if (currentCount_ >= maxCount_) {
53 return true;
54 }
55 currentCount_++;
56 return false;
57 }
58 private:
59 int64_t currentCount_ = 0;
60 const int64_t maxCount_;
61 };
62
63 class FileSizeChecker : public FileAgeingChecker {
64 public:
FileSizeChecker(int64_t sizeKb)65 explicit FileSizeChecker(int64_t sizeKb) : maxSizeKb_(sizeKb) {};
66
ShouldAgeing(const TraceFileInfo & traceFileInfo)67 bool ShouldAgeing(const TraceFileInfo& traceFileInfo) override
68 {
69 if (currentFileNumber_ < minFileNumber_) {
70 currentFileNumber_++;
71 currentSizeKb_ += traceFileInfo.fileSize;
72 return false;
73 }
74
75 if (currentSizeKb_ >= maxSizeKb_) {
76 return true;
77 }
78 currentSizeKb_ += traceFileInfo.fileSize;
79 return false;
80 }
81
82 private:
83 int64_t currentSizeKb_ = 0;
84 const int64_t maxSizeKb_;
85
86 int64_t currentFileNumber_ = 0;
87 const int64_t minFileNumber_ = 2; // To prevent all files from being cleared, set a minimum file number limit
88 };
89
CreateFileChecker(const TraceDumpType traceType)90 std::shared_ptr<FileAgeingChecker> FileAgeingChecker::CreateFileChecker(const TraceDumpType traceType)
91 {
92 if (traceType != TraceDumpType::TRACE_RECORDING && traceType != TraceDumpType::TRACE_SNAPSHOT) {
93 return nullptr;
94 }
95
96 const AgeingParam& param = TraceJsonParser::Instance().GetAgeingParam(traceType);
97 if (IsRootVersion() && !param.rootEnable) {
98 return nullptr;
99 }
100
101 if (param.fileSizeKbLimit > 0) {
102 return std::make_shared<FileSizeChecker>(param.fileSizeKbLimit);
103 }
104
105 if (param.fileNumberLimit > 0) {
106 return std::make_shared<FileNumberChecker>(param.fileNumberLimit);
107 }
108
109 return nullptr;
110 }
111
HandleAgeingImpl(std::vector<TraceFileInfo> & fileList,const TraceDumpType traceType,FileAgeingChecker & helper)112 void HandleAgeingImpl(std::vector<TraceFileInfo>& fileList, const TraceDumpType traceType, FileAgeingChecker& helper)
113 {
114 int32_t deleteCount = 0;
115 // handle the files saved in vector
116 std::vector<TraceFileInfo> result = {};
117 for (auto it = fileList.rbegin(); it != fileList.rend(); it++) {
118 if (helper.ShouldAgeing(*it)) {
119 if (RemoveFile(it->filename)) {
120 deleteCount++;
121 }
122 } else {
123 result.emplace_back(*it);
124 }
125 }
126 fileList.assign(result.rbegin(), result.rend());
127
128 // handle files that are not saved in vector
129 std::set<std::string> traceFiles = {};
130 GetTraceFileNamesInDir(traceFiles, traceType);
131 for (const auto& traceFileInfo : fileList) {
132 traceFiles.erase(traceFileInfo.filename);
133 }
134 for (const auto& filename : traceFiles) {
135 if (RemoveFile(filename)) {
136 deleteCount++;
137 }
138 }
139 HILOG_INFO(LOG_CORE, "HandleAgeing: deleteCount:%{public}d type:%{public}d",
140 deleteCount, static_cast<int32_t>(traceType));
141 }
142 } // namespace
143
144 namespace OHOS {
145 namespace HiviewDFX {
146 namespace Hitrace {
147
HandleAgeing(std::vector<TraceFileInfo> & fileList,const TraceDumpType traceType)148 void FileAgeingUtils::HandleAgeing(std::vector<TraceFileInfo>& fileList, const TraceDumpType traceType)
149 {
150 std::shared_ptr<FileAgeingChecker> checker = FileAgeingChecker::CreateFileChecker(traceType);
151 if (checker != nullptr) {
152 HandleAgeingImpl(fileList, traceType, *checker);
153 }
154 }
155
156 } // namespace Hitrace
157 } // namespace HiviewDFX
158 } // namespace OHOS
159