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
16 #include "hiview_log_config_manager.h"
17
18 #include <fstream>
19
20 #include "json/json.h"
21 #include "hiview_logger.h"
22
23 namespace OHOS {
24 namespace HiviewDFX {
25 namespace {
26 DEFINE_LOG_TAG("HiviewLogConfigManager");
27 constexpr char CONFIG_FILE_PATH[] = "/system/etc/hiview/log_type.json";
28 constexpr char FILE_PATH_KEY[] = "LOGPATH";
29 constexpr char READ_ONLY_KEY[] = "READONLY";
30
ParseJsonFile(const std::string & path)31 Json::Value ParseJsonFile(const std::string& path)
32 {
33 Json::Value jsonRoot;
34 std::ifstream fin(path, std::ifstream::binary);
35 if (!fin.is_open()) {
36 HIVIEW_LOGW("failed to open file, path: %{public}s.", path.c_str());
37 return Json::Value();
38 }
39 Json::CharReaderBuilder builder;
40 Json::CharReaderBuilder::strictMode(&builder.settings_);
41 JSONCPP_STRING errs;
42 if (!parseFromStream(builder, fin, &jsonRoot, &errs)) {
43 HIVIEW_LOGE("failed to parse file, path: %{public}s.", path.c_str());
44 return Json::Value();
45 }
46 return jsonRoot;
47 }
48
IsStringMember(const Json::Value & jsonRoot,const std::string & key)49 inline bool IsStringMember(const Json::Value& jsonRoot, const std::string& key)
50 {
51 return jsonRoot.isObject() && jsonRoot.isMember(key) && jsonRoot[key].isString();
52 }
53
IsBoolMember(const Json::Value & jsonRoot,const std::string & key)54 inline bool IsBoolMember(const Json::Value& jsonRoot, const std::string& key)
55 {
56 return jsonRoot.isObject() && jsonRoot.isMember(key) && jsonRoot[key].isBool();
57 }
58 }
59
GetConfigInfoByType(const std::string & type)60 std::shared_ptr<ConfigInfo> HiviewLogConfigManager::GetConfigInfoByType(const std::string& type)
61 {
62 std::lock_guard<std::mutex> lock(logMutex);
63 if (configInfos.find(type) != configInfos.end()) {
64 return configInfos[type];
65 }
66 return GetLogConfigFromFile(type);
67 }
68
GetLogConfigFromFile(const std::string & type)69 std::shared_ptr<ConfigInfo> HiviewLogConfigManager::GetLogConfigFromFile(const std::string& type)
70 {
71 HIVIEW_LOGI("read log config from file, type: %{public}s", type.c_str());
72 Json::Value jsonRoot = ParseJsonFile(CONFIG_FILE_PATH);
73 if (jsonRoot.empty() || !jsonRoot.isObject()) {
74 HIVIEW_LOGW("no valid log config file.");
75 return nullptr;
76 }
77 if (!jsonRoot.isMember(type)) {
78 HIVIEW_LOGW("no such type: %{public}s.", type.c_str());
79 return nullptr;
80 }
81 if (!IsStringMember(jsonRoot[type], FILE_PATH_KEY)) {
82 HIVIEW_LOGW("no file path tag.");
83 return nullptr;
84 }
85 std::string path(jsonRoot[type][FILE_PATH_KEY].asString());
86 if (path.empty()) {
87 HIVIEW_LOGW("path is empty.");
88 return nullptr;
89 }
90 if (path[path.size() - 1] != '/') {
91 path.append("/"); // add slash at end of dir for simple use
92 }
93 auto configInfoPtr = std::make_shared<ConfigInfo>(path);
94 if (IsBoolMember(jsonRoot[type], READ_ONLY_KEY)) {
95 configInfoPtr->isReadOnly = jsonRoot[type][READ_ONLY_KEY].asBool();
96 }
97 configInfos.insert(std::make_pair(type, configInfoPtr));
98 return configInfoPtr;
99 }
100 } // namespace HiviewDFX
101 } // namespace OHOS