@@ -55,13 +55,16 @@ static bool ppm_sc_modifies_state = false;
55
55
static bool ppm_sc_repair_state = false ;
56
56
static bool ppm_sc_state_remove_io_sc = false ;
57
57
static bool enable_glogger = false ;
58
- static string engine_string = KMOD_ENGINE; /* Default for backward compatibility. */
58
+ static string engine_string;
59
59
static string filter_string = " " ;
60
60
static string file_path = " " ;
61
61
static string bpf_path = " " ;
62
62
static unsigned long buffer_bytes_dim = DEFAULT_DRIVER_BUFFER_BYTES_DIM;
63
63
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;
65
68
66
69
sinsp_evt* get_event (sinsp& inspector, std::function<void (const std::string&)> handle_error);
67
70
@@ -74,17 +77,21 @@ sinsp_evt* get_event(sinsp& inspector, std::function<void(const std::string&)> h
74
77
#define PROCESS_DEFAULTS \
75
78
EVENT_HEADER " ppid=%proc.ppid exe=%proc.exe args=[%proc.cmdline] " EVENT_TRAILER
76
79
80
+ #define PLUGIN_DEFAULTS " %evt.num %evt.time [%evt.pluginname] %evt.plugininfo"
81
+
77
82
#define JSON_PROCESS_DEFAULTS \
78
83
" *%evt.num %evt.time %evt.category %container.id %proc.ppid %proc.pid %evt.type %proc.exe " \
79
84
" %proc.cmdline %evt.args"
80
85
81
86
std::string default_output = EVENT_DEFAULTS;
82
87
std::string process_output = PROCESS_DEFAULTS;
83
88
std::string net_output = PROCESS_DEFAULTS " %fd.name" ;
89
+ std::string plugin_output = PLUGIN_DEFAULTS;
84
90
85
91
static std::unique_ptr<sinsp_evt_formatter> default_formatter = nullptr ;
86
92
static std::unique_ptr<sinsp_evt_formatter> process_formatter = nullptr ;
87
93
static std::unique_ptr<sinsp_evt_formatter> net_formatter = nullptr ;
94
+ static std::unique_ptr<sinsp_evt_formatter> plugin_evt_formatter = nullptr ;
88
95
89
96
static void sigint_handler (int signum) {
90
97
g_interrupted = true ;
@@ -104,6 +111,7 @@ Overview: Goal of sinsp-example binary is to test and debug sinsp functionality
104
111
-m, --modern_bpf modern BPF probe.
105
112
-k, --kmod Kernel module
106
113
-s <path>, --scap_file <path> Scap file
114
+ -p <path>, --plugin <path> Plugin. Path can follow the pattern "filepath.so|init_cfg|open_params".
107
115
-d <dim>, --buffer_dim <dim> Dimension in bytes that every per-CPU buffer will have.
108
116
-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.
109
117
-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
117
125
cout << usage << endl;
118
126
}
119
127
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
+
120
137
#ifndef _WIN32
121
138
// Parse CLI options.
122
139
void parse_CLI_options (sinsp& inspector, int argc, char ** argv) {
@@ -128,6 +145,7 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv) {
128
145
{" modern_bpf" , no_argument, 0 , ' m' },
129
146
{" kmod" , no_argument, 0 , ' k' },
130
147
{" scap_file" , required_argument, 0 , ' s' },
148
+ {" plugin" , required_argument, 0 , ' p' },
131
149
{" buffer_dim" , required_argument, 0 , ' d' },
132
150
{" output-fields" , required_argument, 0 , ' o' },
133
151
{" exclude-users" , no_argument, 0 , ' E' },
@@ -142,7 +160,7 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv) {
142
160
bool format_set = false ;
143
161
int op;
144
162
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)) !=
146
164
-1 ) {
147
165
switch (op) {
148
166
case ' h' :
@@ -157,33 +175,63 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv) {
157
175
default_output = DEFAULT_OUTPUT_STR;
158
176
process_output = JSON_PROCESS_DEFAULTS;
159
177
net_output = JSON_PROCESS_DEFAULTS " %fd.name" ;
178
+ plugin_output = PLUGIN_DEFAULTS;
160
179
}
161
180
inspector.set_buffer_format (sinsp_evt::PF_JSON);
162
181
break ;
163
182
case ' a' :
164
183
g_all_threads = true ;
165
184
break ;
166
185
case ' b' :
167
- engine_string = BPF_ENGINE;
186
+ select_engine ( BPF_ENGINE) ;
168
187
bpf_path = optarg;
169
188
break ;
170
189
case ' m' :
171
- engine_string = MODERN_BPF_ENGINE;
190
+ select_engine ( MODERN_BPF_ENGINE) ;
172
191
break ;
173
192
case ' k' :
174
- engine_string = KMOD_ENGINE;
193
+ select_engine ( KMOD_ENGINE) ;
175
194
break ;
176
195
case ' s' :
177
- engine_string = SAVEFILE_ENGINE;
196
+ select_engine ( SAVEFILE_ENGINE) ;
178
197
file_path = optarg;
179
198
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
+ }
180
227
case ' d' :
181
228
buffer_bytes_dim = strtoul (optarg, NULL , 10 );
182
229
break ;
183
230
case ' o' :
184
231
default_output = optarg;
185
232
process_output = optarg;
186
233
net_output = optarg;
234
+ plugin_output = optarg;
187
235
format_set = true ;
188
236
break ;
189
237
case ' E' :
@@ -293,6 +341,14 @@ void open_engine(sinsp& inspector, libsinsp::events::set<ppm_sc_code> events_sc_
293
341
else if (!engine_string.compare (MODERN_BPF_ENGINE)) {
294
342
inspector.open_modern_bpf (buffer_bytes_dim, DEFAULT_CPU_FOR_EACH_BUFFER, true , ppm_sc);
295
343
}
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
+ }
296
352
#endif
297
353
else {
298
354
std::cerr << " Unknown engine" << std::endl;
@@ -357,8 +413,15 @@ static bool insert_module() {
357
413
int main (int argc, char ** argv) {
358
414
sinsp inspector;
359
415
416
+ filter_list.reset (new sinsp_filter_check_list ());
417
+ filter_factory.reset (new sinsp_filter_factory (&inspector, *filter_list.get ()));
418
+
360
419
#ifndef _WIN32
361
420
parse_CLI_options (inspector, argc, argv);
421
+ if (engine_string.empty ()) {
422
+ // Default for backward compat
423
+ select_engine (KMOD_ENGINE);
424
+ }
362
425
363
426
#ifdef __linux__
364
427
// Try inserting the kernel module
@@ -382,7 +445,9 @@ int main(int argc, char** argv) {
382
445
383
446
if (!filter_string.empty ()) {
384
447
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);
386
451
} catch (const sinsp_exception& e) {
387
452
cerr << " [ERROR] Unable to set filter: " << e.what () << endl;
388
453
}
@@ -403,10 +468,13 @@ int main(int argc, char** argv) {
403
468
inspector.start_capture ();
404
469
405
470
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 () );
407
472
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 ());
410
478
411
479
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now ();
412
480
uint64_t num_events = 0 ;
@@ -467,6 +535,8 @@ void formatted_dump(sinsp&, sinsp_evt* ev) {
467
535
} else if (ev->get_category () == EC_NET || ev->get_category () == EC_IO_READ ||
468
536
ev->get_category () == EC_IO_WRITE) {
469
537
net_formatter->tostring (ev, output);
538
+ } else if (ev->get_info ()->category & EC_PLUGIN) {
539
+ plugin_evt_formatter->tostring (ev, output);
470
540
} else {
471
541
default_formatter->tostring (ev, output);
472
542
}
0 commit comments