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_write_handler.h"
17 
18 #include "file_util.h"
19 #include "hiview_logger.h"
20 #include "string_util.h"
21 
22 namespace OHOS {
23 namespace HiviewDFX {
24 DEFINE_LOG_TAG("HiView-EventWriteHandler");
25 namespace {
TransEventVersionToStr(const EventVersion & eventVersion)26 std::string TransEventVersionToStr(const EventVersion& eventVersion)
27 {
28     std::string concactedContent;
29     concactedContent.append(eventVersion.systemVersion).append("_");
30     concactedContent.append(eventVersion.patchVersion);
31     return concactedContent;
32 }
33 }
34 
HandleRequest(RequestPtr req)35 bool EventWriteHandler::HandleRequest(RequestPtr req)
36 {
37     auto writeReq = BaseRequest::DownCastTo<EventWriteRequest>(req);
38     for (const auto& sysEvent : writeReq->sysEvents) {
39         auto writer = GetEventWriter(sysEvent->version, writeReq);
40         if (!writer->AppendEvent(sysEvent->domain, sysEvent->name, sysEvent->eventStr)) {
41             HIVIEW_LOGE("failed to append event to event writer");
42             Rollback();
43             return false;
44         }
45     }
46     if (!writeReq->isQueryCompleted) {
47         return true;
48     }
49     for (const auto& writer : allJsonFileWriters_) {
50         if (writer.second == nullptr) {
51             continue;
52         }
53         if (!writer.second->Write()) {
54             HIVIEW_LOGE("failed to write export event");
55             Rollback();
56             return false;
57         }
58     }
59     CopyTmpZipFilesToDest();
60     return true;
61 }
62 
GetEventWriter(const EventVersion & eventVersion,std::shared_ptr<EventWriteRequest> writeReq)63 std::shared_ptr<ExportJsonFileWriter> EventWriteHandler::GetEventWriter(const EventVersion& eventVersion,
64     std::shared_ptr<EventWriteRequest> writeReq)
65 {
66     auto writerKey = std::make_pair(writeReq->moduleName, TransEventVersionToStr(eventVersion));
67     auto iter = allJsonFileWriters_.find(writerKey);
68     if (iter == allJsonFileWriters_.end()) {
69         HIVIEW_LOGI("create json file writer with system version[%{public}s] and patch version[%{public}s]",
70             eventVersion.systemVersion.c_str(), eventVersion.patchVersion.c_str());
71         auto jsonFileWriter = std::make_shared<ExportJsonFileWriter>(writeReq->moduleName, eventVersion,
72             writeReq->exportDir, writeReq->maxSingleFileSize);
73         jsonFileWriter->SetExportJsonFileZippedListener([this] (const std::string& srcPath,
74             const std::string& destPath) {
75             zippedExportFileMap_[srcPath] = destPath;
76         });
77         allJsonFileWriters_.emplace(writerKey, jsonFileWriter);
78         return jsonFileWriter;
79     }
80     return iter->second;
81 }
82 
CopyTmpZipFilesToDest()83 void EventWriteHandler::CopyTmpZipFilesToDest()
84 {
85     // move all tmp zipped event export file to dest dir
86     std::for_each(zippedExportFileMap_.begin(), zippedExportFileMap_.end(), [] (const auto& item) {
87         if (!FileUtil::RenameFile(item.first, item.second)) {
88             HIVIEW_LOGE("failed to move %{public}s to %{public}s", StringUtil::HideDeviceIdInfo(item.first).c_str(),
89                 StringUtil::HideDeviceIdInfo(item.second).c_str());
90         }
91         HIVIEW_LOGI("zip file to export: %{public}s", StringUtil::HideDeviceIdInfo(item.second).c_str());
92     });
93     zippedExportFileMap_.clear();
94 }
95 
Rollback()96 void EventWriteHandler::Rollback()
97 {
98     for (const auto& writer : allJsonFileWriters_) {
99         if (writer.second == nullptr) {
100             continue;
101         }
102         writer.second->ClearEventCache();
103     }
104     // delete all tmp zipped export file
105     std::for_each(zippedExportFileMap_.begin(), zippedExportFileMap_.end(), [] (const auto& item) {
106         if (!FileUtil::RemoveFile(item.first)) {
107             HIVIEW_LOGE("failed to delete %{public}s", StringUtil::HideDeviceIdInfo(item.first).c_str());
108         }
109     });
110     zippedExportFileMap_.clear();
111 }
112 } // HiviewDFX
113 } // OHOS