• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "faultlog_database.h"
16 
17 #include <algorithm>
18 #include <cinttypes>
19 #include <list>
20 #include <mutex>
21 #include <string>
22 
23 #include "faultlog_info.h"
24 #include "faultlog_util.h"
25 #include "hisysevent.h"
26 #include "hiview_global.h"
27 #include "logger.h"
28 #include "log_analyzer.h"
29 #include "string_util.h"
30 #include "sys_event.h"
31 #include "sys_event_dao.h"
32 #include "time_util.h"
33 
34 using namespace std;
35 namespace OHOS {
36 namespace HiviewDFX {
37 DEFINE_LOG_TAG("FaultLogDatabase");
38 namespace {
39 static const std::vector<std::string> QUERY_ITEMS =
40     { "time_", "name_", "uid_", "pid_", "MODULE", "REASON", "SUMMARY", "LOG_PATH", "FAULT_TYPE" };
41 static const std::string LOG_PATH_BASE = "/data/log/faultlog/faultlogger/";
ParseFaultLogInfoFromJson(const std::string & jsonStr,FaultLogInfo & info)42 bool ParseFaultLogInfoFromJson(const std::string& jsonStr, FaultLogInfo& info)
43 {
44     auto sysEvent = std::make_unique<SysEvent>("FaultLogDatabase", nullptr, jsonStr);
45     HIVIEW_LOGI("parse FaultLogInfo from %{public}s. 0", jsonStr.c_str());
46     if (sysEvent->ParseJson() < 0) {
47         HIVIEW_LOGI("Failed to parse FaultLogInfo from queryResult.");
48         return false;
49     }
50     info.time = static_cast<int64_t>(std::atoll(sysEvent->GetEventValue("HAPPEN_TIME").c_str()));
51     if (info.time == 0) {
52         info.time = sysEvent->GetEventIntValue("HAPPEN_TIME");
53     }
54     info.pid = sysEvent->GetEventIntValue("PID");
55     if (info.pid == 0) {
56         info.pid = sysEvent->GetEventIntValue("pid_");
57     }
58     info.id = sysEvent->GetEventIntValue("UID");
59     if (info.id == 0) {
60         info.id = sysEvent->GetEventIntValue("uid_");
61     }
62     info.faultLogType = std::atoi(sysEvent->GetEventValue("FAULT_TYPE").c_str());
63     info.module = sysEvent->GetEventValue("MODULE");
64     info.reason = sysEvent->GetEventValue("REASON");
65     info.summary = StringUtil::UnescapeJsonStringValue(sysEvent->GetEventValue("SUMMARY"));
66     info.logPath = LOG_PATH_BASE + GetFaultLogName(info);
67     return true;
68 }
69 }
70 
SaveFaultLogInfo(FaultLogInfo & info)71 void FaultLogDatabase::SaveFaultLogInfo(FaultLogInfo& info)
72 {
73     std::lock_guard<std::mutex> lock(mutex_);
74     std::map<std::string, std::string> eventInfos;
75     AnalysisFaultlog(info, eventInfos);
76     HiSysEvent::Write("RELIABILITY", GetFaultNameByType(info.faultLogType, false), HiSysEvent::EventType::FAULT,
77         "FAULT_TYPE", std::to_string(info.faultLogType),
78         "PID", info.pid,
79         "UID", info.id,
80         "MODULE", info.module,
81         "REASON", info.reason,
82         "SUMMARY", info.summary,
83         "LOG_PATH", info.logPath,
84         "VERSION", info.sectionMap.find("VERSION") != info.sectionMap.end() ? info.sectionMap.at("VERSION") : "",
85         "HAPPEN_TIME", std::to_string(info.time),
86         "PNAME", eventInfos["PNAME"].empty() ? "/" : eventInfos["PNAME"],
87         "FIRST_FRAME", eventInfos["FIRST_FRAME"].empty() ? "/" : eventInfos["FIRST_FRAME"],
88         "SECOND_FRAME", eventInfos["SECOND_FRAME"].empty() ? "/" : eventInfos["SECOND_FRAME"],
89         "LAST_FRAME", eventInfos["LAST_FRAME"].empty() ? "/" : eventInfos["LAST_FRAME"],
90         "FINGERPRINT", eventInfos["fingerPrint"].empty() ? "/" : eventInfos["fingerPrint"]
91     );
92 }
93 
GetFaultInfoList(const std::string & module,int32_t id,int32_t faultType,int32_t maxNum)94 std::list<FaultLogInfo> FaultLogDatabase::GetFaultInfoList(const std::string& module, int32_t id,
95     int32_t faultType, int32_t maxNum)
96 {
97     std::lock_guard<std::mutex> lock(mutex_);
98     std::list<FaultLogInfo> queryResult;
99     auto query = EventStore::SysEventDao::BuildQuery(EventStore::StoreType::FAULT);
100     EventStore::Cond uidCond("UID", EventStore::Op::EQ, id);
101     EventStore::Cond hiviewCond("uid_", EventStore::Op::EQ, static_cast<int64_t>(getuid()));
102     EventStore::Cond condLeft = uidCond.And(hiviewCond);
103     EventStore::Cond condRight("uid_", EventStore::Op::EQ, id);
104     EventStore::Cond condTotal;
105     if (faultType == FaultLogType::CPP_CRASH || faultType == FaultLogType::APP_FREEZE) {
106         condTotal = condLeft;
107     } else if (faultType == FaultLogType::JS_CRASH) {
108         condTotal = condRight;
109     } else {
110         condTotal = condLeft.Or(condRight);
111     }
112     (*query).Select(QUERY_ITEMS).Where(condTotal).Order("time_", false);
113     if (id != 0) {
114         query->And("MODULE", EventStore::Op::EQ, module);
115     }
116 
117     if (faultType != 0) {
118         query->And("FAULT_TYPE", EventStore::Op::EQ, faultType);
119     }
120 
121     EventStore::ResultSet resultSet = query->Execute(maxNum);
122     while (resultSet.HasNext()) {
123         auto it = resultSet.Next();
124         FaultLogInfo info;
125         if (!ParseFaultLogInfoFromJson(it->jsonExtraInfo_, info)) {
126             HIVIEW_LOGI("Failed to parse FaultLogInfo from queryResult.");
127             continue;
128         }
129         queryResult.push_back(info);
130     }
131     return queryResult;
132 }
133 
IsFaultExist(int32_t pid,int32_t uid,int32_t faultType)134 bool FaultLogDatabase::IsFaultExist(int32_t pid, int32_t uid, int32_t faultType)
135 {
136     std::lock_guard<std::mutex> lock(mutex_);
137     auto query = EventStore::SysEventDao::BuildQuery(EventStore::StoreType::FAULT);
138     EventStore::Cond pidUpperCond("PID", EventStore::Op::EQ, pid);
139     EventStore::Cond pidLowerCond("pid_", EventStore::Op::EQ, pid);
140     EventStore::Cond uidUpperCond("UID", EventStore::Op::EQ, uid);
141     EventStore::Cond uidLowerCond("uid_", EventStore::Op::EQ, uid);
142     EventStore::Cond hiviewCond("uid_", EventStore::Op::EQ, static_cast<int64_t>(getuid()));
143     EventStore::Cond typeCond("FAULT_TYPE", EventStore::Op::EQ, faultType);
144     EventStore::Cond condLeft = hiviewCond.And(pidUpperCond).And(uidUpperCond).And(typeCond);
145     EventStore::Cond condRight = pidLowerCond.And(uidLowerCond).And(typeCond);
146     EventStore::Cond condTotal;
147     if (faultType == FaultLogType::CPP_CRASH || faultType == FaultLogType::APP_FREEZE) {
148         condTotal = condLeft;
149     } else if (faultType == FaultLogType::JS_CRASH) {
150         condTotal = condRight;
151     } else {
152         condTotal = condLeft.Or(condRight);
153     }
154     (*query).Select(QUERY_ITEMS).Where(condTotal).Order("time_", false);
155     return query->Execute(1).HasNext();
156 }
157 }  // namespace HiviewDFX
158 }  // namespace OHOS
159