• 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 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