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