Skip to content

Commit 2915b46

Browse files
committed
feat(trace,main): 给trace::Sink添加过滤功能,并在main中使用参数与命令进行配置
1 parent d211109 commit 2915b46

File tree

4 files changed

+171
-4
lines changed

4 files changed

+171
-4
lines changed

Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ LDFLAGS += -pg
5050
endif
5151
endif
5252

53-
CXXFLAGS := $(CCFLAGS) $(CXXFLAGS)
54-
CFLAGS := $(CCFLAGS) $(CFLAGS)
55-
APPS_DIR := $(PWD)
56-
5753
export CC CXX CFLAGS CXXFLAGS LDFLAGS APPS_DIR
5854
export MODULES THIRDPARTY
5955

6056
include config.mk
6157

58+
CXXFLAGS := $(CCFLAGS) $(CXXFLAGS)
59+
CFLAGS := $(CCFLAGS) $(CFLAGS)
60+
APPS_DIR := $(PWD)
61+
6262
all: 3rd-party modules test examples
6363

6464
print:

modules/main/trace.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "trace.h"
2121
#include <iostream>
2222
#include <sstream>
23+
#include <tbox/base/log.h>
2324
#include <tbox/base/json.hpp>
2425
#include <tbox/base/catch_throw.h>
2526
#include <tbox/terminal/session.h>
@@ -74,6 +75,34 @@ bool Trace::initialize(Context &ctx, const Json &cfg)
7475

7576
if (is_enable)
7677
sink.enable();
78+
79+
if (util::json::HasObjectField(js_trace, "filter")) {
80+
auto &js_filter = js_trace.at("filter");
81+
82+
std::string filter_strategy;
83+
if (util::json::GetField(js_filter, "strategy", filter_strategy)) {
84+
if (filter_strategy == "permit") {
85+
sink.setFilterStrategy(trace::Sink::FilterStrategy::kPermit);
86+
} else if (filter_strategy == "reject") {
87+
sink.setFilterStrategy(trace::Sink::FilterStrategy::kReject);
88+
} else {
89+
LogWarn("config 'trace.filter.strategy' field is invalid");
90+
}
91+
}
92+
93+
if (util::json::HasArrayField(js_filter, "exempts")) {
94+
auto &js_exempts = js_filter.at("exempts");
95+
trace::Sink::ExemptSet exempt_set;
96+
for (auto &js_item : js_exempts) {
97+
std::string module;
98+
if (util::json::Get(js_item, module))
99+
exempt_set.insert(module);
100+
else
101+
LogWarn("config 'trace.filter.exempts' item is invalid");
102+
}
103+
sink.setFilterExemptSet(exempt_set);
104+
}
105+
}
77106
}
78107
return true;
79108
}
@@ -155,6 +184,96 @@ void Trace::initShell(TerminalNodes &term)
155184
profile.help = "get current directory";
156185
terminal::AddFuncNode(term, trace_node, "get_dir_path", profile);
157186
}
187+
188+
{
189+
auto filter_node = term.createDirNode();
190+
term.mountNode(trace_node, filter_node, "filter");
191+
192+
{
193+
terminal::StringFuncNodeProfile profile;
194+
profile.get_func = [] () {
195+
auto strategy = trace::Sink::GetInstance().getFilterStrategy();
196+
if (strategy == trace::Sink::FilterStrategy::kPermit)
197+
return "permit";
198+
else
199+
return "reject";
200+
};
201+
profile.set_func = [] (const std::string &strategy) {
202+
if (strategy == "permit") {
203+
trace::Sink::GetInstance().setFilterStrategy(trace::Sink::FilterStrategy::kPermit);
204+
return true;
205+
206+
} else if (strategy == "reject") {
207+
trace::Sink::GetInstance().setFilterStrategy(trace::Sink::FilterStrategy::kReject);
208+
return true;
209+
210+
} else {
211+
return false;
212+
}
213+
};
214+
215+
profile.usage = \
216+
"Usage : strategy # print current filter strategy.\r\n"
217+
" strategy permit|reject # set filter strategy.\r\n";
218+
profile.help = "print or set filter strategy";
219+
terminal::AddFuncNode(term, filter_node, "strategy", profile);
220+
}
221+
222+
{
223+
auto exempts_node = term.createDirNode();
224+
term.mountNode(filter_node, exempts_node, "exempts");
225+
226+
{
227+
auto func_node = term.createFuncNode(
228+
[] (const terminal::Session &s, const terminal::Args &) {
229+
auto exempt_set = trace::Sink::GetInstance().getFilterExemptSet();
230+
std::ostringstream oss;
231+
for (auto &item : exempt_set)
232+
oss << item << "\r\n";
233+
oss << "\r\n";
234+
s.send(oss.str());
235+
}
236+
);
237+
term.mountNode(exempts_node, func_node, "print");
238+
}
239+
240+
{
241+
terminal::StringFuncNodeProfile profile;
242+
profile.set_func = [] (const std::string &module) {
243+
auto &sink = trace::Sink::GetInstance();
244+
auto exempt_set = sink.getFilterExemptSet();
245+
exempt_set.insert(module);
246+
sink.setFilterExemptSet(exempt_set);
247+
return true;
248+
};
249+
profile.usage = "Usage : add <module>\r\n";
250+
profile.help = "add module in exempts";
251+
terminal::AddFuncNode(term, exempts_node, "add", profile);
252+
}
253+
254+
{
255+
terminal::StringFuncNodeProfile profile;
256+
profile.set_func = [] (const std::string &module) {
257+
auto &sink = trace::Sink::GetInstance();
258+
auto exempt_set = sink.getFilterExemptSet();
259+
exempt_set.erase(module);
260+
sink.setFilterExemptSet(exempt_set);
261+
return true;
262+
};
263+
profile.usage = "Usage : remove <module>\r\n";
264+
profile.help = "remove module from exempts";
265+
terminal::AddFuncNode(term, exempts_node, "remove", profile);
266+
}
267+
268+
terminal::AddFuncNode(term, exempts_node, "reset",
269+
[] {
270+
auto &sink = trace::Sink::GetInstance();
271+
sink.setFilterExemptSet(trace::Sink::ExemptSet());
272+
return true;
273+
}
274+
);
275+
}
276+
}
158277
}
159278

160279
}

modules/trace/lib/sink.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,29 @@ void Sink::disable()
121121
}
122122
}
123123

124+
void Sink::setFilterExemptSet(const ExemptSet &exempt_set)
125+
{
126+
std::unique_lock<std::mutex> lk(lock_);
127+
filter_exempt_set_ = exempt_set;
128+
}
129+
130+
Sink::ExemptSet Sink::getFilterExemptSet() const
131+
{
132+
std::unique_lock<std::mutex> lk(lock_);
133+
return filter_exempt_set_;
134+
}
135+
136+
bool Sink::isFilterPassed(const std::string &module) const
137+
{
138+
std::unique_lock<std::mutex> lk(lock_);
139+
bool is_in_exempt_set = filter_exempt_set_.find(module) != filter_exempt_set_.end();
140+
141+
if (filter_strategy_ == FilterStrategy::kPermit)
142+
return !is_in_exempt_set;
143+
else
144+
return is_in_exempt_set;
145+
}
146+
124147
void Sink::commitRecord(const char *name, const char *module, uint32_t line, uint64_t end_timepoint_us, uint64_t duration_us)
125148
{
126149
if (!is_enabled_)
@@ -169,6 +192,9 @@ void Sink::onBackendRecvData(const void *data, size_t size)
169192

170193
void Sink::onBackendRecvRecord(const RecordHeader &record, const char *name, const char *module)
171194
{
195+
if (!isFilterPassed(module))
196+
return;
197+
172198
if (!checkAndCreateRecordFile())
173199
return;
174200

modules/trace/lib/sink.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <string>
2525
#include <map>
2626
#include <limits>
27+
#include <mutex>
28+
#include <set>
2729

2830
#include <tbox/util/async_pipe.h>
2931
#include <tbox/util/buffer.h>
@@ -69,6 +71,19 @@ class Sink {
6971

7072
bool isEnabled() const { return is_enabled_; }
7173

74+
//! 过滤策略
75+
enum class FilterStrategy {
76+
kPermit, //! 允许
77+
kReject, //! 拒绝
78+
};
79+
using ExemptSet = std::set<std::string>;
80+
//! 设置与获取过滤策略,默认允许或是拒绝
81+
void setFilterStrategy(FilterStrategy strategy) { filter_strategy_ = strategy; }
82+
FilterStrategy getFilterStrategy() const { return filter_strategy_; }
83+
//! 设置与获取豁免集合
84+
void setFilterExemptSet(const ExemptSet &exempt_set);
85+
ExemptSet getFilterExemptSet() const;
86+
7287
/**
7388
* \brief 提交记录
7489
*
@@ -98,6 +113,8 @@ class Sink {
98113

99114
bool checkAndCreateRecordFile();
100115

116+
bool isFilterPassed(const std::string &module) const;
117+
101118
Index allocNameIndex(const std::string &name, uint32_t line);
102119
Index allocModuleIndex(const std::string &module);
103120
Index allocThreadIndex(long thread_id);
@@ -130,6 +147,11 @@ class Sink {
130147
//! 线程号编码
131148
std::map<long, Index> thread_to_index_map_;
132149
int next_thread_index_ = 0;
150+
151+
//! 过滤相关变量
152+
mutable std::mutex lock_;
153+
FilterStrategy filter_strategy_ = FilterStrategy::kPermit; //! 默认允许
154+
ExemptSet filter_exempt_set_;
133155
};
134156

135157
}

0 commit comments

Comments
 (0)