1 /*
2 * Copyright (c) 2022-2023 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 "file_util.h"
18 #include "json_parser.h"
19 #include "hiview_logger.h"
20 #include "plugin_stats_event_factory.h"
21 #include "sql_util.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 DB_COLUMIN_EVNET = "event";
32 const std::string DB_COLUMIN_PLUGIN = "plugin";
33 const std::string DB_TABLE_PLUGIN_STATS = "plugin_stats";
34 const char SQL_TEXT_TYPE[] = "TEXT NOT NULL";
35 constexpr int DB_VERSION = 1;
36 }
37
OnCreate(NativeRdb::RdbStore & rdbStore)38 int EventDbStoreCallback::OnCreate(NativeRdb::RdbStore& rdbStore)
39 {
40 HIVIEW_LOGD("create dbStore");
41 return NativeRdb::E_OK;
42 }
43
OnUpgrade(NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)44 int EventDbStoreCallback::OnUpgrade(NativeRdb::RdbStore& rdbStore, int oldVersion, int newVersion)
45 {
46 HIVIEW_LOGD("oldVersion=%{public}d, newVersion=%{public}d", oldVersion, newVersion);
47 return NativeRdb::E_OK;
48 }
49
EventDbHelper(const std::string workPath)50 EventDbHelper::EventDbHelper(const std::string workPath) : dbPath_(workPath), rdbStore_(nullptr)
51 {
52 InitDbStore();
53 }
54
~EventDbHelper()55 EventDbHelper::~EventDbHelper()
56 {}
57
InitDbStore()58 void EventDbHelper::InitDbStore()
59 {
60 std::string workPath = dbPath_;
61 if (workPath.back() != '/') {
62 dbPath_ += "/";
63 }
64 dbPath_ += DB_DIR;
65 if (!FileUtil::FileExists(dbPath_)) {
66 if (FileUtil::ForceCreateDirectory(dbPath_, FileUtil::FILE_PERM_770)) {
67 HIVIEW_LOGI("create sys_event_logger path successfully");
68 } else {
69 dbPath_ = workPath;
70 HIVIEW_LOGE("failed to create sys_event_logger path, use default path");
71 }
72 }
73 dbPath_ += DB_NAME;
74
75 NativeRdb::RdbStoreConfig config(dbPath_);
76 config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
77 EventDbStoreCallback callback;
78 int ret = NativeRdb::E_OK;
79 rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(config, DB_VERSION, callback, ret);
80 if (ret != NativeRdb::E_OK || rdbStore_ == nullptr) {
81 HIVIEW_LOGE("failed to create db store, ret=%{public}d", ret);
82 }
83 }
84
InsertPluginStatsEvent(std::shared_ptr<LoggerEvent> event)85 int EventDbHelper::InsertPluginStatsEvent(std::shared_ptr<LoggerEvent> event)
86 {
87 if (event == nullptr) {
88 HIVIEW_LOGI("event is null");
89 return -1;
90 }
91 if (rdbStore_ == nullptr) {
92 HIVIEW_LOGE("dbStore is null");
93 return -1;
94 }
95 std::vector<std::shared_ptr<LoggerEvent>> oldEvents;
96 std::string pluginName = event->GetValue(PluginStatsEventSpace::KEY_OF_PLUGIN_NAME).GetString();
97 return QueryPluginStatsEvent(oldEvents, pluginName) != 0 ?
98 InsertPluginStatsTable(pluginName, event->ToJsonString()) :
99 UpdatePluginStatsTable(pluginName, event->ToJsonString());
100 }
101
InsertSysUsageEvent(std::shared_ptr<LoggerEvent> event,const std::string & table)102 int EventDbHelper::InsertSysUsageEvent(std::shared_ptr<LoggerEvent> event, const std::string& table)
103 {
104 if (event == nullptr) {
105 HIVIEW_LOGI("event is null");
106 return -1;
107 }
108 if (rdbStore_ == nullptr) {
109 HIVIEW_LOGE("dbStore is null");
110 return -1;
111 }
112 std::shared_ptr<LoggerEvent> oldEvent = nullptr;
113 return QuerySysUsageEvent(oldEvent, table) != 0 ?
114 InsertSysUsageTable(table, event->ToJsonString()) :
115 UpdateSysUsageTable(table, event->ToJsonString());
116 }
117
QueryPluginStatsEvent(std::vector<std::shared_ptr<LoggerEvent>> & events,const std::string & pluginName)118 int EventDbHelper::QueryPluginStatsEvent(std::vector<std::shared_ptr<LoggerEvent>>& events,
119 const std::string& pluginName)
120 {
121 if (rdbStore_ == nullptr) {
122 HIVIEW_LOGE("dbStore is null");
123 return -1;
124 }
125
126 std::vector<std::string> eventStrs;
127 if (QueryPluginStatsTable(eventStrs, pluginName) != 0 || eventStrs.empty()) {
128 HIVIEW_LOGI("failed to query pluginStats table, pluginName=%{public}s", pluginName.c_str());
129 return -1;
130 }
131 auto factory = std::make_unique<PluginStatsEventFactory>();
132 for (auto eventStr : eventStrs) {
133 std::shared_ptr<LoggerEvent> event = factory->Create();
134 if (!JsonParser::ParsePluginStatsEvent(event, eventStr)) {
135 HIVIEW_LOGE("failed to parse the database records=%{public}s", eventStr.c_str());
136 continue;
137 }
138 events.push_back(event);
139 }
140 HIVIEW_LOGI("query plugin_stats events size=%{public}zu", events.size());
141 return 0;
142 }
143
QuerySysUsageEvent(std::shared_ptr<LoggerEvent> & event,const std::string & table)144 int EventDbHelper::QuerySysUsageEvent(std::shared_ptr<LoggerEvent>& event, const std::string& table)
145 {
146 if (rdbStore_ == nullptr) {
147 HIVIEW_LOGE("dbStore is null");
148 return -1;
149 }
150 std::string eventStr;
151 if (QuerySysUsageTable(eventStr, table) != 0 || eventStr.empty()) {
152 HIVIEW_LOGD("failed to query sysUsage table=%{public}s", table.c_str());
153 return -1;
154 }
155 event = std::make_shared<SysUsageEvent>(SysUsageEventSpace::EVENT_NAME, HiSysEvent::STATISTIC);
156 if (!JsonParser::ParseSysUsageEvent(event, eventStr)) {
157 HIVIEW_LOGE("failed to parse the database record=%{public}s", eventStr.c_str());
158 return -1;
159 }
160 return 0;
161 }
162
DeletePluginStatsEvent()163 int EventDbHelper::DeletePluginStatsEvent()
164 {
165 if (rdbStore_ == nullptr) {
166 HIVIEW_LOGE("dbStore is null");
167 return -1;
168 }
169 return DeleteTableData(DB_TABLE_PLUGIN_STATS);
170 }
171
DeleteSysUsageEvent(const std::string & table)172 int EventDbHelper::DeleteSysUsageEvent(const std::string& table)
173 {
174 if (rdbStore_ == nullptr) {
175 HIVIEW_LOGE("dbStore is null");
176 return -1;
177 }
178 return DeleteTableData(table);
179 }
180
CreateTable(const std::string & table,const std::vector<std::pair<std::string,std::string>> & fields)181 int EventDbHelper::CreateTable(const std::string& table,
182 const std::vector<std::pair<std::string, std::string>>& fields)
183 {
184 std::string sql = SqlUtil::GenerateCreateSql(table, fields);
185 if (rdbStore_->ExecuteSql(sql) != NativeRdb::E_OK) {
186 HIVIEW_LOGE("failed to create table=%{public}s, sql=%{public}s", table.c_str(), sql.c_str());
187 return -1;
188 }
189 return 0;
190 }
191
CreatePluginStatsTable(const std::string & table)192 int EventDbHelper::CreatePluginStatsTable(const std::string& table)
193 {
194 /**
195 * table: plugin_stats
196 *
197 * |----|--------|-------|
198 * | id | plugin | event |
199 * |----|--------|-------|
200 */
201 std::vector<std::pair<std::string, std::string>> fields = {
202 {DB_COLUMIN_EVNET, SQL_TEXT_TYPE}, {DB_COLUMIN_PLUGIN, SQL_TEXT_TYPE}
203 };
204 return CreateTable(table, fields);
205 }
206
CreateSysUsageTable(const std::string & table)207 int EventDbHelper::CreateSysUsageTable(const std::string& table)
208 {
209 /**
210 * table: sys_usage / last_sys_usage
211 *
212 * |----|-------|
213 * | id | event |
214 * |----|-------|
215 */
216 std::vector<std::pair<std::string, std::string>> fields = {{DB_COLUMIN_EVNET, SQL_TEXT_TYPE}};
217 return CreateTable(table, fields);
218 }
219
InsertPluginStatsTable(const std::string & pluginName,const std::string & eventStr)220 int EventDbHelper::InsertPluginStatsTable(const std::string& pluginName, const std::string& eventStr)
221 {
222 if (CreatePluginStatsTable(DB_TABLE_PLUGIN_STATS) != 0) {
223 HIVIEW_LOGE("failed to create table=%{public}s", DB_TABLE_PLUGIN_STATS.c_str());
224 return -1;
225 }
226
227 HIVIEW_LOGD("insert db=%{public}s with %{public}s", dbPath_.c_str(), eventStr.c_str());
228 NativeRdb::ValuesBucket bucket;
229 bucket.PutString(DB_COLUMIN_PLUGIN, pluginName);
230 bucket.PutString(DB_COLUMIN_EVNET, eventStr);
231 int64_t seq = 0;
232 if (rdbStore_->Insert(seq, DB_TABLE_PLUGIN_STATS, bucket) != NativeRdb::E_OK) {
233 HIVIEW_LOGE("failed to insert pluginStats event=%{public}s", eventStr.c_str());
234 return -1;
235 }
236 return 0;
237 }
238
InsertSysUsageTable(const std::string & table,const std::string & eventStr)239 int EventDbHelper::InsertSysUsageTable(const std::string& table, const std::string& eventStr)
240 {
241 if (CreateSysUsageTable(table) != 0) {
242 HIVIEW_LOGE("failed to create table=%{public}s", table.c_str());
243 return -1;
244 }
245
246 HIVIEW_LOGD("insert db=%{public}s with %{public}s", dbPath_.c_str(), eventStr.c_str());
247 NativeRdb::ValuesBucket bucket;
248 bucket.PutString(DB_COLUMIN_EVNET, eventStr);
249 int64_t seq = 0;
250 if (rdbStore_->Insert(seq, table, bucket) != NativeRdb::E_OK) {
251 HIVIEW_LOGE("failed to insert sysUsage event=%{public}s", eventStr.c_str());
252 return -1;
253 }
254 return 0;
255 }
256
UpdatePluginStatsTable(const std::string & pluginName,const std::string & eventStr)257 int EventDbHelper::UpdatePluginStatsTable(const std::string& pluginName, const std::string& eventStr)
258 {
259 HIVIEW_LOGD("update db table %{public}s with %{public}s", DB_TABLE_PLUGIN_STATS.c_str(), eventStr.c_str());
260 NativeRdb::ValuesBucket bucket;
261 bucket.PutString(DB_COLUMIN_EVNET, eventStr);
262 NativeRdb::AbsRdbPredicates predicates(DB_TABLE_PLUGIN_STATS);
263 predicates.EqualTo(DB_COLUMIN_PLUGIN, pluginName);
264 int changeRows = 0;
265 if (rdbStore_->Update(changeRows, bucket, predicates) != NativeRdb::E_OK || changeRows == 0) {
266 HIVIEW_LOGE("failed to update pluginStats event=%{public}s", eventStr.c_str());
267 return -1;
268 }
269 return 0;
270 }
271
UpdateSysUsageTable(const std::string & table,const std::string & eventStr)272 int EventDbHelper::UpdateSysUsageTable(const std::string& table, const std::string& eventStr)
273 {
274 HIVIEW_LOGD("update db table %{public}s with %{public}s", table.c_str(), eventStr.c_str());
275 NativeRdb::ValuesBucket bucket;
276 bucket.PutString(DB_COLUMIN_EVNET, eventStr);
277 NativeRdb::AbsRdbPredicates predicates(table);
278 int changeRows = 0;
279 if (rdbStore_->Update(changeRows, bucket, predicates) != NativeRdb::E_OK || changeRows == 0) {
280 HIVIEW_LOGE("failed to update sysUsage event=%{public}s", eventStr.c_str());
281 return -1;
282 }
283 return 0;
284 }
285
QueryPluginStatsTable(std::vector<std::string> & eventStrs,const std::string & pluginName)286 int EventDbHelper::QueryPluginStatsTable(std::vector<std::string>& eventStrs, const std::string& pluginName)
287 {
288 return (QueryDb(eventStrs, DB_TABLE_PLUGIN_STATS, {{DB_COLUMIN_PLUGIN, pluginName}}) != NativeRdb::E_OK) ? -1 : 0;
289 }
290
QuerySysUsageTable(std::string & eventStr,const std::string & table)291 int EventDbHelper::QuerySysUsageTable(std::string& eventStr, const std::string& table)
292 {
293 std::vector<std::string> events;
294 if (QueryDb(events, table, {}) != NativeRdb::E_OK || events.empty()) {
295 return -1;
296 }
297 eventStr = events[0];
298 return 0;
299 }
300
QueryDb(std::vector<std::string> & eventStrs,const std::string & table,const std::vector<std::pair<std::string,std::string>> & queryConds)301 int EventDbHelper::QueryDb(std::vector<std::string>& eventStrs, const std::string& table,
302 const std::vector<std::pair<std::string, std::string>>& queryConds)
303 {
304 NativeRdb::AbsRdbPredicates predicates(table);
305 for (auto queryCond : queryConds) {
306 predicates.EqualTo(queryCond.first, queryCond.second);
307 }
308 auto resultSet = rdbStore_->Query(predicates, {DB_COLUMIN_EVNET});
309 if (resultSet == nullptr) {
310 HIVIEW_LOGI("failed to query table=%{public}s", table.c_str());
311 return -1;
312 }
313 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
314 std::string event;
315 if (resultSet->GetString(0, event) != NativeRdb::E_OK) {
316 HIVIEW_LOGI("failed to get %{public}s string from resultSet", DB_COLUMIN_EVNET.c_str());
317 continue;
318 }
319 eventStrs.emplace_back(event);
320 }
321 return 0;
322 }
323
DeleteTableData(const std::string & table)324 int EventDbHelper::DeleteTableData(const std::string& table)
325 {
326 HIVIEW_LOGI("delete data from the table=%{public}s", table.c_str());
327 int deleteRows = 0;
328 NativeRdb::AbsRdbPredicates predicates(table);
329 return rdbStore_->Delete(deleteRows, predicates) == NativeRdb::E_OK ? 0 : -1;
330 }
331 } // namespace HiviewDFX
332 } // namespace OHOS
333