1 /*
2 * Copyright (c) 2023 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 #include "sys_event_doc.h"
16
17 #include <cerrno>
18
19 #include "base_def.h"
20 #include "event_store_config.h"
21 #include "file_util.h"
22 #include "hiview_logger.h"
23 #include "sys_event_database.h"
24 #include "sys_event_doc_reader.h"
25 #include "sys_event_doc_writer.h"
26
27 namespace OHOS {
28 namespace HiviewDFX {
29 namespace EventStore {
30 DEFINE_LOG_TAG("HiView-SysEventDoc");
31 namespace {
32 const char FILE_NAME_SEPARATOR[] = "-";
33 const char FILE_SEPARATOR[] = "/";
34 const char FILE_EXT[] = ".db";
35 }
36
SysEventDoc(const std::string & domain,const std::string & name)37 SysEventDoc::SysEventDoc(const std::string& domain, const std::string& name)
38 : writer_(nullptr), reader_(nullptr), domain_(domain), name_(name), type_(0)
39 {}
40
SysEventDoc(const std::string & file)41 SysEventDoc::SysEventDoc(const std::string& file) : writer_(nullptr), reader_(nullptr), type_(0), curFile_(file)
42 {}
43
~SysEventDoc()44 SysEventDoc::~SysEventDoc()
45 {}
46
Insert(const std::shared_ptr<SysEvent> & sysEvent)47 int SysEventDoc::Insert(const std::shared_ptr<SysEvent>& sysEvent)
48 {
49 if (sysEvent == nullptr) {
50 HIVIEW_LOGI("event is null");
51 return DOC_STORE_ERROR_NULL;
52 }
53
54 // init a writer for writing
55 auto ret = DOC_STORE_SUCCESS;
56 if (ret = InitWriter(sysEvent); ret != 0) {
57 HIVIEW_LOGE("failed to init writer from file=%{public}s", curFile_.c_str());
58 return ret;
59 }
60
61 // write event to the file
62 if (ret = writer_->Write(sysEvent); ret == DOC_STORE_NEW_FILE) {
63 // need to store to a new file
64 if (ret = CreateCurFile(GetDir(), sysEvent); ret != DOC_STORE_SUCCESS) {
65 HIVIEW_LOGE("failed to update curFile=%{public}s", curFile_.c_str());
66 return ret;
67 }
68 writer_ = std::make_shared<SysEventDocWriter>(curFile_);
69 HIVIEW_LOGD("update writer in new File=%{public}s", curFile_.c_str());
70 return writer_->Write(sysEvent);
71 }
72 return ret;
73 }
74
Query(const DocQuery & query,EntryQueue & entries,int & num)75 int SysEventDoc::Query(const DocQuery& query, EntryQueue& entries, int& num)
76 {
77 auto ret = DOC_STORE_SUCCESS;
78 if (reader_ == nullptr) {
79 if (ret = InitReader(); ret != DOC_STORE_SUCCESS) {
80 return ret;
81 }
82 }
83 return reader_->Read(query, entries, num);
84 }
85
InitWriter(const std::shared_ptr<SysEvent> & sysEvent)86 int SysEventDoc::InitWriter(const std::shared_ptr<SysEvent>& sysEvent)
87 {
88 if (writer_ == nullptr || IsNeedUpdateCurFile()) {
89 type_ = sysEvent->eventType_;
90 level_ = sysEvent->GetLevel();
91 if (auto ret = UpdateCurFile(sysEvent); ret != 0) {
92 HIVIEW_LOGE("failed to update current file");
93 return ret;
94 }
95 writer_ = std::make_shared<SysEventDocWriter>(curFile_);
96 HIVIEW_LOGD("init writer in curFile=%{public}s", curFile_.c_str());
97 }
98 return DOC_STORE_SUCCESS;
99 }
100
InitReader()101 int SysEventDoc::InitReader()
102 {
103 if (curFile_.empty() || !FileUtil::FileExists(curFile_)) {
104 HIVIEW_LOGE("failed to init reader from file=%{public}s", curFile_.c_str());
105 return DOC_STORE_ERROR_IO;
106 }
107 reader_ = std::make_shared<SysEventDocReader>(curFile_);
108 return DOC_STORE_SUCCESS;
109 }
110
IsFileFull(const std::string & file)111 bool SysEventDoc::IsFileFull(const std::string& file)
112 {
113 return FileUtil::GetFileSize(file) >= GetMaxFileSize();
114 }
115
IsNeedUpdateCurFile()116 bool SysEventDoc::IsNeedUpdateCurFile()
117 {
118 return curFile_.empty() || IsFileFull(curFile_);
119 }
120
UpdateCurFile(const std::shared_ptr<SysEvent> & sysEvent)121 int SysEventDoc::UpdateCurFile(const std::shared_ptr<SysEvent>& sysEvent)
122 {
123 std::string dir = GetDir();
124 if (dir.empty()) {
125 return DOC_STORE_ERROR_IO;
126 }
127 std::string filePath = GetCurFile(dir);
128 if (filePath.empty() || IsFileFull(filePath)) {
129 return CreateCurFile(dir, sysEvent);
130 }
131 curFile_ = filePath;
132 return DOC_STORE_SUCCESS;
133 }
134
GetDir()135 std::string SysEventDoc::GetDir()
136 {
137 std::string dir = SysEventDatabase::GetInstance().GetDatabaseDir() + domain_;
138 if (!FileUtil::IsDirectory(dir) && !FileUtil::ForceCreateDirectory(dir)) {
139 HIVIEW_LOGE("failed to create domain dir=%{public}s", dir.c_str());
140 return "";
141 }
142 return dir;
143 }
144
GetCurFile(const std::string & dir)145 std::string SysEventDoc::GetCurFile(const std::string& dir)
146 {
147 std::vector<std::string> files;
148 FileUtil::GetDirFiles(dir, files);
149 std::string curFile;
150 for (auto& file : files) {
151 if (file.find(FILE_SEPARATOR + name_ + FILE_NAME_SEPARATOR) == std::string::npos) {
152 continue;
153 }
154 if ((file.size() == curFile.size() && file > curFile) || file.size() > curFile.size()) {
155 curFile = file;
156 }
157 }
158 return curFile;
159 }
160
GetMaxFileSize()161 uint32_t SysEventDoc::GetMaxFileSize()
162 {
163 return EventStoreConfig::GetInstance().GetMaxFileSize(type_) * NUM_OF_BYTES_IN_KB;
164 }
165
CreateCurFile(const std::string & dir,const std::shared_ptr<SysEvent> & sysEvent)166 int SysEventDoc::CreateCurFile(const std::string& dir, const std::shared_ptr<SysEvent>& sysEvent)
167 {
168 auto seq = sysEvent->GetEventSeq();
169 std::string filePath = dir + FILE_SEPARATOR;
170 filePath.append(name_).append(FILE_NAME_SEPARATOR).append(std::to_string(type_)).append(FILE_NAME_SEPARATOR)
171 .append(level_).append(FILE_NAME_SEPARATOR).append(std::to_string(seq)).append(FILE_EXT);
172 if (FileUtil::CreateFile(filePath, FileUtil::FILE_PERM_660) != 0 && !FileUtil::FileExists(filePath)) {
173 HIVIEW_LOGE("failed to create file=%{public}s, errno=%{public}d", filePath.c_str(), errno);
174 return DOC_STORE_ERROR_IO;
175 }
176 curFile_ = filePath;
177 return DOC_STORE_SUCCESS;
178 }
179 } // EventStore
180 } // HiviewDFX
181 } // OHOS
182