1 /*
2 * Copyright (c) 2024 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 "file_util.h"
19 #include "hiview_logger.h"
20 #include "sys_event_sequence_mgr.h"
21
22 namespace OHOS {
23 namespace HiviewDFX {
24 DEFINE_LOG_TAG("HiView-EventExportTask");
25 using ExportEventListParsers = std::map<std::string, std::shared_ptr<ExportEventListParser>>;
26 namespace {
27 constexpr int64_t BYTE_TO_MB = 1024 * 1024;
28
GetParser(ExportEventListParsers & parsers,const std::string & path)29 std::shared_ptr<ExportEventListParser> GetParser(ExportEventListParsers& parsers,
30 const std::string& path)
31 {
32 auto iter = parsers.find(path);
33 if (iter == parsers.end()) {
34 parsers.emplace(path, std::make_shared<ExportEventListParser>(path));
35 return parsers[path];
36 }
37 return iter->second;
38 }
39 }
40
OnTaskRun()41 void EventExportTask::OnTaskRun()
42 {
43 if (config_ == nullptr || dbMgr_ == nullptr) {
44 HIVIEW_LOGE("config manager or db manager is invalid");
45 return;
46 }
47 if (FileUtil::GetFolderSize(config_->exportDir) >= static_cast<uint64_t>(config_->maxCapcity * BYTE_TO_MB)) {
48 HIVIEW_LOGE("event export directory is full");
49 return;
50 }
51 // init handler request
52 auto readReq = std::make_shared<EventReadRequest>();
53 if (!InitReadRequest(readReq)) {
54 HIVIEW_LOGE("failed to init read request");
55 return;
56 }
57 // init write handler
58 auto writeHandler = std::make_shared<EventWriteHandler>();
59 // init read handler
60 auto readHandler = std::make_shared<EventReadHandler>();
61 readHandler->SetEventExportedListener([this] (int64_t beginSeq, int64_t endSeq) {
62 HIVIEW_LOGW("export end sequence is updated with %{public}" PRId64 "", endSeq);
63 curBeginSeqInQuery_ = beginSeq;
64 curEndSeqInQuery_ = endSeq;
65 });
66 // init handler chain
67 readHandler->SetNextHandler(writeHandler);
68 // start handler chain
69 if (!readHandler->HandleRequest(readReq)) {
70 HIVIEW_LOGE("failed to export events in range [%{public}" PRId64 ",%{public}" PRId64 ")",
71 curBeginSeqInQuery_, curEndSeqInQuery_);
72 // record export progress
73 dbMgr_->HandleExportTaskFinished(config_->moduleName, curEndSeqInQuery_);
74 return;
75 }
76 // record export progress
77 dbMgr_->HandleExportTaskFinished(config_->moduleName, readReq->endSeq);
78 HIVIEW_LOGI("succeed to export events in range [%{public}" PRId64 ",%{public}" PRId64 ")", readReq->beginSeq,
79 readReq->endSeq);
80 }
81
ParseExportEventList(ExportEventList & list) const82 bool EventExportTask::ParseExportEventList(ExportEventList& list) const
83 {
84 ExportEventListParsers parsers;
85 auto iter = std::max_element(config_->eventsConfigFiles.begin(), config_->eventsConfigFiles.end(),
86 [&parsers] (const std::string& path1, const std::string& path2) {
87 auto parser1 = GetParser(parsers, path1);
88 auto parser2 = GetParser(parsers, path2);
89 return parser1->GetConfigurationVersion() < parser2->GetConfigurationVersion();
90 });
91 if (iter == config_->eventsConfigFiles.end()) {
92 HIVIEW_LOGE("no event list file path is configured.");
93 return false;
94 }
95 HIVIEW_LOGD("event list file path is %{public}s", (*iter).c_str());
96 auto parser = GetParser(parsers, *iter);
97 parser->GetExportEventList(list);
98 return true;
99 }
100
InitReadRequest(std::shared_ptr<EventReadRequest> readReq) const101 bool EventExportTask::InitReadRequest(std::shared_ptr<EventReadRequest> readReq) const
102 {
103 if (readReq == nullptr) {
104 return false;
105 }
106 readReq->beginSeq = dbMgr_->GetExportBeginSeq(config_->moduleName);
107 if (readReq->beginSeq == INVALID_SEQ_VAL) {
108 HIVIEW_LOGE("invalid export: begin sequence:%{public}" PRId64 "", readReq->beginSeq);
109 return false;
110 }
111 readReq->endSeq = EventStore::SysEventSequenceManager::GetInstance().GetSequence();
112 if (readReq->beginSeq >= readReq->endSeq) {
113 HIVIEW_LOGE("invalid export range: [%{public}" PRId64 ",%{public}" PRId64 ")",
114 readReq->beginSeq, readReq->endSeq);
115 return false;
116 }
117 if (!ParseExportEventList(readReq->eventList) || readReq->eventList.empty()) {
118 HIVIEW_LOGE("failed to get a valid event export list");
119 return false;
120 }
121 readReq->moduleName = config_->moduleName;
122 readReq->maxSize = config_->maxSize;
123 readReq->exportDir = config_->exportDir;
124 return true;
125 }
126 } // HiviewDFX
127 } // OHOS