std::string sinsp_user_event::to_string(uint64_t timestamp, std::string&& name, std::string&& description, std::string&& scope, tag_map_t&& tags, uint32_t sev) { const std::string from("\""); const std::string to("\\\""); std::ostringstream ostr; ostr << "timestamp: " << timestamp << '\n' << "name: \"" << replace_in_place(name, from, to) << "\"\n" "description: \"" << replace_in_place(description, from, to) << "\"\n" "scope: \"" << replace_in_place(scope, from, to) << "\"\n"; if(sev != UNKNOWN_SEVERITY) { ostr << "priority: " << sev << '\n'; } if(tags.size()) { ostr << "tags:"; for(auto& tag : tags) { ostr << "\n \"" << replace(tag.first, from, to) << "\": \"" << replace_in_place(tag.second, from, to) << '"'; } } ostr << std::flush; g_logger.log(ostr.str(), sinsp_logger::SEV_DEBUG); return ostr.str(); }
// // MAIN // int main(int argc, char **argv) { int res = EXIT_SUCCESS; sinsp* inspector = NULL; vector<string> infiles; string outfile; int op; uint64_t cnt = -1; bool quiet = false; bool absolute_times = false; bool is_filter_display = false; bool verbose = false; bool list_flds = false; bool print_progress = false; bool compress = false; sinsp_evt::param_fmt event_buffer_format = sinsp_evt::PF_NORMAL; sinsp_filter* display_filter = NULL; double duration = 1; captureinfo cinfo; string output_format; uint32_t snaplen = 0; int long_index = 0; int32_t n_filterargs = 0; int cflag = 0; string cname; vector<summary_table_entry>* summary_table = NULL; string timefmt = "%evt.time"; static struct option long_options[] = { {"print-ascii", no_argument, 0, 'A' }, {"abstimes", no_argument, 0, 'a' }, #ifdef HAS_CHISELS {"chisel", required_argument, 0, 'c' }, {"list-chisels", no_argument, &cflag, 1 }, #endif {"compress", no_argument, 0, 'z' }, {"displayflt", no_argument, 0, 'd' }, {"debug", no_argument, 0, 'D'}, {"help", no_argument, 0, 'h' }, #ifdef HAS_CHISELS {"chisel-info", required_argument, 0, 'i' }, #endif {"json", no_argument, 0, 'j' }, {"list", no_argument, 0, 'l' }, {"list-events", no_argument, 0, 'L' }, {"numevents", required_argument, 0, 'n' }, {"progress", required_argument, 0, 'P' }, {"print", required_argument, 0, 'p' }, {"quiet", no_argument, 0, 'q' }, {"readfile", required_argument, 0, 'r' }, {"snaplen", required_argument, 0, 's' }, {"summary", no_argument, 0, 'S' }, {"timetype", required_argument, 0, 't' }, {"verbose", no_argument, 0, 'v' }, {"writefile", required_argument, 0, 'w' }, {"print-hex", no_argument, 0, 'x'}, {"print-hex-ascii", no_argument, 0, 'X'}, {0, 0, 0, 0} }; output_format = "*%evt.num <TIME> %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.args"; // output_format = DEFAULT_OUTPUT_STR; try { inspector = new sinsp(); #ifdef HAS_CHISELS add_chisel_dirs(inspector); #endif // // Parse the args // while((op = getopt_long(argc, argv, "Aac:dDhi:jlLn:Pp:qr:Ss:t:vw:xXz", long_options, &long_index)) != -1) { switch(op) { case 'A': if(event_buffer_format != sinsp_evt::PF_NORMAL) { fprintf(stderr, "you cannot specify more than one output format\n"); delete inspector; return EXIT_SUCCESS; } event_buffer_format = sinsp_evt::PF_EOLS; break; case 'a': absolute_times = true; break; case 0: if(cflag != 1 && cflag != 2) { break; } if(cflag == 2) { cname = optarg; } #ifdef HAS_CHISELS case 'c': { if(cflag == 0) { string ostr(optarg); if(ostr.size() >= 1) { if(ostr == "l") { cflag = 1; } } } if(cflag == 1) { vector<chisel_desc> chlist; sinsp_chisel::get_chisel_list(&chlist); list_chisels(&chlist, true); delete inspector; return EXIT_SUCCESS; } sinsp_chisel* ch = new sinsp_chisel(inspector, optarg); parse_chisel_args(ch, inspector, optind, argc, argv, &n_filterargs); g_chisels.push_back(ch); } #endif break; case 'D': inspector->set_debug_mode(true); break; #ifdef HAS_CHISELS // --chisel-info and -i case 'i': { cname = optarg; vector<chisel_desc> chlist; sinsp_chisel::get_chisel_list(&chlist); for(uint32_t j = 0; j < chlist.size(); j++) { if(chlist[j].m_name == cname) { print_chisel_info(&chlist[j]); delete inspector; return EXIT_SUCCESS; } } throw sinsp_exception("chisel " + cname + " not found - use -cl to list them."); } break; #endif case 'd': is_filter_display = true; break; case 'j': // throw sinsp_exception("json output not yet implemented"); if(event_buffer_format != sinsp_evt::PF_NORMAL) { fprintf(stderr, "you cannot specify more than one output format\n"); delete inspector; return EXIT_SUCCESS; } event_buffer_format = sinsp_evt::PF_JSON; break; case 'h': usage(); delete inspector; return EXIT_SUCCESS; case 'l': list_flds = true; break; case 'L': list_events(inspector); delete inspector; return EXIT_SUCCESS; case 'n': cnt = atoi(optarg); if(cnt <= 0) { throw sinsp_exception(string("invalid packet count") + optarg); res = EXIT_FAILURE; goto exit; } break; case 'P': print_progress = true; break; case 'p': if(string(optarg) == "p") { // // -pp shows the default output format, useful if the user wants to tweak it. // replace_in_place(output_format, "<TIME>", timefmt); printf("%s\n", output_format.c_str()); delete inspector; return EXIT_SUCCESS; } else { output_format = optarg; } break; case 'q': quiet = true; break; case 'r': infiles.push_back(optarg); break; case 'S': summary_table = new vector<summary_table_entry>; for(uint32_t j = 0; j < PPM_EVENT_MAX; j++) { summary_table->push_back(summary_table_entry(j, false)); } for(uint32_t j = 0; j < PPM_SC_MAX * 2; j++) { summary_table->push_back(summary_table_entry(j, true)); } break; case 's': snaplen = atoi(optarg); break; case 't': { string tms(optarg); if(tms == "h") { timefmt = "%evt.time"; } else if(tms == "a") { timefmt = "%evt.rawtime.s.%evt.rawtime.ns"; } else if(tms == "r") { timefmt = "%evt.reltime.s.%evt.reltime.ns"; } else if(tms == "d") { timefmt = "%evt.latency.s.%evt.latency.ns"; } } break; case 'v': verbose = true; break; case 'w': outfile = optarg; quiet = true; break; case 'x': if(event_buffer_format != sinsp_evt::PF_NORMAL) { fprintf(stderr, "you cannot specify more than one output format\n"); delete inspector; return EXIT_SUCCESS; } event_buffer_format = sinsp_evt::PF_HEX; break; case 'X': if(event_buffer_format != sinsp_evt::PF_NORMAL) { fprintf(stderr, "you cannot specify more than one output format\n"); delete inspector; return EXIT_SUCCESS; } event_buffer_format = sinsp_evt::PF_HEXASCII; break; case 'z': compress = true; break; default: break; } } inspector->set_buffer_format(event_buffer_format); // // If -l was specified, print the fields and exit // if(list_flds) { if(verbose) { // // -ll shows the fields verbosely, i.e. with more information // like the type // list_fields(true); } else { list_fields(false); } res = EXIT_SUCCESS; goto exit; } string filter; // // the filter is at the end of the command line // if(optind + n_filterargs < argc) { #ifdef HAS_FILTERING for(int32_t j = optind + n_filterargs; j < argc; j++) { filter += argv[j]; if(j < argc) { filter += " "; } } if(is_filter_display) { display_filter = new sinsp_filter(inspector, filter); } #else fprintf(stderr, "filtering not compiled.\n"); res = EXIT_FAILURE; goto exit; #endif } if(signal(SIGINT, signal_callback) == SIG_ERR) { fprintf(stderr, "An error occurred while setting SIGINT signal handler.\n"); res = EXIT_FAILURE; goto exit; } if(signal(SIGTERM, signal_callback) == SIG_ERR) { fprintf(stderr, "An error occurred while setting SIGTERM signal handler.\n"); res = EXIT_FAILURE; goto exit; } // // Insert the right time format based on the -t flag // replace_in_place(output_format, "<TIME>", timefmt); // // Create the event formatter // sinsp_evt_formatter formatter(inspector, output_format); for(uint32_t j = 0; j < infiles.size() || infiles.size() == 0; j++) { #ifdef HAS_FILTERING if(filter.size() && !is_filter_display) { inspector->set_filter(filter); } #endif // // Launch the capture // bool open_success = true; if(infiles.size() != 0) { initialize_chisels(); // // We have a file to open // inspector->open(infiles[j]); } else { if(j > 0) { break; } initialize_chisels(); // // No file to open, this is a live capture // #if defined(HAS_CAPTURE) if(print_progress) { fprintf(stderr, "the -P flag cannot be used with live captures.\n"); res = EXIT_FAILURE; goto exit; } try { inspector->open(""); } catch(sinsp_exception e) { open_success = false; } #else // // Starting live capture // If this fails on Windows and OSX, don't try with any driver // inspector->open(""); #endif // // Starting the live capture failed, try to load the driver with // modprobe. // if(!open_success) { open_success = true; system("modprobe sysdig-probe > /dev/null 2> /dev/null"); inspector->open(""); } } if(snaplen != 0) { inspector->set_snaplen(snaplen); } duration = ((double)clock()) / CLOCKS_PER_SEC; if(outfile != "") { inspector->autodump_start(outfile, compress); } // // Notify the chisels that the capture is starting // chisels_on_capture_start(); cinfo = do_inspect(inspector, cnt, quiet, absolute_times, print_progress, display_filter, summary_table, &formatter); duration = ((double)clock()) / CLOCKS_PER_SEC - duration; scap_stats cstats; inspector->get_capture_stats(&cstats); if(verbose) { fprintf(stderr, "Driver Events:%" PRIu64 "\nDriver Drops:%" PRIu64 "\n", cstats.n_evts, cstats.n_drops); fprintf(stderr, "Elapsed time: %.3lf, Captured Events: %" PRIu64 ", %.2lf eps\n", duration, cinfo.m_nevts, (double)cinfo.m_nevts / duration); } // // Done. Close the capture. // inspector->close(); } } catch(sinsp_exception& e) { cerr << e.what() << endl; handle_end_of_file(print_progress); res = EXIT_FAILURE; } catch(...) { handle_end_of_file(print_progress); res = EXIT_FAILURE; } exit: // // If there's a summary table, sort and print it // if(summary_table != NULL) { print_summary_table(inspector, summary_table, 100); } free_chisels(); if(inspector) { delete inspector; } if(display_filter) { delete display_filter; } #ifdef _WIN32 _CrtDumpMemoryLeaks(); #endif return res; }
// // ARGUMENT PARSING AND PROGRAM SETUP // sysdig_init_res sysdig_init(int argc, char **argv) { sysdig_init_res res; sinsp* inspector = NULL; vector<string> infiles; string outfile; int op; uint64_t cnt = -1; bool quiet = false; bool is_filter_display = false; bool verbose = false; bool list_flds = false; bool print_progress = false; bool compress = false; sinsp_evt::param_fmt event_buffer_format = sinsp_evt::PF_NORMAL; sinsp_filter* display_filter = NULL; double duration = 1; captureinfo cinfo; string output_format; uint32_t snaplen = 0; int long_index = 0; int32_t n_filterargs = 0; int cflag = 0; bool jflag = false; string cname; vector<summary_table_entry>* summary_table = NULL; string timefmt = "%evt.time"; // These variables are for the cycle_writer engine int duration_seconds = 0; int rollover_mb = 0; int file_limit = 0; bool do_cycle = false; static struct option long_options[] = { {"print-ascii", no_argument, 0, 'A' }, {"print-base64", no_argument, 0, 'b' }, #ifdef HAS_CHISELS {"chisel", required_argument, 0, 'c' }, {"list-chisels", no_argument, &cflag, 1 }, #endif {"compress", no_argument, 0, 'z' }, {"displayflt", no_argument, 0, 'd' }, {"debug", no_argument, 0, 'D'}, {"fatfile", no_argument, 0, 'F'}, #ifndef DISABLE_CGW {"seconds", required_argument, 0, 'G' }, #endif {"help", no_argument, 0, 'h' }, #ifdef HAS_CHISELS {"chisel-info", required_argument, 0, 'i' }, #endif #ifndef DISABLE_CGW {"file-size", required_argument, 0, 'C' }, #endif {"json", no_argument, 0, 'j' }, {"list", no_argument, 0, 'l' }, {"list-events", no_argument, 0, 'L' }, {"numevents", required_argument, 0, 'n' }, {"progress", required_argument, 0, 'P' }, {"print", required_argument, 0, 'p' }, {"quiet", no_argument, 0, 'q' }, {"readfile", required_argument, 0, 'r' }, {"snaplen", required_argument, 0, 's' }, {"summary", no_argument, 0, 'S' }, {"timetype", required_argument, 0, 't' }, {"verbose", no_argument, 0, 'v' }, {"version", no_argument, 0, 0 }, {"writefile", required_argument, 0, 'w' }, #ifndef DISABLE_CGW {"limit", required_argument, 0, 'W' }, #endif {"print-hex", no_argument, 0, 'x'}, {"print-hex-ascii", no_argument, 0, 'X'}, {0, 0, 0, 0} }; output_format = "*%evt.num <TIME> %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info"; // output_format = DEFAULT_OUTPUT_STR; try { inspector = new sinsp(); #ifdef HAS_CHISELS add_chisel_dirs(inspector); #endif // // Parse the args // while((op = getopt_long(argc, argv, "Abc:" #ifndef DISABLE_CGW "C:" #endif "dDF" #ifndef DISABLE_CGW "G:" #endif "hi:jlLn:Pp:qr:Ss:t:v" #ifndef DISABLE_CGW "W:" #endif "w:xXz", long_options, &long_index)) != -1) { switch(op) { case 'A': if(event_buffer_format != sinsp_evt::PF_NORMAL) { fprintf(stderr, "you cannot specify more than one output format\n"); delete inspector; return sysdig_init_res(EXIT_SUCCESS); } event_buffer_format = sinsp_evt::PF_EOLS; break; case 'b': if(event_buffer_format != sinsp_evt::PF_NORMAL) { fprintf(stderr, "you cannot specify more than one output format\n"); delete inspector; return sysdig_init_res(EXIT_SUCCESS); } event_buffer_format = sinsp_evt::PF_BASE64; break; case 0: if(cflag != 1 && cflag != 2) { break; } if(cflag == 2) { cname = optarg; } #ifdef HAS_CHISELS case 'c': { if(cflag == 0) { string ostr(optarg); if(ostr.size() >= 1) { if(ostr == "l") { cflag = 1; } } } if(cflag == 1) { vector<chisel_desc> chlist; sinsp_chisel::get_chisel_list(&chlist); list_chisels(&chlist, true); delete inspector; return sysdig_init_res(EXIT_SUCCESS); } sinsp_chisel* ch = new sinsp_chisel(inspector, optarg); parse_chisel_args(ch, inspector, optind, argc, argv, &n_filterargs); g_chisels.push_back(ch); } #endif break; #ifndef DISABLE_CGW // File-size case 'C': rollover_mb = atoi(optarg); if(rollover_mb <= 0) { throw sinsp_exception(string("invalid file size") + optarg); res.m_res = EXIT_FAILURE; goto exit; } // -C always implicates a cycle do_cycle = true; break; #endif case 'D': inspector->set_debug_mode(true); break; case 'F': inspector->set_fatfile_dump_mode(true); break; #ifndef DISABLE_CGW // Number of seconds between roll-over case 'G': duration_seconds = atoi(optarg); if(duration_seconds <= 0) { throw sinsp_exception(string("invalid duration") + optarg); res.m_res = EXIT_FAILURE; goto exit; } break; #endif #ifdef HAS_CHISELS // --chisel-info and -i case 'i': { cname = optarg; vector<chisel_desc> chlist; sinsp_chisel::get_chisel_list(&chlist); for(uint32_t j = 0; j < chlist.size(); j++) { if(chlist[j].m_name == cname) { print_chisel_info(&chlist[j]); delete inspector; return sysdig_init_res(EXIT_SUCCESS); } } throw sinsp_exception("chisel " + cname + " not found - use -cl to list them."); } break; #endif case 'd': is_filter_display = true; break; case 'j': // // set the json flag to 1 for now, the data format will depend from the print format parameters // jflag = true; break; case 'h': usage(); delete inspector; return sysdig_init_res(EXIT_SUCCESS); case 'l': list_flds = true; break; case 'L': list_events(inspector); delete inspector; return sysdig_init_res(EXIT_SUCCESS); case 'n': cnt = atoi(optarg); if(cnt <= 0) { throw sinsp_exception(string("invalid event count ") + optarg); res.m_res = EXIT_FAILURE; goto exit; } break; case 'P': print_progress = true; break; case 'p': if(string(optarg) == "p") { // // -pp shows the default output format, useful if the user wants to tweak it. // replace_in_place(output_format, "<TIME>", timefmt); printf("%s\n", output_format.c_str()); delete inspector; return sysdig_init_res(EXIT_SUCCESS); } else { output_format = optarg; } break; case 'q': quiet = true; break; case 'r': infiles.push_back(optarg); break; case 'S': summary_table = new vector<summary_table_entry>; for(uint32_t j = 0; j < PPM_EVENT_MAX; j++) { summary_table->push_back(summary_table_entry(j, false)); } for(uint32_t j = 0; j < PPM_SC_MAX * 2; j++) { summary_table->push_back(summary_table_entry(j, true)); } break; case 's': snaplen = atoi(optarg); break; case 't': { string tms(optarg); if(tms == "h") { timefmt = "%evt.time"; } else if(tms == "a") { timefmt = "%evt.rawtime.s.%evt.rawtime.ns"; } else if(tms == "r") { timefmt = "%evt.reltime.s.%evt.reltime.ns"; } else if(tms == "d") { timefmt = "%evt.latency.s.%evt.latency.ns"; } else if(tms == "D") { timefmt = "%evt.deltatime.s.%evt.deltatime.ns"; } else { fprintf(stderr, "invalid modifier for flag -t\n"); delete inspector; return sysdig_init_res(EXIT_FAILURE); } } break; case 'v': verbose = true; break; case 'w': outfile = optarg; quiet = true; break; #ifndef DISABLE_CGW // Number of capture files to cycle through case 'W': file_limit = atoi(optarg); if(file_limit <= 0) { throw sinsp_exception(string("invalid file limit") + optarg); res.m_res = EXIT_FAILURE; goto exit; } break; #endif case 'x': if(event_buffer_format != sinsp_evt::PF_NORMAL) { fprintf(stderr, "you cannot specify more than one output format\n"); delete inspector; return sysdig_init_res(EXIT_FAILURE); } event_buffer_format = sinsp_evt::PF_HEX; break; case 'X': if(event_buffer_format != sinsp_evt::PF_NORMAL) { fprintf(stderr, "you cannot specify more than one output format\n"); delete inspector; return sysdig_init_res(EXIT_FAILURE); } event_buffer_format = sinsp_evt::PF_HEXASCII; break; case 'z': compress = true; break; default: break; } if(string(long_options[long_index].name) == "version") { printf("sysdig version %s\n", SYSDIG_VERSION); delete inspector; return sysdig_init_res(EXIT_SUCCESS); } } // // If -j was specified the event_buffer_format must be rewritten to account for it // if(jflag) { switch (event_buffer_format) { case sinsp_evt::PF_NORMAL: event_buffer_format = sinsp_evt::PF_JSON; break; case sinsp_evt::PF_EOLS: event_buffer_format = sinsp_evt::PF_JSONEOLS; break; case sinsp_evt::PF_HEX: event_buffer_format = sinsp_evt::PF_JSONHEX; break; case sinsp_evt::PF_HEXASCII: event_buffer_format = sinsp_evt::PF_JSONHEXASCII; break; case sinsp_evt::PF_BASE64: event_buffer_format = sinsp_evt::PF_JSONBASE64; break; default: // do nothing break; } } inspector->set_buffer_format(event_buffer_format); // // If -l was specified, print the fields and exit // if(list_flds) { if(verbose) { // // -ll shows the fields verbosely, i.e. with more information // like the type // list_fields(true); } else { list_fields(false); } res.m_res = EXIT_SUCCESS; goto exit; } string filter; // // the filter is at the end of the command line // if(optind + n_filterargs < argc) { #ifdef HAS_FILTERING for(int32_t j = optind + n_filterargs; j < argc; j++) { filter += argv[j]; if(j < argc) { filter += " "; } } if(is_filter_display) { display_filter = new sinsp_filter(inspector, filter); } #else fprintf(stderr, "filtering not compiled.\n"); res.m_res = EXIT_FAILURE; goto exit; #endif } if(signal(SIGINT, signal_callback) == SIG_ERR) { fprintf(stderr, "An error occurred while setting SIGINT signal handler.\n"); res.m_res = EXIT_FAILURE; goto exit; } if(signal(SIGTERM, signal_callback) == SIG_ERR) { fprintf(stderr, "An error occurred while setting SIGTERM signal handler.\n"); res.m_res = EXIT_FAILURE; goto exit; } // // Insert the right time format based on the -t flag // replace_in_place(output_format, "<TIME>", timefmt); // // Create the event formatter // sinsp_evt_formatter formatter(inspector, output_format); for(uint32_t j = 0; j < infiles.size() || infiles.size() == 0; j++) { #ifdef HAS_FILTERING if(filter.size() && !is_filter_display) { inspector->set_filter(filter); } #endif // // Launch the capture // bool open_success = true; if(infiles.size() != 0) { initialize_chisels(); // // We have a file to open // inspector->open(infiles[j]); } else { if(j > 0) { break; } initialize_chisels(); // // No file to open, this is a live capture // #if defined(HAS_CAPTURE) if(print_progress) { fprintf(stderr, "the -P flag cannot be used with live captures.\n"); res.m_res = EXIT_FAILURE; goto exit; } try { inspector->open(""); } catch(sinsp_exception e) { open_success = false; } #else // // Starting live capture // If this fails on Windows and OSX, don't try with any driver // inspector->open(""); #endif // // Starting the live capture failed, try to load the driver with // modprobe. // if(!open_success) { open_success = true; system("modprobe sysdig-probe > /dev/null 2> /dev/null"); inspector->open(""); } } if(snaplen != 0) { inspector->set_snaplen(snaplen); } duration = ((double)clock()) / CLOCKS_PER_SEC; if(outfile != "") { inspector->setup_cycle_writer(outfile, rollover_mb, duration_seconds, file_limit, do_cycle, compress); inspector->autodump_next_file(); } // // Notify the chisels that the capture is starting // chisels_on_capture_start(); cinfo = do_inspect(inspector, cnt, quiet, jflag, print_progress, display_filter, summary_table, &formatter); duration = ((double)clock()) / CLOCKS_PER_SEC - duration; scap_stats cstats; inspector->get_capture_stats(&cstats); if(verbose) { fprintf(stderr, "Driver Events:%" PRIu64 "\nDriver Drops:%" PRIu64 "\n", cstats.n_evts, cstats.n_drops); fprintf(stderr, "Elapsed time: %.3lf, Captured Events: %" PRIu64 ", %.2lf eps\n", duration, cinfo.m_nevts, (double)cinfo.m_nevts / duration); } // // Done. Close the capture. // inspector->close(); } } catch(sinsp_capture_interrupt_exception&) { handle_end_of_file(print_progress); } catch(sinsp_exception& e) { cerr << e.what() << endl; handle_end_of_file(print_progress); res.m_res = EXIT_FAILURE; } catch(...) { handle_end_of_file(print_progress); res.m_res = EXIT_FAILURE; } exit: // // If any of the chisels is requesting another run, // for(vector<sinsp_chisel*>::iterator it = g_chisels.begin(); it != g_chisels.end(); ++it) { string na; if((*it)->get_nextrun_args(&na)) { res.m_next_run_args = sinsp_split(na, ' '); } } // // If there's a summary table, sort and print it // if(summary_table != NULL) { print_summary_table(inspector, summary_table, 100); } // // Free all the stuff that was allocated // free_chisels(); if(inspector) { delete inspector; } if(display_filter) { delete display_filter; } return res; }
void sinsp_chisel::set_args(vector<string>* argvals) { uint32_t j, k; m_argvals = *argvals; if(!m_ls) { const Json::Value args = (*m_root)["info"]["arguments"]; // // Validate the arguments // if(m_argvals.size() != args.size()) { throw sinsp_exception("wrong number of parameters for chisel " + m_filename); } // // Apply the arguments // const Json::Value clst = (*m_root)["chisels"]; for(j = 0; j < clst.size(); j++) { string filter = clst[j]["filter"].asString(); for(k = 0; k < args.size(); k++) { replace_in_place(filter, string("$") + args[k]["name"].asString(), string(m_argvals[k])); } string formatter = clst[j]["format"].asString(); for(k = 0; k < args.size(); k++) { replace_in_place(formatter, string("$") + args[k]["name"].asString(), string(m_argvals[k])); } chiselinfo* ci = new chiselinfo(m_inspector); ci->init(filter, formatter); m_subchisels.push_back(ci); } } else { #ifdef HAS_LUA_CHISELS // // Validate the arguments // if(m_argvals.size() != m_lua_script_info.m_args.size()) { throw sinsp_exception("wrong number of parameters for chisel " + m_filename); } // // Push the arguments // for(k = 0; k < m_lua_script_info.m_args.size(); k++) { lua_getglobal(m_ls, "on_set_arg"); if(!lua_isfunction(m_ls, -1)) { lua_pop(m_ls, 1); throw sinsp_exception("chisel " + m_filename + " misses a set_arg() function."); } lua_pushstring(m_ls, m_lua_script_info.m_args[k].m_name.c_str()); lua_pushstring(m_ls, m_argvals[k].c_str()); // // call get_info() // if(lua_pcall(m_ls, 2, 1, 0) != 0) { throw sinsp_exception(m_filename + " chisel error: " + lua_tostring(m_ls, -1)); } if(!lua_isboolean(m_ls, -1)) { throw sinsp_exception(m_filename + " chisel error: wrong set_arg() return value."); } int sares = lua_toboolean(m_ls, -1); if(!sares) { throw sinsp_exception("set_arg() for chisel " + m_filename + " failed."); } lua_pop(m_ls, 1); } #endif } }