Skip to content

Commit 65ee768

Browse files
FedeDPpoiana
authored andcommitted
new(userspace/libsinsp): support plugins in sinsp-example.
Signed-off-by: Federico Di Pierro <[email protected]>
1 parent 556d868 commit 65ee768

File tree

1 file changed

+81
-11
lines changed

1 file changed

+81
-11
lines changed

userspace/libsinsp/examples/test.cpp

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,16 @@ static bool ppm_sc_modifies_state = false;
5555
static bool ppm_sc_repair_state = false;
5656
static bool ppm_sc_state_remove_io_sc = false;
5757
static bool enable_glogger = false;
58-
static string engine_string = KMOD_ENGINE; /* Default for backward compatibility. */
58+
static string engine_string;
5959
static string filter_string = "";
6060
static string file_path = "";
6161
static string bpf_path = "";
6262
static unsigned long buffer_bytes_dim = DEFAULT_DRIVER_BUFFER_BYTES_DIM;
6363
static uint64_t max_events = UINT64_MAX;
64-
static sinsp_filter_check_list s_filterlist;
64+
static std::shared_ptr<sinsp_plugin> plugin;
65+
static std::string open_params; // for source plugins, its open params
66+
static std::unique_ptr<filter_check_list> filter_list;
67+
static std::shared_ptr<sinsp_filter_factory> filter_factory;
6568

6669
sinsp_evt* get_event(sinsp& inspector, std::function<void(const std::string&)> handle_error);
6770

@@ -74,17 +77,21 @@ sinsp_evt* get_event(sinsp& inspector, std::function<void(const std::string&)> h
7477
#define PROCESS_DEFAULTS \
7578
EVENT_HEADER "ppid=%proc.ppid exe=%proc.exe args=[%proc.cmdline] " EVENT_TRAILER
7679

80+
#define PLUGIN_DEFAULTS "%evt.num %evt.time [%evt.pluginname] %evt.plugininfo"
81+
7782
#define JSON_PROCESS_DEFAULTS \
7883
"*%evt.num %evt.time %evt.category %container.id %proc.ppid %proc.pid %evt.type %proc.exe " \
7984
"%proc.cmdline %evt.args"
8085

8186
std::string default_output = EVENT_DEFAULTS;
8287
std::string process_output = PROCESS_DEFAULTS;
8388
std::string net_output = PROCESS_DEFAULTS " %fd.name";
89+
std::string plugin_output = PLUGIN_DEFAULTS;
8490

8591
static std::unique_ptr<sinsp_evt_formatter> default_formatter = nullptr;
8692
static std::unique_ptr<sinsp_evt_formatter> process_formatter = nullptr;
8793
static std::unique_ptr<sinsp_evt_formatter> net_formatter = nullptr;
94+
static std::unique_ptr<sinsp_evt_formatter> plugin_evt_formatter = nullptr;
8895

8996
static void sigint_handler(int signum) {
9097
g_interrupted = true;
@@ -104,6 +111,7 @@ Overview: Goal of sinsp-example binary is to test and debug sinsp functionality
104111
-m, --modern_bpf modern BPF probe.
105112
-k, --kmod Kernel module
106113
-s <path>, --scap_file <path> Scap file
114+
-p <path>, --plugin <path> Plugin. Path can follow the pattern "filepath.so|init_cfg|open_params".
107115
-d <dim>, --buffer_dim <dim> Dimension in bytes that every per-CPU buffer will have.
108116
-o <fields>, --output-fields <fields> Output fields string (see <filter> for supported display fields) that overwrites default output fields for all events. * at the beginning prints JSON keys with null values, else no null fields are printed.
109117
-E, --exclude-users Don't create the user/group tables
@@ -117,6 +125,15 @@ Overview: Goal of sinsp-example binary is to test and debug sinsp functionality
117125
cout << usage << endl;
118126
}
119127

128+
static void select_engine(const char* select) {
129+
if(!engine_string.empty()) {
130+
std::cerr << "While selecting " << select
131+
<< ": another engine was previously selected: " << engine_string << endl;
132+
exit(EXIT_FAILURE);
133+
}
134+
engine_string = select;
135+
}
136+
120137
#ifndef _WIN32
121138
// Parse CLI options.
122139
void parse_CLI_options(sinsp& inspector, int argc, char** argv) {
@@ -128,6 +145,7 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv) {
128145
{"modern_bpf", no_argument, 0, 'm'},
129146
{"kmod", no_argument, 0, 'k'},
130147
{"scap_file", required_argument, 0, 's'},
148+
{"plugin", required_argument, 0, 'p'},
131149
{"buffer_dim", required_argument, 0, 'd'},
132150
{"output-fields", required_argument, 0, 'o'},
133151
{"exclude-users", no_argument, 0, 'E'},
@@ -142,7 +160,7 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv) {
142160
bool format_set = false;
143161
int op;
144162
int long_index = 0;
145-
while((op = getopt_long(argc, argv, "hf:jab:mks:d:o:En:zxqgr", long_options, &long_index)) !=
163+
while((op = getopt_long(argc, argv, "hf:jab:mks:p:d:o:En:zxqgr", long_options, &long_index)) !=
146164
-1) {
147165
switch(op) {
148166
case 'h':
@@ -157,33 +175,63 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv) {
157175
default_output = DEFAULT_OUTPUT_STR;
158176
process_output = JSON_PROCESS_DEFAULTS;
159177
net_output = JSON_PROCESS_DEFAULTS " %fd.name";
178+
plugin_output = PLUGIN_DEFAULTS;
160179
}
161180
inspector.set_buffer_format(sinsp_evt::PF_JSON);
162181
break;
163182
case 'a':
164183
g_all_threads = true;
165184
break;
166185
case 'b':
167-
engine_string = BPF_ENGINE;
186+
select_engine(BPF_ENGINE);
168187
bpf_path = optarg;
169188
break;
170189
case 'm':
171-
engine_string = MODERN_BPF_ENGINE;
190+
select_engine(MODERN_BPF_ENGINE);
172191
break;
173192
case 'k':
174-
engine_string = KMOD_ENGINE;
193+
select_engine(KMOD_ENGINE);
175194
break;
176195
case 's':
177-
engine_string = SAVEFILE_ENGINE;
196+
select_engine(SAVEFILE_ENGINE);
178197
file_path = optarg;
179198
break;
199+
case 'p': {
200+
std::string pluginpath = optarg;
201+
size_t cpos = pluginpath.find('|');
202+
std::string init_config;
203+
// Extract init config from string if present
204+
if(cpos != std::string::npos) {
205+
init_config = pluginpath.substr(cpos + 1);
206+
pluginpath = pluginpath.substr(0, cpos);
207+
}
208+
cpos = init_config.find('|');
209+
if(cpos != std::string::npos) {
210+
open_params = init_config.substr(cpos + 1);
211+
init_config = init_config.substr(0, cpos);
212+
}
213+
plugin = inspector.register_plugin(pluginpath);
214+
if(std::string err; !plugin->init(init_config, err)) {
215+
std::cerr << "Error while initing plugin: " << err << std::endl;
216+
exit(EXIT_FAILURE);
217+
}
218+
if(plugin->caps() & CAP_SOURCING) {
219+
select_engine(SOURCE_PLUGIN_ENGINE);
220+
filter_list->add_filter_check(inspector.new_generic_filtercheck());
221+
}
222+
if(plugin->caps() & CAP_EXTRACTION) {
223+
filter_list->add_filter_check(sinsp_plugin::new_filtercheck(plugin));
224+
}
225+
break;
226+
}
180227
case 'd':
181228
buffer_bytes_dim = strtoul(optarg, NULL, 10);
182229
break;
183230
case 'o':
184231
default_output = optarg;
185232
process_output = optarg;
186233
net_output = optarg;
234+
plugin_output = optarg;
187235
format_set = true;
188236
break;
189237
case 'E':
@@ -293,6 +341,14 @@ void open_engine(sinsp& inspector, libsinsp::events::set<ppm_sc_code> events_sc_
293341
else if(!engine_string.compare(MODERN_BPF_ENGINE)) {
294342
inspector.open_modern_bpf(buffer_bytes_dim, DEFAULT_CPU_FOR_EACH_BUFFER, true, ppm_sc);
295343
}
344+
#endif
345+
#ifdef HAS_ENGINE_SOURCE_PLUGIN
346+
else if(!engine_string.compare(SOURCE_PLUGIN_ENGINE)) {
347+
inspector.open_plugin(plugin->name(),
348+
"",
349+
plugin->id() == 0 ? sinsp_plugin_platform::SINSP_PLATFORM_FULL
350+
: sinsp_plugin_platform::SINSP_PLATFORM_HOSTINFO);
351+
}
296352
#endif
297353
else {
298354
std::cerr << "Unknown engine" << std::endl;
@@ -357,8 +413,15 @@ static bool insert_module() {
357413
int main(int argc, char** argv) {
358414
sinsp inspector;
359415

416+
filter_list.reset(new sinsp_filter_check_list());
417+
filter_factory.reset(new sinsp_filter_factory(&inspector, *filter_list.get()));
418+
360419
#ifndef _WIN32
361420
parse_CLI_options(inspector, argc, argv);
421+
if(engine_string.empty()) {
422+
// Default for backward compat
423+
select_engine(KMOD_ENGINE);
424+
}
362425

363426
#ifdef __linux__
364427
// Try inserting the kernel module
@@ -382,7 +445,9 @@ int main(int argc, char** argv) {
382445

383446
if(!filter_string.empty()) {
384447
try {
385-
inspector.set_filter(filter_string);
448+
sinsp_filter_compiler compiler(filter_factory, filter_string);
449+
std::unique_ptr<sinsp_filter> s = compiler.compile();
450+
inspector.set_filter(std::move(s), filter_string);
386451
} catch(const sinsp_exception& e) {
387452
cerr << "[ERROR] Unable to set filter: " << e.what() << endl;
388453
}
@@ -403,10 +468,13 @@ int main(int argc, char** argv) {
403468
inspector.start_capture();
404469

405470
default_formatter =
406-
std::make_unique<sinsp_evt_formatter>(&inspector, default_output, s_filterlist);
471+
std::make_unique<sinsp_evt_formatter>(&inspector, default_output, *filter_list.get());
407472
process_formatter =
408-
std::make_unique<sinsp_evt_formatter>(&inspector, process_output, s_filterlist);
409-
net_formatter = std::make_unique<sinsp_evt_formatter>(&inspector, net_output, s_filterlist);
473+
std::make_unique<sinsp_evt_formatter>(&inspector, process_output, *filter_list.get());
474+
net_formatter =
475+
std::make_unique<sinsp_evt_formatter>(&inspector, net_output, *filter_list.get());
476+
plugin_evt_formatter =
477+
std::make_unique<sinsp_evt_formatter>(&inspector, plugin_output, *filter_list.get());
410478

411479
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
412480
uint64_t num_events = 0;
@@ -467,6 +535,8 @@ void formatted_dump(sinsp&, sinsp_evt* ev) {
467535
} else if(ev->get_category() == EC_NET || ev->get_category() == EC_IO_READ ||
468536
ev->get_category() == EC_IO_WRITE) {
469537
net_formatter->tostring(ev, output);
538+
} else if(ev->get_info()->category & EC_PLUGIN) {
539+
plugin_evt_formatter->tostring(ev, output);
470540
} else {
471541
default_formatter->tostring(ev, output);
472542
}

0 commit comments

Comments
 (0)