1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4020a203aSopenharmony_ci * you may not use this file except in compliance with the License. 5020a203aSopenharmony_ci * You may obtain a copy of the License at 6020a203aSopenharmony_ci * 7020a203aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8020a203aSopenharmony_ci * 9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12020a203aSopenharmony_ci * See the License for the specific language governing permissions and 13020a203aSopenharmony_ci * limitations under the License. 14020a203aSopenharmony_ci */ 15020a203aSopenharmony_ci#include "faultlog_manager.h" 16020a203aSopenharmony_ci 17020a203aSopenharmony_ci#include <cstdint> 18020a203aSopenharmony_ci#include <memory> 19020a203aSopenharmony_ci#include <mutex> 20020a203aSopenharmony_ci#include <string> 21020a203aSopenharmony_ci#include <vector> 22020a203aSopenharmony_ci 23020a203aSopenharmony_ci#include <fcntl.h> 24020a203aSopenharmony_ci#include <sys/stat.h> 25020a203aSopenharmony_ci#include <sys/types.h> 26020a203aSopenharmony_ci#include <unistd.h> 27020a203aSopenharmony_ci 28020a203aSopenharmony_ci#include "defines.h" 29020a203aSopenharmony_ci#include "file_util.h" 30020a203aSopenharmony_ci#include "log_store_ex.h" 31020a203aSopenharmony_ci#include "hiview_logger.h" 32020a203aSopenharmony_ci#include "time_util.h" 33020a203aSopenharmony_ci 34020a203aSopenharmony_ci#include "faultlog_database.h" 35020a203aSopenharmony_ci#include "faultlog_formatter.h" 36020a203aSopenharmony_ci#include "faultlog_info.h" 37020a203aSopenharmony_ci#include "faultlog_util.h" 38020a203aSopenharmony_ci 39020a203aSopenharmony_cinamespace OHOS { 40020a203aSopenharmony_cinamespace HiviewDFX { 41020a203aSopenharmony_cinamespace { 42020a203aSopenharmony_ciconstexpr char DEFAULT_FAULTLOG_FOLDER[] = "/data/log/faultlog/faultlogger/"; 43020a203aSopenharmony_ciconstexpr int32_t MAX_FAULT_LOG_PER_HAP = 10; 44020a203aSopenharmony_ci} 45020a203aSopenharmony_ci 46020a203aSopenharmony_ciDEFINE_LOG_LABEL(0xD002D11, "FaultLogManager"); 47020a203aSopenharmony_ciLogStoreEx::LogFileFilter CreateLogFileFilter(time_t time, int32_t id, int32_t faultLogType, const std::string& module) 48020a203aSopenharmony_ci{ 49020a203aSopenharmony_ci LogStoreEx::LogFileFilter filter = [time, id, faultLogType, module](const LogFile &file) { 50020a203aSopenharmony_ci FaultLogInfo info = ExtractInfoFromFileName(file.name_); 51020a203aSopenharmony_ci if (info.time <= time) { 52020a203aSopenharmony_ci return false; 53020a203aSopenharmony_ci } 54020a203aSopenharmony_ci 55020a203aSopenharmony_ci if ((id != -1) && (info.id != id)) { 56020a203aSopenharmony_ci return false; 57020a203aSopenharmony_ci } 58020a203aSopenharmony_ci 59020a203aSopenharmony_ci if ((faultLogType != 0) && (info.faultLogType != faultLogType)) { 60020a203aSopenharmony_ci return false; 61020a203aSopenharmony_ci } 62020a203aSopenharmony_ci 63020a203aSopenharmony_ci if ((!module.empty()) && (info.module != module)) { 64020a203aSopenharmony_ci return false; 65020a203aSopenharmony_ci } 66020a203aSopenharmony_ci return true; 67020a203aSopenharmony_ci }; 68020a203aSopenharmony_ci return filter; 69020a203aSopenharmony_ci} 70020a203aSopenharmony_ci 71020a203aSopenharmony_ciFaultLogManager::~FaultLogManager() 72020a203aSopenharmony_ci{ 73020a203aSopenharmony_ci if (faultLogDb_ != nullptr) { 74020a203aSopenharmony_ci delete faultLogDb_; 75020a203aSopenharmony_ci faultLogDb_ = nullptr; 76020a203aSopenharmony_ci } 77020a203aSopenharmony_ci} 78020a203aSopenharmony_ci 79020a203aSopenharmony_ciint32_t FaultLogManager::CreateTempFaultLogFile(time_t time, int32_t id, int32_t faultType, 80020a203aSopenharmony_ci const std::string &module) const 81020a203aSopenharmony_ci{ 82020a203aSopenharmony_ci FaultLogInfo info; 83020a203aSopenharmony_ci info.time = time; 84020a203aSopenharmony_ci info.id = id; 85020a203aSopenharmony_ci info.faultLogType = faultType; 86020a203aSopenharmony_ci info.module = module; 87020a203aSopenharmony_ci auto fileName = GetFaultLogName(info); 88020a203aSopenharmony_ci return store_->CreateLogFile(fileName); 89020a203aSopenharmony_ci} 90020a203aSopenharmony_ci 91020a203aSopenharmony_civoid FaultLogManager::Init() 92020a203aSopenharmony_ci{ 93020a203aSopenharmony_ci store_ = std::make_unique<LogStoreEx>(DEFAULT_FAULTLOG_FOLDER, true); 94020a203aSopenharmony_ci LogStoreEx::LogFileComparator comparator = [](const LogFile &lhs, const LogFile &rhs) { 95020a203aSopenharmony_ci FaultLogInfo lhsInfo = ExtractInfoFromFileName(lhs.name_); 96020a203aSopenharmony_ci FaultLogInfo rhsInfo = ExtractInfoFromFileName(rhs.name_); 97020a203aSopenharmony_ci return lhsInfo.time > rhsInfo.time; 98020a203aSopenharmony_ci }; 99020a203aSopenharmony_ci store_->SetLogFileComparator(comparator); 100020a203aSopenharmony_ci store_->Init(); 101020a203aSopenharmony_ci faultLogDb_ = new FaultLogDatabase(looper_); 102020a203aSopenharmony_ci} 103020a203aSopenharmony_ci 104020a203aSopenharmony_cistd::string FaultLogManager::SaveFaultLogToFile(FaultLogInfo &info) const 105020a203aSopenharmony_ci{ 106020a203aSopenharmony_ci auto fileName = GetFaultLogName(info); 107020a203aSopenharmony_ci std::string filePath = std::string(DEFAULT_FAULTLOG_FOLDER) + fileName; 108020a203aSopenharmony_ci if (FileUtil::FileExists(filePath)) { 109020a203aSopenharmony_ci HIVIEW_LOGI("logfile %{public}s already exist.", filePath.c_str()); 110020a203aSopenharmony_ci return ""; 111020a203aSopenharmony_ci } 112020a203aSopenharmony_ci auto fd = store_->CreateLogFile(fileName); 113020a203aSopenharmony_ci if (fd < 0) { 114020a203aSopenharmony_ci return ""; 115020a203aSopenharmony_ci } 116020a203aSopenharmony_ci 117020a203aSopenharmony_ci FaultLogger::WriteDfxLogToFile(fd); 118020a203aSopenharmony_ci FaultLogger::WriteFaultLogToFile(fd, info.faultLogType, info.sectionMap); 119020a203aSopenharmony_ci FaultLogger::WriteLogToFile(fd, info.logPath); 120020a203aSopenharmony_ci if (info.sectionMap.count("HILOG") == 1) { 121020a203aSopenharmony_ci FileUtil::SaveStringToFd(fd, "\nHiLog:\n"); 122020a203aSopenharmony_ci FileUtil::SaveStringToFd(fd, info.sectionMap["HILOG"]); 123020a203aSopenharmony_ci } 124020a203aSopenharmony_ci FaultLogger::LimitCppCrashLog(fd, info.faultLogType); 125020a203aSopenharmony_ci close(fd); 126020a203aSopenharmony_ci 127020a203aSopenharmony_ci std::string logFile = info.logPath; 128020a203aSopenharmony_ci if (logFile != "" && FileUtil::FileExists(logFile)) { 129020a203aSopenharmony_ci if (!FileUtil::RemoveFile(logFile)) { 130020a203aSopenharmony_ci HIVIEW_LOGW("remove logFile %{public}s failed.", logFile.c_str()); 131020a203aSopenharmony_ci } else { 132020a203aSopenharmony_ci HIVIEW_LOGI("remove logFile %{public}s.", logFile.c_str()); 133020a203aSopenharmony_ci } 134020a203aSopenharmony_ci } 135020a203aSopenharmony_ci store_->ClearSameLogFilesIfNeeded(CreateLogFileFilter(0, info.id, info.faultLogType, info.module), 136020a203aSopenharmony_ci MAX_FAULT_LOG_PER_HAP); 137020a203aSopenharmony_ci info.logPath = std::string(DEFAULT_FAULTLOG_FOLDER) + fileName; 138020a203aSopenharmony_ci HIVIEW_LOGI("create log %{public}s", fileName.c_str()); 139020a203aSopenharmony_ci return fileName; 140020a203aSopenharmony_ci} 141020a203aSopenharmony_ci 142020a203aSopenharmony_cistd::list<FaultLogInfo> FaultLogManager::GetFaultInfoList(const std::string& module, 143020a203aSopenharmony_ci int32_t id, int32_t faultType, int32_t maxNum) const 144020a203aSopenharmony_ci{ 145020a203aSopenharmony_ci std::list<FaultLogInfo> ret; 146020a203aSopenharmony_ci if (faultLogDb_ != nullptr) { 147020a203aSopenharmony_ci ret = faultLogDb_->GetFaultInfoList(module, id, faultType, maxNum); 148020a203aSopenharmony_ci HIVIEW_LOGI("Find %{public}zu fault records for uid:%{public}d type:%{public}d", 149020a203aSopenharmony_ci ret.size(), id, faultType); 150020a203aSopenharmony_ci } 151020a203aSopenharmony_ci return ret; 152020a203aSopenharmony_ci} 153020a203aSopenharmony_ci 154020a203aSopenharmony_civoid FaultLogManager::SaveFaultInfoToRawDb(FaultLogInfo& info) const 155020a203aSopenharmony_ci{ 156020a203aSopenharmony_ci if (faultLogDb_ != nullptr) { 157020a203aSopenharmony_ci faultLogDb_->SaveFaultLogInfo(info); 158020a203aSopenharmony_ci } 159020a203aSopenharmony_ci} 160020a203aSopenharmony_ci 161020a203aSopenharmony_civoid FaultLogManager::ReduceLogFileListSize(std::list<std::string> &infoVec, int32_t maxNum) const 162020a203aSopenharmony_ci{ 163020a203aSopenharmony_ci if ((maxNum < 0) || (infoVec.size() <= static_cast<uint32_t>(maxNum))) { 164020a203aSopenharmony_ci return; 165020a203aSopenharmony_ci } 166020a203aSopenharmony_ci 167020a203aSopenharmony_ci auto begin = infoVec.begin(); 168020a203aSopenharmony_ci std::advance(begin, maxNum); 169020a203aSopenharmony_ci infoVec.erase(begin, infoVec.end()); 170020a203aSopenharmony_ci} 171020a203aSopenharmony_ci 172020a203aSopenharmony_cistd::list<std::string> FaultLogManager::GetFaultLogFileList(const std::string &module, time_t time, int32_t id, 173020a203aSopenharmony_ci int32_t faultType, int32_t maxNum) const 174020a203aSopenharmony_ci{ 175020a203aSopenharmony_ci LogStoreEx::LogFileFilter filter = CreateLogFileFilter(time, id, faultType, module); 176020a203aSopenharmony_ci auto vec = store_->GetLogFiles(filter); 177020a203aSopenharmony_ci std::list<std::string> ret; 178020a203aSopenharmony_ci std::transform(vec.begin(), vec.end(), std::back_inserter(ret), [](const LogFile &file) { return file.path_; }); 179020a203aSopenharmony_ci ReduceLogFileListSize(ret, maxNum); 180020a203aSopenharmony_ci return ret; 181020a203aSopenharmony_ci} 182020a203aSopenharmony_ci 183020a203aSopenharmony_cibool FaultLogManager::GetFaultLogContent(const std::string &name, std::string &content) const 184020a203aSopenharmony_ci{ 185020a203aSopenharmony_ci auto path = std::string(DEFAULT_FAULTLOG_FOLDER) + name; 186020a203aSopenharmony_ci return FileUtil::LoadStringFromFile(path, content); 187020a203aSopenharmony_ci} 188020a203aSopenharmony_ci 189020a203aSopenharmony_cibool FaultLogManager::IsProcessedFault(int32_t pid, int32_t uid, int32_t faultType) 190020a203aSopenharmony_ci{ 191020a203aSopenharmony_ci if (faultLogDb_ == nullptr) { 192020a203aSopenharmony_ci return false; 193020a203aSopenharmony_ci } 194020a203aSopenharmony_ci 195020a203aSopenharmony_ci return faultLogDb_->IsFaultExist(pid, uid, faultType); 196020a203aSopenharmony_ci} 197020a203aSopenharmony_ci} // namespace HiviewDFX 198020a203aSopenharmony_ci} // namespace OHOS 199