1 /*
2 * Copyright (c) 2021 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 "plugin_config.h"
16 #include <fstream>
17 #include <iostream>
18 #include <regex>
19 #include <sstream>
20 #include "logger.h"
21 #include "string_util.h"
22
23 namespace OHOS {
24 namespace HiviewDFX {
25 DEFINE_LOG_TAG("HiView-PluginConfig");
PluginConfig(const std::string & file)26 PluginConfig::PluginConfig(const std::string& file) : configPath_(file) {}
StartParse()27 bool PluginConfig::StartParse()
28 {
29 std::ifstream in;
30 in.open(configPath_);
31 if (!in.is_open()) {
32 HIVIEW_LOGW("fail to open config file.");
33 return false;
34 }
35 int fieldCount = 0;
36 std::string field = "";
37 std::string buf = "";
38 const int fieldNameField = 1;
39 const int fieldCountField = 2;
40 while (getline(in, buf)) {
41 std::string strTmp = StringUtil::TrimStr(buf);
42 if (strTmp == "") {
43 continue;
44 }
45 std::smatch result;
46 if (fieldCount == 0) {
47 if (!regex_search(strTmp, result, std::regex("(plugins|pipelines|pipelinegroups)\\s*:\\s*(\\d+)"))) {
48 HIVIEW_LOGW("match field failed.");
49 in.close();
50 return false;
51 }
52
53 field = StringUtil::TrimStr(result[fieldNameField]);
54 fieldCount = atoi(std::string(result[fieldCountField]).c_str());
55 HIVIEW_LOGD("find field:%{public}s.", field.c_str());
56 continue;
57 }
58
59 if (field == "plugins") {
60 ParsePlugin(strTmp);
61 } else if (field == "pipelines") {
62 ParsePipeline(strTmp);
63 } else if (field == "pipelinegroups") {
64 ParsePipelineGroup(strTmp);
65 }
66 fieldCount--;
67 }
68 in.close();
69 return true;
70 }
71
ParsePlugin(const std::string & pluginStr)72 void PluginConfig::ParsePlugin(const std::string& pluginStr)
73 {
74 std::smatch result;
75 if (!regex_search(pluginStr, result,
76 std::regex("([^\\[]+)\\[([^\\[:]*):?([^:]*):?([^\\]]*)\\]\\s*:(\\d+)\\s+(dynamic|static)"))) {
77 HIVIEW_LOGW("no match plugin expression found! \n");
78 return;
79 }
80
81 // EventProcessorExample1[thread:t-example-2]:30 static
82 const int pluginNameField = 1;
83 const int workHandlerTypeField = 2;
84 const int workHandlerNameField = 3;
85 const int countOfThreadPoolField = 4;
86 const int loadDelayField = 5;
87 const int loadTypeField = 6;
88 PluginInfo info;
89
90 info.isStatic = (result[loadTypeField] == "static");
91 info.isEventSource = false;
92 info.loadDelay = atoi(std::string(result[loadDelayField]).c_str());
93 info.name = result[pluginNameField];
94 info.workHandlerType = result[workHandlerTypeField];
95 info.workHandlerName = result[workHandlerNameField];
96
97 // EventProcessorExample4[pool:pool-example-4:4]:0 static
98 if (result[workHandlerTypeField] == "pool") {
99 WorkPoolInfo poolInfo;
100 poolInfo.name = result[workHandlerNameField],
101 poolInfo.threadCount = atoi(std::string(result[countOfThreadPoolField]).c_str()),
102 workPoolInfoMap_[poolInfo.name] = std::move(poolInfo);
103 }
104 pluginInfoList_.push_back(std::move(info));
105 }
106
ParsePipeline(const std::string & pipelineStr)107 void PluginConfig::ParsePipeline(const std::string& pipelineStr)
108 {
109 std::smatch result;
110 // FromTwo2Three:EventProcessorExample2 EventProcessorExample3
111 if (!regex_search(pipelineStr, result, std::regex("(\\S+)\\s*:(.+)"))) {
112 HIVIEW_LOGW("Fail to match pipeline expression.");
113 return;
114 }
115
116 const int pipelineNameField = 1;
117 const int pluginNameListField = 2;
118 PipelineInfo pipelineInfo;
119 pipelineInfo.name = result.str(pipelineNameField);
120 pipelineInfo.pluginNameList = StringUtil::SplitStr(result.str(pluginNameListField));
121 pipelineInfoList_.push_back(std::move(pipelineInfo));
122 }
123
ParsePipelineGroup(const std::string & pipelineGroup)124 void PluginConfig::ParsePipelineGroup(const std::string& pipelineGroup)
125 {
126 std::smatch result;
127 // EventSourceExample:FromTwo2Three FromThree2Two
128 if (!regex_search(pipelineGroup, result, std::regex("(\\S+)\\s*:(.+)"))) {
129 HIVIEW_LOGW("Fail to match pipeline group expression.");
130 return;
131 }
132
133 const int pipelineGroupNameField = 1;
134 const int pipelineNameListField = 2;
135 std::string eventSourceName = StringUtil::TrimStr(result.str(pipelineGroupNameField));
136 auto ret = std::find_if(pluginInfoList_.begin(), pluginInfoList_.end(), [&](PluginInfo& info) {
137 if (info.name == eventSourceName) {
138 info.isEventSource = true;
139 info.pipelineNameList = StringUtil::SplitStr(result.str(pipelineNameListField));
140 return true;
141 }
142 return false;
143 });
144 if (ret != std::end(pluginInfoList_)) {
145 HIVIEW_LOGD("%s is an event source.", eventSourceName.c_str());
146 }
147 }
148
GetPluginInfoList() const149 const std::list<PluginConfig::PluginInfo>& PluginConfig::GetPluginInfoList() const
150 {
151 return pluginInfoList_;
152 }
153
GetPipelineInfoList() const154 const std::list<PluginConfig::PipelineInfo>& PluginConfig::GetPipelineInfoList() const
155 {
156 return pipelineInfoList_;
157 }
158 } // namespace HiviewDFX
159 } // namespace OHOS
160