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