1 /*
2 * Copyright (c) 2022 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 "event_db_helper.h"
16
17 #include "data_query.h"
18 #include "file_util.h"
19 #include "json_parser.h"
20 #include "logger.h"
21 #include "plugin_stats_event_factory.h"
22 #include "sys_usage_event.h"
23 #include "usage_event_common.h"
24
25 namespace OHOS {
26 namespace HiviewDFX {
27 DEFINE_LOG_TAG("HiView-EventDbHelper");
28 namespace {
29 const std::string DB_DIR = "sys_event_logger/";
30 const std::string DB_NAME = "event.db";
31 const std::string PLUGIN_STATS_COLL = "plugin_stats";
32 constexpr uint32_t DEFAULT_RECORD_NUM = 1;
33 constexpr int ERR_DEFAULT = -1;
34 }
35
EventDbHelper(const std::string workPath)36 EventDbHelper::EventDbHelper(const std::string workPath) : dbPath_(workPath), storeMgr_(nullptr)
37 {
38 InitDbPath();
39 InitDbStoreMgr();
40 }
41
~EventDbHelper()42 EventDbHelper::~EventDbHelper()
43 {
44 if (CloseDocStore() < 0) {
45 HIVIEW_LOGE("fail to close db");
46 }
47 }
48
InitDbPath()49 void EventDbHelper::InitDbPath()
50 {
51 std::string workPath = this->dbPath_;
52 if (workPath.back() != '/') {
53 this->dbPath_ += "/";
54 }
55 this->dbPath_ += DB_DIR;
56 if (FileUtil::FileExists(this->dbPath_)) {
57 this->dbPath_ += DB_NAME;
58 return;
59 }
60
61 if (FileUtil::ForceCreateDirectory(this->dbPath_, FileUtil::FILE_PERM_770)) {
62 HIVIEW_LOGI("create sys_event_logger path successfully");
63 } else {
64 this->dbPath_ = workPath;
65 HIVIEW_LOGE("failed to create sys_event_logger path, use default path");
66 }
67 this->dbPath_ += DB_NAME;
68 }
69
InitDbStoreMgr()70 void EventDbHelper::InitDbStoreMgr()
71 {
72 this->storeMgr_ = std::make_unique<StoreManager>();
73 }
74
GetDocStore()75 std::shared_ptr<DocStore> EventDbHelper::GetDocStore()
76 {
77 Option option;
78 option.db = this->dbPath_;
79 option.flag = Option::NO_TRIM_ON_CLOSE;
80 return this->storeMgr_->GetDocStore(option);
81 }
82
CloseDocStore()83 int EventDbHelper::CloseDocStore()
84 {
85 Option option;
86 option.db = this->dbPath_;
87 return this->storeMgr_->CloseDocStore(option);
88 }
89
InsertPluginStatsEvent(const std::shared_ptr<LoggerEvent> & event)90 int EventDbHelper::InsertPluginStatsEvent(const std::shared_ptr<LoggerEvent>& event)
91 {
92 if (event == nullptr) {
93 return ERR_DEFAULT;
94 }
95 std::vector<std::shared_ptr<LoggerEvent>> queryEvents;
96 std::string pluginName = event->GetValue(PluginStatsEventSpace::KEY_OF_PLUGIN_NAME).GetString();
97 int queryRes = QueryPluginStatsEvent(queryEvents, pluginName);
98 if (queryRes >= 0 && queryEvents.size() == DEFAULT_RECORD_NUM) {
99 return UpdateDb(queryRes, event->ToJsonString(), PLUGIN_STATS_COLL);
100 } else {
101 return InsertDb(event->ToJsonString(), PLUGIN_STATS_COLL);
102 }
103 }
104
InsertSysUsageEvent(const std::shared_ptr<LoggerEvent> & event,const std::string & coll)105 int EventDbHelper::InsertSysUsageEvent(const std::shared_ptr<LoggerEvent>& event, const std::string& coll)
106 {
107 if (event == nullptr) {
108 return ERR_DEFAULT;
109 }
110 std::vector<std::shared_ptr<LoggerEvent>> queryEvents;
111 int queryRes = QuerySysUsageEvent(queryEvents, coll);
112 if (queryRes >= 0 && queryEvents.size() == DEFAULT_RECORD_NUM) {
113 return UpdateDb(queryRes, event->ToJsonString(), coll);
114 } else {
115 return InsertDb(event->ToJsonString(), coll);
116 }
117 }
118
InsertDb(const std::string & jsonStr,const std::string & coll)119 int EventDbHelper::InsertDb(const std::string& jsonStr, const std::string& coll)
120 {
121 HIVIEW_LOGD("insert db file %{public}s with %{public}s", this->dbPath_.c_str(), jsonStr.c_str());
122 auto docStore = GetDocStore();
123 Entry entry;
124 entry.id = 0;
125 entry.value = jsonStr;
126 if (docStore->Put(entry, coll.c_str()) != 0) {
127 HIVIEW_LOGE("failed to insert collection %{public}s for %{public}s", coll.c_str(), jsonStr.c_str());
128 return ERR_DEFAULT;
129 }
130 return entry.id;
131 }
132
BuildQuery(DataQuery & query,const std::map<std::string,std::string> & condMap)133 void EventDbHelper::BuildQuery(DataQuery& query, const std::map<std::string, std::string>& condMap)
134 {
135 for (auto& cond : condMap) {
136 query.EqualTo(cond.first, cond.second);
137 }
138 }
139
QueryPluginStatsEvent(std::vector<std::shared_ptr<LoggerEvent>> & events,const std::string & pluginName)140 int EventDbHelper::QueryPluginStatsEvent(std::vector<std::shared_ptr<LoggerEvent>>& events,
141 const std::string& pluginName)
142 {
143 std::map<std::string, std::string> condMap;
144 if (!pluginName.empty()) {
145 condMap = { {PluginStatsEventSpace::KEY_OF_PLUGIN_NAME, pluginName} };
146 }
147 DataQuery query;
148 BuildQuery(query, condMap);
149 std::vector<Entry> entries;
150 int res = QueryDb(query, entries, PLUGIN_STATS_COLL);
151 if (res < 0) {
152 return res;
153 }
154 auto factory = std::make_unique<PluginStatsEventFactory>();
155 for (auto entry : entries) {
156 res = entry.id;
157 std::shared_ptr<LoggerEvent> event = factory->Create();
158 if (!JsonParser::ParsePluginStatsEvent(event, entry.value)) {
159 HIVIEW_LOGE("failed to parse the database records=%{public}s", entry.value.c_str());
160 continue;
161 }
162 events.push_back(event);
163 }
164 HIVIEW_LOGI("query plugin_stats result=%{public}d, events size=%{public}zu", res, entries.size());
165 return events.size() == DEFAULT_RECORD_NUM ? res : static_cast<int>(events.size());
166 }
167
QuerySysUsageEvent(std::vector<std::shared_ptr<LoggerEvent>> & events,const std::string & coll)168 int EventDbHelper::QuerySysUsageEvent(std::vector<std::shared_ptr<LoggerEvent>>& events, const std::string& coll)
169 {
170 using namespace SysUsageEventSpace;
171
172 std::vector<Entry> entries;
173 int res = QueryDb(DataQuery(), entries, coll);
174 if (res < 0) {
175 return res;
176 }
177 for (auto entry : entries) {
178 res = entry.id;
179 std::shared_ptr<LoggerEvent> event =
180 std::make_shared<SysUsageEvent>(EVENT_DOMAIN, EVENT_NAME, HiSysEvent::STATISTIC);
181 if (!JsonParser::ParseSysUsageEvent(event, entries[0].value)) {
182 HIVIEW_LOGE("failed to parse the database records=%{public}s", entries[0].value.c_str());
183 continue;
184 }
185 events.push_back(event);
186 }
187 HIVIEW_LOGI("query sys_usage result=%{public}d, events size=%{public}zu", res, entries.size());
188 return events.size() == DEFAULT_RECORD_NUM ? res : static_cast<int>(events.size());
189 }
190
QueryDb(const DataQuery & query,std::vector<Entry> & entries,const std::string & coll)191 int EventDbHelper::QueryDb(const DataQuery& query, std::vector<Entry>& entries, const std::string& coll)
192 {
193 return GetDocStore()->GetEntriesWithQuery(query, entries, coll.c_str());
194 }
195
UpdateDb(int id,const std::string & value,const std::string & coll)196 int EventDbHelper::UpdateDb(int id, const std::string& value, const std::string& coll)
197 {
198 HIVIEW_LOGD("update db coll %{public}s with %{public}s", coll.c_str(), value.c_str());
199 Entry entry;
200 entry.id = id;
201 entry.value = value;
202 return GetDocStore()->Merge(entry, coll.c_str());
203 }
204
DeletePluginStatsEvent()205 int EventDbHelper::DeletePluginStatsEvent()
206 {
207 return DeleteDb(DataQuery(), PLUGIN_STATS_COLL);
208 }
209
DeleteSysUsageEvent(const std::string & coll)210 int EventDbHelper::DeleteSysUsageEvent(const std::string& coll)
211 {
212 return DeleteDb(DataQuery(), coll);
213 }
214
DeleteDb(const DataQuery & query,const std::string & coll)215 int EventDbHelper::DeleteDb(const DataQuery& query, const std::string& coll)
216 {
217 HIVIEW_LOGD("delete db coll %{public}s", coll.c_str());
218 return GetDocStore()->Delete(query, coll.c_str());
219 }
220 } // namespace HiviewDFX
221 } // namespace OHOS
222