1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (c) 2021 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_database.h" 16020a203aSopenharmony_ci 17020a203aSopenharmony_ci#include <algorithm> 18020a203aSopenharmony_ci#include <cinttypes> 19020a203aSopenharmony_ci#include <list> 20020a203aSopenharmony_ci#include <mutex> 21020a203aSopenharmony_ci#include <string> 22020a203aSopenharmony_ci 23020a203aSopenharmony_ci#include "faultlog_info.h" 24020a203aSopenharmony_ci#include "faultlog_util.h" 25020a203aSopenharmony_ci#include "hisysevent.h" 26020a203aSopenharmony_ci#include "hiview_global.h" 27020a203aSopenharmony_ci#include "hiview_logger.h" 28020a203aSopenharmony_ci#include "log_analyzer.h" 29020a203aSopenharmony_ci#include "string_util.h" 30020a203aSopenharmony_ci#include "sys_event_dao.h" 31020a203aSopenharmony_ci#include "time_util.h" 32020a203aSopenharmony_ci 33020a203aSopenharmony_ci#include "decoded/decoded_event.h" 34020a203aSopenharmony_ci 35020a203aSopenharmony_ciusing namespace std; 36020a203aSopenharmony_cinamespace OHOS { 37020a203aSopenharmony_cinamespace HiviewDFX { 38020a203aSopenharmony_ciDEFINE_LOG_LABEL(0xD002D11, "FaultLogDatabase"); 39020a203aSopenharmony_cinamespace { 40020a203aSopenharmony_cistatic const std::vector<std::string> QUERY_ITEMS = { 41020a203aSopenharmony_ci "time_", "name_", "uid_", "pid_", "MODULE", "REASON", "SUMMARY", "LOG_PATH", "FAULT_TYPE" 42020a203aSopenharmony_ci}; 43020a203aSopenharmony_cistatic const std::string LOG_PATH_BASE = "/data/log/faultlog/faultlogger/"; 44020a203aSopenharmony_cibool ParseFaultLogInfoFromJson(std::shared_ptr<EventRaw::RawData> rawData, FaultLogInfo& info) 45020a203aSopenharmony_ci{ 46020a203aSopenharmony_ci if (rawData == nullptr) { 47020a203aSopenharmony_ci HIVIEW_LOGE("raw data of sys event is null."); 48020a203aSopenharmony_ci return false; 49020a203aSopenharmony_ci } 50020a203aSopenharmony_ci auto sysEvent = std::make_unique<SysEvent>("FaultLogDatabase", nullptr, rawData); 51020a203aSopenharmony_ci constexpr string::size_type FIRST_200_BYTES = 200; 52020a203aSopenharmony_ci HIVIEW_LOGI("parse FaultLogInfo from %{public}s.", sysEvent->AsJsonStr().substr(0, FIRST_200_BYTES).c_str()); 53020a203aSopenharmony_ci constexpr int64_t DEFAULT_INT_VALUE = 0; 54020a203aSopenharmony_ci info.time = static_cast<int64_t>(std::atoll(sysEvent->GetEventValue("HAPPEN_TIME").c_str())); 55020a203aSopenharmony_ci if (info.time == DEFAULT_INT_VALUE) { 56020a203aSopenharmony_ci info.time = sysEvent->GetEventIntValue("HAPPEN_TIME") != DEFAULT_INT_VALUE? 57020a203aSopenharmony_ci sysEvent->GetEventIntValue("HAPPEN_TIME") : sysEvent->GetEventIntValue("time_"); 58020a203aSopenharmony_ci } 59020a203aSopenharmony_ci info.pid = sysEvent->GetEventIntValue("PID") != DEFAULT_INT_VALUE ? 60020a203aSopenharmony_ci sysEvent->GetEventIntValue("PID") : sysEvent->GetEventIntValue("pid_"); 61020a203aSopenharmony_ci 62020a203aSopenharmony_ci info.id = sysEvent->GetEventIntValue("UID") != DEFAULT_INT_VALUE ? 63020a203aSopenharmony_ci sysEvent->GetEventIntValue("UID") : sysEvent->GetEventIntValue("uid_"); 64020a203aSopenharmony_ci info.faultLogType = std::atoi(sysEvent->GetEventValue("FAULT_TYPE").c_str()); 65020a203aSopenharmony_ci info.module = sysEvent->GetEventValue("MODULE"); 66020a203aSopenharmony_ci info.reason = sysEvent->GetEventValue("REASON"); 67020a203aSopenharmony_ci info.summary = StringUtil::UnescapeJsonStringValue(sysEvent->GetEventValue("SUMMARY")); 68020a203aSopenharmony_ci info.logPath = LOG_PATH_BASE + GetFaultLogName(info); 69020a203aSopenharmony_ci return true; 70020a203aSopenharmony_ci} 71020a203aSopenharmony_ci} 72020a203aSopenharmony_ci 73020a203aSopenharmony_ciFaultLogDatabase::FaultLogDatabase(const std::shared_ptr<EventLoop>& eventLoop) : eventLoop_(eventLoop) {} 74020a203aSopenharmony_ci 75020a203aSopenharmony_civoid FaultLogDatabase::SaveFaultLogInfo(FaultLogInfo& info) 76020a203aSopenharmony_ci{ 77020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 78020a203aSopenharmony_ci if (info.faultLogType == FaultLogType::SYS_FREEZE) { 79020a203aSopenharmony_ci AnalysisFaultlog(info, info.parsedLogInfo); 80020a203aSopenharmony_ci for (const auto& logInfo : info.parsedLogInfo) { 81020a203aSopenharmony_ci info.sectionMap[logInfo.first] = logInfo.second; 82020a203aSopenharmony_ci } 83020a203aSopenharmony_ci info.parsedLogInfo.clear(); 84020a203aSopenharmony_ci } 85020a203aSopenharmony_ci if (!eventLoop_) { 86020a203aSopenharmony_ci HIVIEW_LOGE("eventLoop_ is not inited."); 87020a203aSopenharmony_ci return; 88020a203aSopenharmony_ci } 89020a203aSopenharmony_ci auto task = [info] () mutable { 90020a203aSopenharmony_ci HiSysEventWrite( 91020a203aSopenharmony_ci HiSysEvent::Domain::RELIABILITY, 92020a203aSopenharmony_ci GetFaultNameByType(info.faultLogType, false), 93020a203aSopenharmony_ci HiSysEvent::EventType::FAULT, 94020a203aSopenharmony_ci "FAULT_TYPE", std::to_string(info.faultLogType), 95020a203aSopenharmony_ci "PID", info.pid, 96020a203aSopenharmony_ci "UID", info.id, 97020a203aSopenharmony_ci "MODULE", info.module, 98020a203aSopenharmony_ci "REASON", info.reason, 99020a203aSopenharmony_ci "SUMMARY", info.summary, 100020a203aSopenharmony_ci "LOG_PATH", info.logPath, 101020a203aSopenharmony_ci "VERSION", info.sectionMap.find("VERSION") != info.sectionMap.end() ? info.sectionMap.at("VERSION") : "", 102020a203aSopenharmony_ci "PRE_INSTALL", info.sectionMap["PRE_INSTALL"], 103020a203aSopenharmony_ci "FOREGROUND", info.sectionMap["FOREGROUND"], 104020a203aSopenharmony_ci "HAPPEN_TIME", info.time, 105020a203aSopenharmony_ci "HITRACE_TIME", info.sectionMap.find("HITRACE_TIME") != info.sectionMap.end() ? 106020a203aSopenharmony_ci info.sectionMap.at("HITRACE_TIME") : "", 107020a203aSopenharmony_ci "SYSRQ_TIME", info.sectionMap.find("SYSRQ_TIME") != info.sectionMap.end() ? 108020a203aSopenharmony_ci info.sectionMap.at("SYSRQ_TIME") : "", 109020a203aSopenharmony_ci "PNAME", info.sectionMap["PROCESS_NAME"].empty() ? "/" : info.sectionMap["PROCESS_NAME"], 110020a203aSopenharmony_ci "FIRST_FRAME", info.sectionMap["FIRST_FRAME"].empty() ? "/" : info.sectionMap["FIRST_FRAME"], 111020a203aSopenharmony_ci "SECOND_FRAME", info.sectionMap["SECOND_FRAME"].empty() ? "/" : info.sectionMap["SECOND_FRAME"], 112020a203aSopenharmony_ci "LAST_FRAME", info.sectionMap["LAST_FRAME"].empty() ? "/" : info.sectionMap["LAST_FRAME"], 113020a203aSopenharmony_ci "FINGERPRINT", info.sectionMap["fingerPrint"].empty() ? "/" : info.sectionMap["fingerPrint"], 114020a203aSopenharmony_ci "STACK", info.sectionMap["STACK"].empty() ? "" : info.sectionMap["STACK"] 115020a203aSopenharmony_ci ); 116020a203aSopenharmony_ci }; 117020a203aSopenharmony_ci constexpr int delayTime = 2; 118020a203aSopenharmony_ci eventLoop_->AddTimerEvent(nullptr, nullptr, task, delayTime, false); 119020a203aSopenharmony_ci} 120020a203aSopenharmony_ci 121020a203aSopenharmony_cistd::list<std::shared_ptr<EventStore::SysEventQuery>> CreateQueries( 122020a203aSopenharmony_ci int32_t faultType, EventStore::Cond upperCaseCond, EventStore::Cond lowerCaseCond) 123020a203aSopenharmony_ci{ 124020a203aSopenharmony_ci std::list<std::shared_ptr<EventStore::SysEventQuery>> queries; 125020a203aSopenharmony_ci if (faultType == FaultLogType::JS_CRASH || faultType == FaultLogType::ALL) { 126020a203aSopenharmony_ci std::vector<std::string> faultNames = { "JS_ERROR" }; 127020a203aSopenharmony_ci std::vector<std::string> domains = { HiSysEvent::Domain::ACE, HiSysEvent::Domain::AAFWK }; 128020a203aSopenharmony_ci for (std::string domain : domains) { 129020a203aSopenharmony_ci auto query = EventStore::SysEventDao::BuildQuery(domain, faultNames); 130020a203aSopenharmony_ci if (query == nullptr) { 131020a203aSopenharmony_ci continue; 132020a203aSopenharmony_ci } 133020a203aSopenharmony_ci query->And(lowerCaseCond); 134020a203aSopenharmony_ci query->Select(QUERY_ITEMS).Order("time_", false); 135020a203aSopenharmony_ci queries.push_back(query); 136020a203aSopenharmony_ci } 137020a203aSopenharmony_ci } 138020a203aSopenharmony_ci if (faultType != FaultLogType::JS_CRASH) { 139020a203aSopenharmony_ci std::string faultName = GetFaultNameByType(faultType, false); 140020a203aSopenharmony_ci std::vector<std::vector<std::string>> faultNames = { {faultName} }; 141020a203aSopenharmony_ci if (faultType == FaultLogType::ALL) { 142020a203aSopenharmony_ci faultNames = { {"CPP_CRASH"}, {"APP_FREEZE"}}; 143020a203aSopenharmony_ci } 144020a203aSopenharmony_ci for (auto name : faultNames) { 145020a203aSopenharmony_ci auto query = EventStore::SysEventDao::BuildQuery(HiSysEvent::Domain::RELIABILITY, name); 146020a203aSopenharmony_ci if (query == nullptr) { 147020a203aSopenharmony_ci continue; 148020a203aSopenharmony_ci } 149020a203aSopenharmony_ci query->And(upperCaseCond); 150020a203aSopenharmony_ci query->Select(QUERY_ITEMS).Order("time_", false); 151020a203aSopenharmony_ci queries.push_back(query); 152020a203aSopenharmony_ci } 153020a203aSopenharmony_ci } 154020a203aSopenharmony_ci return queries; 155020a203aSopenharmony_ci} 156020a203aSopenharmony_ci 157020a203aSopenharmony_cistd::list<FaultLogInfo> FaultLogDatabase::GetFaultInfoList(const std::string& module, int32_t id, 158020a203aSopenharmony_ci int32_t faultType, int32_t maxNum) 159020a203aSopenharmony_ci{ 160020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 161020a203aSopenharmony_ci std::list<FaultLogInfo> queryResult; 162020a203aSopenharmony_ci if (faultType < FaultLogType::ALL || faultType > FaultLogType::APP_FREEZE) { 163020a203aSopenharmony_ci HIVIEW_LOGE("Unsupported fault type, please check it!"); 164020a203aSopenharmony_ci return queryResult; 165020a203aSopenharmony_ci } 166020a203aSopenharmony_ci EventStore::Cond hiviewUidCond("uid_", EventStore::Op::EQ, static_cast<int64_t>(getuid())); 167020a203aSopenharmony_ci EventStore::Cond uidUpperCond = hiviewUidCond.And("UID", EventStore::Op::EQ, id); 168020a203aSopenharmony_ci EventStore::Cond uidLowerCond("uid_", EventStore::Op::EQ, id); 169020a203aSopenharmony_ci auto queries = CreateQueries(faultType, uidUpperCond, uidLowerCond); 170020a203aSopenharmony_ci for (auto query : queries) { 171020a203aSopenharmony_ci if (id != 0) { 172020a203aSopenharmony_ci query->And("MODULE", EventStore::Op::EQ, module); 173020a203aSopenharmony_ci } 174020a203aSopenharmony_ci EventStore::ResultSet resultSet = query->Execute(maxNum); 175020a203aSopenharmony_ci while (resultSet.HasNext()) { 176020a203aSopenharmony_ci auto it = resultSet.Next(); 177020a203aSopenharmony_ci FaultLogInfo info; 178020a203aSopenharmony_ci if (!ParseFaultLogInfoFromJson(it->rawData_, info)) { 179020a203aSopenharmony_ci HIVIEW_LOGI("Failed to parse FaultLogInfo from queryResult."); 180020a203aSopenharmony_ci continue; 181020a203aSopenharmony_ci } 182020a203aSopenharmony_ci queryResult.push_back(info); 183020a203aSopenharmony_ci } 184020a203aSopenharmony_ci } 185020a203aSopenharmony_ci if (queries.size() > 1) { 186020a203aSopenharmony_ci queryResult.sort( 187020a203aSopenharmony_ci [](const FaultLogInfo& a, const FaultLogInfo& b) { 188020a203aSopenharmony_ci return a.time > b.time; 189020a203aSopenharmony_ci }); 190020a203aSopenharmony_ci if (queryResult.size() > static_cast<size_t>(maxNum)) { 191020a203aSopenharmony_ci queryResult.resize(maxNum); 192020a203aSopenharmony_ci } 193020a203aSopenharmony_ci } 194020a203aSopenharmony_ci 195020a203aSopenharmony_ci return queryResult; 196020a203aSopenharmony_ci} 197020a203aSopenharmony_ci 198020a203aSopenharmony_cibool FaultLogDatabase::IsFaultExist(int32_t pid, int32_t uid, int32_t faultType) 199020a203aSopenharmony_ci{ 200020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 201020a203aSopenharmony_ci if (faultType < FaultLogType::ALL || faultType > FaultLogType::RUST_PANIC) { 202020a203aSopenharmony_ci HIVIEW_LOGE("Unsupported fault type, please check it!"); 203020a203aSopenharmony_ci return false; 204020a203aSopenharmony_ci } 205020a203aSopenharmony_ci EventStore::Cond hiviewUidCond("uid_", EventStore::Op::EQ, static_cast<int64_t>(getuid())); 206020a203aSopenharmony_ci EventStore::Cond pidUpperCond = hiviewUidCond.And("PID", EventStore::Op::EQ, pid). 207020a203aSopenharmony_ci And("UID", EventStore::Op::EQ, uid); 208020a203aSopenharmony_ci EventStore::Cond pidLowerCond("pid_", EventStore::Op::EQ, pid); 209020a203aSopenharmony_ci pidLowerCond = pidLowerCond.And("uid_", EventStore::Op::EQ, uid); 210020a203aSopenharmony_ci auto queries = CreateQueries(faultType, pidUpperCond, pidLowerCond); 211020a203aSopenharmony_ci for (auto query : queries) { 212020a203aSopenharmony_ci if (query->Execute(1).HasNext()) { 213020a203aSopenharmony_ci return true; 214020a203aSopenharmony_ci } 215020a203aSopenharmony_ci } 216020a203aSopenharmony_ci return false; 217020a203aSopenharmony_ci} 218020a203aSopenharmony_ci} // namespace HiviewDFX 219020a203aSopenharmony_ci} // namespace OHOS 220