1 /*
2 * Copyright (c) 2024-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 "event_export_task.h"
17
18 #include "event_json_parser.h"
19 #include "file_util.h"
20 #include "hiview_logger.h"
21 #include "setting_observer_manager.h"
22 #include "sys_event_sequence_mgr.h"
23
24 namespace OHOS {
25 namespace HiviewDFX {
26 DEFINE_LOG_TAG("HiView-EventExportTask");
27 using ExportEventListParsers = std::map<std::string, std::shared_ptr<ExportEventListParser>>;
28 namespace {
29 constexpr int64_t BYTE_TO_MB = 1024 * 1024;
30
GetParser(ExportEventListParsers & parsers,const std::string & path)31 std::shared_ptr<ExportEventListParser> GetParser(ExportEventListParsers& parsers,
32 const std::string& path)
33 {
34 auto iter = parsers.find(path);
35 if (iter == parsers.end()) {
36 parsers.emplace(path, std::make_shared<ExportEventListParser>(path));
37 return parsers[path];
38 }
39 return iter->second;
40 }
41
IsExportSwitchOff(std::shared_ptr<ExportConfig> config,std::shared_ptr<ExportDbManager> dbMgr)42 bool IsExportSwitchOff(std::shared_ptr<ExportConfig> config, std::shared_ptr<ExportDbManager> dbMgr)
43 {
44 bool isSwitchOff = (SettingObserverManager::GetInstance()->GetStringValue(config->exportSwitchParam.name) !=
45 config->exportSwitchParam.enabledVal);
46 if (isSwitchOff) {
47 HIVIEW_LOGI("export switch for module %{public}s is off", config->moduleName.c_str());
48 int64_t enabledSeq = dbMgr->GetExportEnabledSeq(config->moduleName);
49 // handle setting parameter listening error
50 if (enabledSeq != INVALID_SEQ_VAL && !FileUtil::FileExists(dbMgr->GetEventInheritFlagPath())) {
51 dbMgr->HandleExportSwitchChanged(config->moduleName, INVALID_SEQ_VAL);
52 }
53 return true;
54 }
55 HIVIEW_LOGI("export switch for module %{public}s is on", config->moduleName.c_str());
56 int64_t enabledSeq = dbMgr->GetExportEnabledSeq(config->moduleName);
57 if (enabledSeq == INVALID_SEQ_VAL) { // handle setting parameter listening error
58 enabledSeq = EventStore::SysEventSequenceManager::GetInstance().GetSequence();
59 dbMgr->HandleExportSwitchChanged(config->moduleName, enabledSeq);
60 }
61 return false;
62 }
63 }
64
OnTaskRun()65 void EventExportTask::OnTaskRun()
66 {
67 if (config_ == nullptr || dbMgr_ == nullptr) {
68 HIVIEW_LOGE("config manager or db manager is invalid");
69 return;
70 }
71 if (IsExportSwitchOff(config_, dbMgr_)) {
72 return;
73 }
74 if (FileUtil::GetFolderSize(config_->exportDir) >= static_cast<uint64_t>(config_->maxCapcity * BYTE_TO_MB)) {
75 HIVIEW_LOGE("event export directory is full");
76 return;
77 }
78 // init handler request
79 auto readReq = std::make_shared<EventReadRequest>();
80 if (!InitReadRequest(readReq)) {
81 HIVIEW_LOGE("failed to init read request");
82 return;
83 }
84 // init write handler
85 auto writeHandler = std::make_shared<EventWriteHandler>();
86 // init read handler
87 auto readHandler = std::make_shared<EventReadHandler>();
88 readHandler->SetEventExportedListener([this] (int64_t beginSeq, int64_t endSeq) {
89 HIVIEW_LOGW("finished exporting events in range [%{public}" PRId64 ", %{public}" PRId64 ")",
90 beginSeq, endSeq);
91 // sync export progress to db
92 dbMgr_->HandleExportTaskFinished(config_->moduleName, endSeq);
93 });
94 // init handler chain
95 readHandler->SetNextHandler(writeHandler);
96 // start handler chain
97 if (!readHandler->HandleRequest(readReq)) {
98 HIVIEW_LOGE("failed to export all events in range [%{public}" PRId64 ",%{public}" PRId64 ")",
99 readReq->beginSeq, readReq->endSeq);
100 return;
101 }
102 // record export progress
103 HIVIEW_LOGI("succeed to export all events in range [%{public}" PRId64 ",%{public}" PRId64 ")", readReq->beginSeq,
104 readReq->endSeq);
105 }
106
ParseExportEventList(ExportEventList & list) const107 bool EventExportTask::ParseExportEventList(ExportEventList& list) const
108 {
109 if (config_->eventsConfigFiles.empty()) {
110 // if export event list file isn't configured, use export info configured in hisysevent.def
111 EventJsonParser::GetInstance()->GetAllCollectEvents(list);
112 return true;
113 }
114 ExportEventListParsers parsers;
115 auto iter = std::max_element(config_->eventsConfigFiles.begin(), config_->eventsConfigFiles.end(),
116 [&parsers] (const std::string& path1, const std::string& path2) {
117 auto parser1 = GetParser(parsers, path1);
118 auto parser2 = GetParser(parsers, path2);
119 return parser1->GetConfigurationVersion() < parser2->GetConfigurationVersion();
120 });
121 if (iter == config_->eventsConfigFiles.end()) {
122 HIVIEW_LOGE("no event list file path is configured.");
123 return false;
124 }
125 HIVIEW_LOGD("event list file path is %{public}s", (*iter).c_str());
126 auto parser = GetParser(parsers, *iter);
127 parser->GetExportEventList(list);
128 return true;
129 }
130
InitReadRequest(std::shared_ptr<EventReadRequest> readReq) const131 bool EventExportTask::InitReadRequest(std::shared_ptr<EventReadRequest> readReq) const
132 {
133 if (readReq == nullptr) {
134 return false;
135 }
136 readReq->beginSeq = dbMgr_->GetExportBeginSeq(config_->moduleName);
137 if (readReq->beginSeq == INVALID_SEQ_VAL) {
138 HIVIEW_LOGE("invalid export: begin sequence:%{public}" PRId64 "", readReq->beginSeq);
139 return false;
140 }
141 readReq->endSeq = EventStore::SysEventSequenceManager::GetInstance().GetSequence();
142 if (readReq->beginSeq >= readReq->endSeq) {
143 HIVIEW_LOGE("invalid export range: [%{public}" PRId64 ",%{public}" PRId64 ")",
144 readReq->beginSeq, readReq->endSeq);
145 return false;
146 }
147 if (!ParseExportEventList(readReq->eventList) || readReq->eventList.empty()) {
148 HIVIEW_LOGE("failed to get a valid event export list");
149 return false;
150 }
151 readReq->moduleName = config_->moduleName;
152 readReq->maxSize = config_->maxSize;
153 readReq->exportDir = config_->exportDir;
154 return true;
155 }
156 } // HiviewDFX
157 } // OHOS
158