示例#1
0
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();
}
示例#2
0
//
// 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;
}
示例#3
0
//
// 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;
}
示例#4
0
文件: chisel.cpp 项目: SpiderX/sysdig
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
	}
}