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 "cloud_daemon_statistic.h"
17
18 #include <fcntl.h>
19 #include <fstream>
20 #include <sys/stat.h>
21 #include <unistd.h>
22
23 #include "utils_log.h"
24
25 namespace OHOS {
26 namespace FileManagement {
27 namespace CloudFile {
28 using namespace std;
29
30 #define FILE_SIZE_BYTE_TO_KB 1024
31 #define FILE_SIZE_KB_TO_MB 1024
32 #define STAT_TIME_MS_TO_S 1000
33 #define CLOUD_FILE_DIR_MOD 0770
34 #define CLOUD_FILE_MOD 0660
35
36 static const string STAT_DATA_DIR_NAME = "/data/service/el1/public/cloudfile/cloud_data_statistic";
37 static const string STAT_DATA_FILE_NAME = "cloud_sync_read_file_stat";
38 static const vector<uint64_t> OPEN_SIZE_RANGE_VECTOR = { 256, 512, 1 * FILE_SIZE_KB_TO_MB, 2 * FILE_SIZE_KB_TO_MB,
39 4 * FILE_SIZE_KB_TO_MB, 6 * FILE_SIZE_KB_TO_MB, 8 * FILE_SIZE_KB_TO_MB, 15 * FILE_SIZE_KB_TO_MB };
40 static const vector<uint64_t> OPEN_TIME_RANGE_VECTOR = { 250, 500, 1000, 1500, 2000, 5000 };
41 static const vector<uint64_t> READ_SIZE_RANGE_VECTOR = { 128, 256, 512, 1 * FILE_SIZE_KB_TO_MB, 2 * FILE_SIZE_KB_TO_MB,
42 4 * FILE_SIZE_KB_TO_MB };
43 static const vector<uint64_t> READ_TIME_RANGE_VECTOR = { 300, 600, 900, 1200, 1500, 2000, 3000, 5000, 8000 };
44
GetRangeIndex(uint64_t value,const vector<uint64_t> rangeVector)45 static uint32_t GetRangeIndex(uint64_t value, const vector<uint64_t> rangeVector)
46 {
47 uint32_t index = 0;
48 for (; index < rangeVector.size(); index++) {
49 if (value <= rangeVector[index]) {
50 break;
51 }
52 }
53 return index;
54 }
55
UpdateOpenSizeStat(uint64_t size)56 void CloudDaemonStatistic::UpdateOpenSizeStat(uint64_t size)
57 {
58 uint32_t index = GetRangeIndex(size / FILE_SIZE_BYTE_TO_KB, OPEN_SIZE_RANGE_VECTOR);
59 if (index >= OPEN_SIZE_MAX) {
60 LOGE("update open size stat fail, index overflow, index = %{public}u.", index);
61 return;
62 }
63 openSizeStat_[index]++;
64 }
65
UpdateOpenTimeStat(uint32_t type,uint64_t time)66 void CloudDaemonStatistic::UpdateOpenTimeStat(uint32_t type, uint64_t time)
67 {
68 uint32_t index = GetRangeIndex(time, OPEN_TIME_RANGE_VECTOR);
69 if (index >= OPEN_TIME_MAX) {
70 LOGE("update open time stat fail, index overflow, index = %{public}u.", index);
71 return;
72 }
73 openTimeStat_[type][index]++;
74 }
75
UpdateReadSizeStat(uint64_t size)76 void CloudDaemonStatistic::UpdateReadSizeStat(uint64_t size)
77 {
78 uint32_t index = GetRangeIndex(size / FILE_SIZE_BYTE_TO_KB, READ_SIZE_RANGE_VECTOR);
79 if (index >= READ_SIZE_MAX) {
80 LOGE("update read size stat fail, index overflow, index = %{public}u.", index);
81 return;
82 }
83 readSizeStat_[index]++;
84 }
85
UpdateReadTimeStat(uint64_t size,uint64_t time)86 void CloudDaemonStatistic::UpdateReadTimeStat(uint64_t size, uint64_t time)
87 {
88 uint32_t indexSize = GetRangeIndex(size / FILE_SIZE_BYTE_TO_KB, READ_SIZE_RANGE_VECTOR);
89 uint32_t indexTime = GetRangeIndex(time, READ_TIME_RANGE_VECTOR);
90 if (indexSize >= READ_SIZE_MAX || indexTime >= READ_TIME_MAX) {
91 LOGE("update read time stat fail, index overflow, indexSize = %{public}u, indexTime = %{public}u.",
92 indexSize, indexTime);
93 return;
94 }
95 readTimeStat_[indexSize][indexTime]++;
96 }
97
AddFileData()98 void CloudDaemonStatistic::AddFileData()
99 {
100 /* file not exist means first time, no former data, normal case */
101 auto ret = access(STAT_DATA_DIR_NAME.c_str(), F_OK);
102 if (ret != 0) {
103 LOGI("dir cloud_data_statistic not exist, ret = %{public}d.", ret);
104 return;
105 }
106 std::ifstream statDataFile(STAT_DATA_DIR_NAME + "/" + STAT_DATA_FILE_NAME);
107 if (!statDataFile) {
108 LOGI("file cloud_sync_read_file_stat not exist.");
109 return;
110 }
111
112 uint64_t tmpData;
113 for (uint32_t i = 0; i < OPEN_SIZE_MAX; i++) {
114 statDataFile >> tmpData;
115 openSizeStat_[i] += tmpData;
116 }
117 for (uint32_t i = 0; i < FILE_TYPE_MAX; i++) {
118 for (uint32_t j = 0; j < OPEN_TIME_MAX; j++) {
119 statDataFile >> tmpData;
120 openTimeStat_[i][j] += tmpData;
121 }
122 }
123 for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
124 statDataFile >> tmpData;
125 readSizeStat_[i] += tmpData;
126 }
127 for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
128 for (uint32_t j = 0; j < READ_TIME_MAX; j++) {
129 statDataFile >> tmpData;
130 readTimeStat_[i][j] += tmpData;
131 }
132 }
133 statDataFile.close();
134 }
135
OutputToFile()136 void CloudDaemonStatistic::OutputToFile()
137 {
138 string tmpStr = "";
139
140 if (access(STAT_DATA_DIR_NAME.c_str(), F_OK) != 0) {
141 auto ret = mkdir(STAT_DATA_DIR_NAME.c_str(), CLOUD_FILE_DIR_MOD);
142 if (ret != 0) {
143 LOGE("mkdir cloud_data_statistic fail, ret = %{public}d.", ret);
144 return;
145 }
146 }
147 string statFilePath = STAT_DATA_DIR_NAME + "/" + STAT_DATA_FILE_NAME;
148 if (access(statFilePath.c_str(), F_OK) != 0) {
149 auto fd = creat(statFilePath.c_str(), CLOUD_FILE_MOD);
150 if (fd < 0) {
151 LOGE("create file cloud_sync_read_file_stat fail.");
152 return;
153 }
154 close(fd);
155 }
156
157 std::ofstream statDataFile(statFilePath);
158 if (!statDataFile) {
159 LOGE("open out stream file cloud_sync_read_file_stat fail.");
160 return;
161 }
162
163 for (uint32_t i = 0; i < OPEN_SIZE_MAX; i++) {
164 tmpStr += (to_string(openSizeStat_[i]) + " ");
165 }
166 statDataFile << tmpStr << endl << endl;
167 tmpStr = "";
168
169 for (uint32_t i = 0; i < FILE_TYPE_MAX; i++) {
170 for (uint32_t j = 0; j < OPEN_TIME_MAX; j++) {
171 tmpStr += (to_string(openTimeStat_[i][j]) + " ");
172 }
173 tmpStr += "\n";
174 }
175 statDataFile << tmpStr << endl;
176 tmpStr = "";
177
178 for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
179 tmpStr += (to_string(readSizeStat_[i]) + " ");
180 }
181 statDataFile << tmpStr << endl << endl;
182 tmpStr = "";
183
184 for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
185 for (uint32_t j = 0; j < READ_TIME_MAX; j++) {
186 tmpStr += (to_string(readTimeStat_[i][j]) + " ");
187 }
188 tmpStr += "\n";
189 }
190 statDataFile << tmpStr << endl;
191 statDataFile.close();
192 }
193
ClearStat()194 void CloudDaemonStatistic::ClearStat()
195 {
196 for (uint32_t i = 0; i < OPEN_SIZE_MAX; i++) {
197 openSizeStat_[i] = 0;
198 }
199 for (uint32_t i = 0; i < FILE_TYPE_MAX; i++) {
200 for (uint32_t j = 0; j < OPEN_TIME_MAX; j++) {
201 openTimeStat_[i][j] = 0;
202 }
203 }
204 for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
205 readSizeStat_[i] = 0;
206 }
207 for (uint32_t i = 0; i < READ_SIZE_MAX; i++) {
208 for (uint32_t j = 0; j < READ_TIME_MAX; j++) {
209 readTimeStat_[i][j] = 0;
210 }
211 }
212 }
213
UpdateStatData()214 void CloudDaemonStatistic::UpdateStatData()
215 {
216 AddFileData();
217 OutputToFile();
218 ClearStat();
219 }
220
GetInstance()221 CloudDaemonStatistic &CloudDaemonStatistic::GetInstance()
222 {
223 static CloudDaemonStatistic instance_;
224 return instance_;
225 }
226
227 } // namespace CloudFile
228 } // namespace FileManagement
229 } // namespace OHOS