1 /*
2 * Copyright (c) 2025 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 "period_file_operator.h"
17
18 #include <algorithm>
19 #include <cerrno>
20 #include <chrono>
21 #include <iomanip>
22 #include <vector>
23
24 #include "file_util.h"
25 #include "hiview_global.h"
26 #include "hiview_logger.h"
27 #include "parameter_ex.h"
28 #include "string_util.h"
29 #include "time_util.h"
30
31 namespace OHOS {
32 namespace HiviewDFX {
33 DEFINE_LOG_TAG("HiView-PeriodInfoFileOperator");
34 namespace {
35 constexpr size_t PERIOD_FILE_WROTE_STEP = 100;
36 }
37
PeriodInfoFileOperator(HiviewContext * context,const std::string & fileName)38 PeriodInfoFileOperator::PeriodInfoFileOperator(HiviewContext* context, const std::string& fileName)
39 {
40 filePath_ = GetPeriodInfoFilePath(context, fileName);
41 }
42
ReadPeriodInfoFromFile(size_t splitItemCnt,SplitPeriodInfoHandler periodInfoHandler)43 void PeriodInfoFileOperator::ReadPeriodInfoFromFile(size_t splitItemCnt, SplitPeriodInfoHandler periodInfoHandler)
44 {
45 if (!Parameter::IsBetaVersion()) {
46 HIVIEW_LOGD("no need to read.");
47 return;
48 }
49 if (periodInfoHandler == nullptr) {
50 HIVIEW_LOGE("period info handler is null");
51 return;
52 }
53
54 std::vector<std::string> allLineContent;
55 if (!FileUtil::LoadLinesFromFile(filePath_, allLineContent)) {
56 HIVIEW_LOGE("failed to read some lines from %{public}s", filePath_.c_str());
57 return;
58 }
59 for (const auto& lineContent : allLineContent) {
60 std::vector<std::string> infoDetails;
61 StringUtil::SplitStr(lineContent, " ", infoDetails);
62 if (infoDetails.size() != splitItemCnt) {
63 HIVIEW_LOGW("incorrect line content: %{public}s", lineContent.c_str());
64 break;
65 }
66 periodInfoHandler(infoDetails);
67 }
68 }
69
WritePeriodInfoToFile(PeriodContentBuilder contentBuilder)70 void PeriodInfoFileOperator::WritePeriodInfoToFile(PeriodContentBuilder contentBuilder)
71 {
72 ++optCnt_;
73 if (optCnt_ % PERIOD_FILE_WROTE_STEP != 0) {
74 return;
75 }
76
77 if (contentBuilder == nullptr) {
78 HIVIEW_LOGW("content builder is null or content is empty");
79 return;
80 }
81
82 std::ofstream periodFileStream;
83 periodFileStream.open(filePath_, std::ios::trunc);
84 if (!periodFileStream.is_open()) {
85 HIVIEW_LOGW("failed to open %{public}s", filePath_.c_str());
86 return;
87 }
88 periodFileStream << contentBuilder() << std::endl;
89 }
90
GetPeriodInfoFilePath(HiviewContext * context,const std::string & fileName)91 std::string PeriodInfoFileOperator::GetPeriodInfoFilePath(HiviewContext* context, const std::string& fileName)
92 {
93 if (context == nullptr) {
94 HIVIEW_LOGW("context is null");
95 return "";
96 }
97
98 std::string periodFilePath = context->GetHiViewDirectory(HiviewContext::DirectoryType::WORK_DIRECTORY);
99 periodFilePath = FileUtil::IncludeTrailingPathDelimiter(periodFilePath.append("sys_event_db/count_statistic/"));
100 if (!FileUtil::IsDirectory(periodFilePath) && !FileUtil::ForceCreateDirectory(periodFilePath)) {
101 HIVIEW_LOGE("failed to init directory %{public}s.", periodFilePath.c_str());
102 return "";
103 }
104 periodFilePath.append(fileName);
105 return periodFilePath;
106 }
107
108 } // namespace HiviewDFX
109 } // namespace OHOS