1 /*
2 * Copyright (c) 2021-2025 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
16 #include "sys_event_store.h"
17
18 #include <cstdio>
19 #include <memory>
20
21 #include "event.h"
22 #include "event_export_engine.h"
23 #include "file_util.h"
24 #include "focused_event_util.h"
25 #include "hiview_global.h"
26 #include "hiview_logger.h"
27 #include "hiview_platform.h"
28 #include "running_status_logger.h"
29 #include "parameter_ex.h"
30 #include "plugin_factory.h"
31 #include "string_util.h"
32 #include "sys_event.h"
33 #include "sys_event_dao.h"
34 #include "sys_event_db_mgr.h"
35 #include "sys_event_sequence_mgr.h"
36 #include "time_util.h"
37
38 namespace OHOS {
39 namespace HiviewDFX {
40 namespace {
41 REGISTER(SysEventStore);
42 DEFINE_LOG_TAG("HiView-SysEventStore");
43 constexpr char PROP_LAST_BACKUP[] = "persist.hiviewdfx.priv.sysevent.backup_time";
44 constexpr int TWO_HOURS_OFFSET = -2;
45 constexpr size_t EVENT_STORE_INFO_DEFAULT_CNT = 1;
46 constexpr char STORE_PERIOD_CNT_ITEM_CONCATE[] = " ";
47 constexpr size_t STORE_PERIOD_INFO_ITEM_CNT = 2;
48
LogStorePeriodInfo(std::shared_ptr<StorePeriodInfo> info)49 void LogStorePeriodInfo(std::shared_ptr<StorePeriodInfo> info)
50 {
51 std::string logInfo;
52 // append period
53 logInfo.append("period=[").append(info->timeStamp).append("]; ");
54 // append num of the event which has been stored;
55 logInfo.append("stored_event_num=[").append(std::to_string(info->storedCnt)).append("]");
56 RunningStatusLogger::GetInstance().LogEventCountStatisticInfo(logInfo);
57 }
58 }
59
SysEventStore()60 SysEventStore::SysEventStore() : hasLoaded_(false)
61 {
62 sysEventDbMgr_ = std::make_unique<SysEventDbMgr>();
63 }
64
OnLoad()65 void SysEventStore::OnLoad()
66 {
67 HIVIEW_LOGI("sys event service load");
68 sysEventDbMgr_->StartCheckStoreTask(this->workLoop_);
69
70 lastBackupTime_ = Parameter::GetString(PROP_LAST_BACKUP, "");
71 // pack id must be initialized as soon as event store plugin has been loaded
72 EventExportEngine::InitPackId();
73 hasLoaded_ = true;
74
75 periodFileOpt_ = std::make_unique<PeriodInfoFileOperator>(GetHiviewContext(), "event_store_period_count");
76 periodFileOpt_->ReadPeriodInfoFromFile(STORE_PERIOD_INFO_ITEM_CNT,
77 [this] (const std::vector<std::string>& infoDetails) {
78 uint64_t storeCnt = 0;
79 StringUtil::ConvertStringTo(infoDetails[1], storeCnt); // 1 is the index of store count
80 periodInfoList_.emplace_back(std::make_shared<StorePeriodInfo>(infoDetails[0], storeCnt));
81 });
82 }
83
OnUnload()84 void SysEventStore::OnUnload()
85 {
86 HIVIEW_LOGI("sys event service unload");
87 EventExportEngine::GetInstance().Stop();
88 }
89
IsNeedBackup(const std::string & dateStr)90 bool SysEventStore::IsNeedBackup(const std::string& dateStr)
91 {
92 if (lastBackupTime_ == dateStr) {
93 return false;
94 }
95 if (lastBackupTime_.empty()) {
96 // first time boot, no need to backup
97 lastBackupTime_ = dateStr;
98 Parameter::SetProperty(PROP_LAST_BACKUP, dateStr);
99 HIVIEW_LOGI("first time boot, record backup time: %{public}s.", dateStr.c_str());
100 return false;
101 }
102 return true;
103 }
104
Convert2SysEvent(std::shared_ptr<Event> & event)105 std::shared_ptr<SysEvent> SysEventStore::Convert2SysEvent(std::shared_ptr<Event>& event)
106 {
107 if (event == nullptr) {
108 HIVIEW_LOGE("event is null");
109 return nullptr;
110 }
111 if (event->messageType_ != Event::MessageType::SYS_EVENT) {
112 HIVIEW_LOGE("receive out of sys event type");
113 return nullptr;
114 }
115 std::shared_ptr<SysEvent> sysEvent = Event::DownCastTo<SysEvent>(event);
116 if (sysEvent == nullptr) {
117 HIVIEW_LOGE("sysevent is null");
118 }
119 return sysEvent;
120 }
121
OnEvent(std::shared_ptr<Event> & event)122 bool SysEventStore::OnEvent(std::shared_ptr<Event>& event)
123 {
124 if (!hasLoaded_) {
125 HIVIEW_LOGE("SysEventService not ready");
126 return false;
127 }
128 // start event export engine only once time
129 std::call_once(exportEngineStartFlag_, [] () {
130 EventExportEngine::GetInstance().Start();
131 });
132
133 std::shared_ptr<SysEvent> sysEvent = Convert2SysEvent(event);
134 if (sysEvent != nullptr && sysEvent->preserve_) {
135 // add seq to sys event and save it to local file
136 int64_t eventSeq = EventStore::SysEventSequenceManager::GetInstance().GetSequence();
137 sysEvent->SetEventSeq(eventSeq);
138 sysEvent->SetEventValue("period_seq_", sysEvent->GetValue("period_seq_"));
139 if (FocusedEventUtil::IsFocusedEvent(sysEvent->domain_, sysEvent->eventName_)) {
140 HIVIEW_LOGI("event[%{public}s|%{public}s|%{public}" PRId64 "] is valid.",
141 sysEvent->domain_.c_str(), sysEvent->eventName_.c_str(), eventSeq);
142 }
143 EventStore::SysEventSequenceManager::GetInstance().SetSequence(++eventSeq);
144 sysEventDbMgr_->SaveToStore(sysEvent);
145
146 if (!Parameter::IsOversea() && !Parameter::IsFactoryMode()) {
147 std::string dateStr(TimeUtil::TimestampFormatToDate(TimeUtil::GetSeconds(), "%Y%m%d"));
148 if (IsNeedBackup(dateStr)) {
149 EventStore::SysEventDao::Backup();
150 lastBackupTime_ = dateStr;
151 Parameter::SetProperty(PROP_LAST_BACKUP, dateStr);
152 }
153 }
154 StatisticStorePeriodInfo(sysEvent);
155 }
156 return true;
157 }
158
StatisticStorePeriodInfo(const std::shared_ptr<SysEvent> event)159 void SysEventStore::StatisticStorePeriodInfo(const std::shared_ptr<SysEvent> event)
160 {
161 if (!Parameter::IsBetaVersion()) {
162 return;
163 }
164 auto eventPeriodTimeStamp = event->GetEventPeriodSeqInfo().timeStamp;
165 HIVIEW_LOGD("current formatted hour is %{public}s", eventPeriodTimeStamp.c_str());
166 if (eventPeriodTimeStamp.empty()) {
167 HIVIEW_LOGW("time stamp of current event period sequence is empty");
168 return;
169 }
170 std::shared_ptr<StorePeriodInfo> recentPeriodInfo = nullptr;
171 for (auto iter = periodInfoList_.crbegin(); iter != periodInfoList_.crend(); ++iter) {
172 auto storeInfoItem = *iter;
173 if (storeInfoItem->timeStamp == eventPeriodTimeStamp) {
174 recentPeriodInfo = storeInfoItem;
175 break;
176 }
177 }
178 if (recentPeriodInfo != nullptr) {
179 ++(recentPeriodInfo->storedCnt);
180 RecordStorePeriodInfo();
181 return;
182 }
183
184 time_t baseTimeStamp = TimeUtil::StrToTimeStamp(eventPeriodTimeStamp, "%Y%m%d%H");
185 auto twoHourAgoTs = TimeUtil::TimestampFormatToDate(baseTimeStamp + TWO_HOURS_OFFSET * TimeUtil::SECONDS_PER_HOUR,
186 "%Y%m%d%H");
187 // clear and log historical info
188 while (!periodInfoList_.empty()) {
189 auto infoItem = periodInfoList_.front();
190 if (infoItem->timeStamp <= twoHourAgoTs || infoItem->timeStamp > eventPeriodTimeStamp) {
191 LogStorePeriodInfo(infoItem);
192 periodInfoList_.pop_front();
193 } else {
194 break;
195 }
196 }
197 recentPeriodInfo = std::make_shared<StorePeriodInfo>(eventPeriodTimeStamp, EVENT_STORE_INFO_DEFAULT_CNT);
198 periodInfoList_.emplace_back(recentPeriodInfo);
199 RecordStorePeriodInfo();
200 }
201
RecordStorePeriodInfo()202 void SysEventStore::RecordStorePeriodInfo()
203 {
204 periodFileOpt_->WritePeriodInfoToFile([this] () {
205 std::string periodInfoContent;
206 for (const auto& periodInfo : periodInfoList_) {
207 periodInfoContent.append(periodInfo->timeStamp).append(STORE_PERIOD_CNT_ITEM_CONCATE);
208 periodInfoContent.append(std::to_string(periodInfo->storedCnt)).append("\n");
209 }
210 return periodInfoContent;
211 });
212 }
213 } // namespace HiviewDFX
214 } // namespace OHOS
215