1 /*
2 * Copyright (c) 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 "export_event_packager.h"
17
18 #include "event_write_strategy_factory.h"
19 #include "export_file_writer.h"
20 #include "export_json_file_builder.h"
21 #include "file_util.h"
22 #include "hiview_logger.h"
23 #include "string_util.h"
24
25 namespace OHOS {
26 namespace HiviewDFX {
27 DEFINE_LOG_TAG("HiView-EventExportFlow");
28 namespace {
29 constexpr int64_t MB_TO_BYTE = 1024 * 1024;
30 }
31
ExportEventPackager(const std::string & moduleName,const std::string & exportDir,const EventVersion & eventVersion,int32_t uid,int64_t maxFileSize)32 ExportEventPackager::ExportEventPackager(const std::string& moduleName, const std::string& exportDir,
33 const EventVersion& eventVersion, int32_t uid, int64_t maxFileSize)
34 {
35 moduleName_ = moduleName;
36 exportDir_ = exportDir;
37 eventVersion_ = eventVersion;
38 uid_ = uid;
39 maxFileSize_ = static_cast<uint64_t>(maxFileSize * MB_TO_BYTE);
40 }
41
AppendEvent(const std::string & domain,const std::string & name,const std::string & eventStr)42 bool ExportEventPackager::AppendEvent(const std::string& domain, const std::string& name,
43 const std::string& eventStr)
44 {
45 uint64_t eventSize = eventStr.size();
46 if (totalJsonStrSize_ + eventSize > maxFileSize_ && !Package()) {
47 HIVIEW_LOGE("failed to package events");
48 return false;
49 }
50 auto iter = packagedEvents_.find(domain);
51 if (iter == packagedEvents_.end()) {
52 packagedEvents_.emplace(domain, std::vector<std::pair<std::string, std::string>> {
53 std::make_pair(name, eventStr),
54 });
55 totalJsonStrSize_ += eventSize;
56 return true;
57 }
58 iter->second.emplace_back(name, eventStr);
59 totalJsonStrSize_ += eventSize;
60 return true;
61 }
62
ClearPackagedEvents()63 void ExportEventPackager::ClearPackagedEvents()
64 {
65 packagedEvents_.clear();
66 totalJsonStrSize_ = 0;
67 }
68
Package()69 bool ExportEventPackager::Package()
70 {
71 if (packagedEvents_.empty()) {
72 HIVIEW_LOGW("no need to package empty cache");
73 return true;
74 }
75 ExportFileWriter fileWriter;
76 fileWriter.SetExportFileWroteListener([this] (const std::string& srcPath,
77 const std::string& destPath) {
78 packagedFiles_[srcPath] = destPath;
79 });
80 WriteStrategyParam param {
81 moduleName_,
82 exportDir_,
83 eventVersion_,
84 uid_,
85 };
86 bool ret = fileWriter.Write(std::make_shared<ExportJsonFileBuilder>(eventVersion_), packagedEvents_, param);
87 if (!ret) {
88 HIVIEW_LOGE("failed to package cached events");
89 }
90 // after package, the event cache must be cleared
91 ClearPackagedEvents();
92 return ret;
93 }
94
ClearPackagedFiles()95 void ExportEventPackager::ClearPackagedFiles()
96 {
97 // delete all temporary pacakaged files
98 std::for_each(packagedFiles_.begin(), packagedFiles_.end(), [] (const auto& item) {
99 if (!FileUtil::RemoveFile(item.first)) {
100 HIVIEW_LOGE("failed to delete %{public}s", StringUtil::HideDeviceIdInfo(item.first).c_str());
101 }
102 });
103 packagedFiles_.clear();
104 }
105
HandlePackagedFiles()106 void ExportEventPackager::HandlePackagedFiles()
107 {
108 // move all temporary packaged file to dest directory
109 std::for_each(packagedFiles_.begin(), packagedFiles_.end(), [] (const auto& item) {
110 if (!FileUtil::RenameFile(item.first, item.second)) {
111 HIVIEW_LOGE("failed to move %{public}s to %{public}s", StringUtil::HideDeviceIdInfo(item.first).c_str(),
112 StringUtil::HideDeviceIdInfo(item.second).c_str());
113 }
114 HIVIEW_LOGI("renamed file: %{public}s", StringUtil::HideDeviceIdInfo(item.second).c_str());
115 });
116 packagedFiles_.clear();
117 }
118 } // HiviewDFX
119 } // OHOS