1 /* 2 * Copyright (C) 2021 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 #ifndef SP_CSV_UTIL_H 16 #define SP_CSV_UTIL_H 17 #include <iostream> 18 #include <string> 19 #include <fstream> 20 #include <sstream> 21 #include <climits> 22 #include <cstdlib> 23 #include <map> 24 #include "common.h" 25 #include "sp_data.h" 26 #include "sp_utils.h" 27 #include "sp_task.h" 28 #include <sys/stat.h> 29 #include <sys/statfs.h> 30 #include "sp_log.h" 31 #include "hisysevent.h" 32 #include <vector> 33 #include <dirent.h> 34 namespace OHOS { 35 namespace SmartPerf { 36 class SpCsvUtil { 37 public: WriteCsv(const std::string & path,std::vector<SPData> & vmap)38 static void WriteCsv(const std::string &path, std::vector<SPData>& vmap) 39 { 40 std::ofstream outFile; 41 std::string cmdResult; 42 SPUtils::LoadCmd(CMD_COMMAND_MAP.at(CmdCommand::USER_PERMISSIONS), cmdResult); 43 outFile.open(path.c_str(), std::ios::out | std::ios::trunc); 44 if (SPUtils::GetPathPermissions(path) && outFile.is_open() && path == "/data/local/tmp/data.csv" && 45 (cmdResult == "root" || cmdResult == "shell")) { 46 std::string cmd = "chmod 777 " + path; 47 SPUtils::LoadCmd(cmd, cmdResult); 48 } 49 int i = 0; 50 for (SPData& spdata : vmap) { 51 std::string lineContent = ""; 52 for (auto iter = spdata.values.cbegin(); iter != spdata.values.cend(); ++iter) { 53 lineContent += iter->second + ","; 54 } 55 if (i == 0) { 56 std::string csvTitle = ""; 57 csvTitle = SetDataCsvTitle(spdata); 58 csvTitle.pop_back(); 59 outFile << csvTitle << std::endl; 60 } 61 lineContent.pop_back(); 62 outFile << lineContent << std::endl; 63 ++i; 64 } 65 ReportFileWriteEvent(path); 66 outFile.close(); 67 } WriteCsvH(std::map<std::string,std::string> & vmap)68 static void WriteCsvH(std::map<std::string, std::string>& vmap) 69 { 70 const std::string outGeneralPath = "/data/local/tmp/smartperf/1/t_general_info.csv"; 71 std::ofstream outFile(outGeneralPath, std::ios::out | std::ios::trunc); 72 if (!outFile.is_open()) { 73 std::cout << "Error opening file!" << std::endl; 74 return; 75 } 76 for (const auto& [key, value] : vmap) { 77 outFile << key << "," << value << std::endl; 78 } 79 ReportFileWriteEvent(outGeneralPath); 80 outFile.close(); 81 } SetDataCsvTitle(SPData & spdata)82 static std::string SetDataCsvTitle(SPData& spdata) 83 { 84 std::string csvTitle = SPTask::GetInstance().GetCsvTitle(); 85 if (csvTitle.empty()) { 86 for (auto iter = spdata.values.cbegin(); iter != spdata.values.cend(); ++iter) { 87 csvTitle += iter->first + ","; 88 } 89 } 90 return csvTitle; 91 } 92 IsUiTestCreatedFile(const std::string & fileName)93 static bool IsUiTestCreatedFile(const std::string &fileName) 94 { 95 if (fileName == "t_general_info.csv" || fileName == "t_index_info.csv" || fileName == "data.csv") { 96 return true; 97 } 98 return false; 99 } 100 GetFileSize(const std::string & filePath)101 static uint64_t GetFileSize(const std::string &filePath) 102 { 103 struct stat fileStat; 104 uint64_t fileSize = stat(filePath.c_str(), &fileStat) ? 0 : static_cast<uint64_t>(fileStat.st_size); 105 return fileSize; 106 } 107 GetUiTestCreatedFileSize(const std::string & newFilePath,std::string & dirName)108 static uint64_t GetUiTestCreatedFileSize(const std::string &newFilePath, std::string &dirName) 109 { 110 uint64_t createdFileSize = 0; 111 DIR* dir = opendir(dirName.c_str()); 112 if (!dir) { 113 LOGE("Open dir %{public}s failed.", dirName.c_str()); 114 return createdFileSize; 115 } 116 if (newFilePath != "") { 117 createdFileSize += GetFileSize(newFilePath); 118 } 119 struct dirent* file; 120 while ((file = readdir(dir)) != nullptr) { 121 if (file->d_type == DT_REG && IsUiTestCreatedFile(file->d_name)) { 122 std::string filePath = dirName + "/" + file->d_name; 123 if (filePath != newFilePath) { 124 createdFileSize += GetFileSize(filePath); 125 } 126 } 127 } 128 closedir(dir); 129 return createdFileSize; 130 } 131 ReportFileWriteEvent(const std::string & newFilePath)132 static void ReportFileWriteEvent(const std::string &newFilePath) 133 { 134 std::string partitionName = "/data"; 135 std::string dirName = "/data/local/tmp"; 136 struct statfs partitionStat; 137 138 if (statfs(partitionName.c_str(), &partitionStat) != 0) { 139 LOGE("Get remain partition size failed, partitionName = %{public}s", partitionName.c_str()); 140 return; 141 } 142 constexpr double units = 1024.0; 143 double remainPartitionSize = (static_cast<double>(partitionStat.f_bfree) / units) * 144 (static_cast<double>(partitionStat.f_bsize) / units); 145 uint64_t createdFileSize = GetUiTestCreatedFileSize(newFilePath, dirName); 146 std::vector<std::string> filePaths = { dirName }; 147 std::vector<uint64_t> fileSizes = { createdFileSize }; 148 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::FILEMANAGEMENT, "USER_DATA_SIZE", 149 HiviewDFX::HiSysEvent::EventType::STATISTIC, 150 "COMPONENT_NAME", "SP_daemon", 151 "PARTITION_NAME", partitionName, 152 "REMAIN_PARTITION_SIZE", remainPartitionSize, 153 "FILE_OR_FOLDER_PATH", filePaths, 154 "FILE_OR_FOLDER_SIZE", fileSizes); 155 156 LOGD("partitionName = %s", partitionName.c_str()); 157 LOGD("remainPartitionSize = %lld", remainPartitionSize); 158 } 159 }; 160 } 161 } 162 163 #endif // SP_CSV_UTILS_H 164