Exemple #1
0
int
VUT_g_Arg(const char *arg)
{

	VUT.g_arg = VSLQ_Name2Grouping(arg, -1);
	if (VUT.g_arg == -2)
		VUT_Error(1, "Ambiguous grouping type: %s", arg);
	else if (VUT.g_arg < 0)
		VUT_Error(1, "Unknown grouping type: %s", arg);
	return (1);
}
static void
openout(int append)
{

	AN(LOG.w_arg);
	if (LOG.B_opt)
		LOG.fo = VSL_WriteOpen(VUT.vsl, LOG.w_arg, append, 0);
	else
		LOG.fo = fopen(LOG.w_arg, append ? "a" : "w");
	if (LOG.fo == NULL)
		VUT_Error(1, "Can't open output file (%s)",
		    LOG.B_opt ? VSL_Error(VUT.vsl) : strerror(errno));
	VUT.dispatch_priv = LOG.fo;
}
Exemple #3
0
int
main(int argc, char **argv)
{
	int i;
	const char *colon, *ptag;
	const char *profile = "responsetime";
	pthread_t thr;
	int fnum = -1;
	struct profile cli_p = {0};
	cli_p.name = 0;

	VUT_Init(progname, argc, argv, &vopt_spec);
	AZ(pthread_cond_init(&timebend_cv, NULL));

	while ((i = getopt(argc, argv, vopt_spec.vopt_optstring)) != -1) {
		switch (i) {
		case 'h':
			/* Usage help */
			usage(0);
		case 'p':
			delay = strtod(optarg, NULL);
			if (delay <= 0)
				VUT_Error(1, "-p: invalid '%s'", optarg);
			break;
		case 'P':
			colon = strchr(optarg, ':');
			/* no colon, take the profile as a name */
			if (colon == NULL) {
				profile = optarg;
				break;
			}
			/* else it's a definition, we hope */
			if (colon == optarg + 1 &&
			    (*optarg == 'b' || *optarg == 'c')) {
				cli_p.VSL_arg = *optarg;
				ptag = colon + 1;
				colon = strchr(colon + 1, ':');
				if (colon == NULL)
					profile_error(optarg);
			} else {
				ptag = optarg;
				cli_p.VSL_arg = 'c';
			}

			assert(colon);
			if (sscanf(colon + 1, "%d:%d:%d", &cli_p.field,
			    &cli_p.hist_low, &cli_p.hist_high) != 3)
				profile_error(optarg);

			match_tag = VSL_Name2Tag(ptag, colon - ptag);
			if (match_tag < 0)
				VUT_Error(1,
				    "-P: '%s' is not a valid tag name",
				    optarg);
			cli_p.name = "custom";
			cli_p.tag = match_tag;
			profile = NULL;
			active_profile = &cli_p;

			break;
		case 'B':
			timebend = strtod(optarg, NULL);
			if (timebend == 0)
				VUT_Error(1,
				    "-B: being able to bend time does not"
				    " mean we can stop it"
				    " (invalid factor '%s')", optarg);
			if (timebend < 0)
				VUT_Error(1,
				    "-B: being able to bend time does not"
				    " mean we can make it go backwards"
				    " (invalid factor '%s')", optarg);
			break;
		default:
			if (!VUT_Arg(i, optarg))
				usage(1);
		}
	}

	if (optind != argc)
		usage(1);

	/* Check for valid grouping mode */
	assert(VUT.g_arg < VSL_g__MAX);
	if (VUT.g_arg != VSL_g_vxid && VUT.g_arg != VSL_g_request)
		VUT_Error(1, "Invalid grouping mode: %s"
		    " (only vxid and request are supported)",
		    VSLQ_grouping[VUT.g_arg]);

	if (profile) {
		for (active_profile = profiles; active_profile->name;
		     active_profile++) {
			if (strcmp(active_profile->name, profile) == 0)
				break;
		}
	}
	AN(active_profile);
	if (!active_profile->name)
		VUT_Error(1, "-P: No such profile '%s'", profile);

	assert(VUT_Arg(active_profile->VSL_arg, NULL));
	match_tag = active_profile->tag;
	fnum = active_profile->field;
	hist_low = active_profile->hist_low;
	hist_high = active_profile->hist_high;

	hist_range = hist_high - hist_low;
	hist_buckets = hist_range * HIST_RES;
	bucket_hit = calloc(sizeof *bucket_hit, hist_buckets);
	bucket_miss = calloc(sizeof *bucket_miss, hist_buckets);

	if (timebend > 0)
		t0 = VTIM_mono();

	format = malloc(4L * fnum);
	AN(format);
	for (i = 0; i < fnum - 1; i++)
		strcpy(format + 4 * i, "%*s ");
	strcpy(format + 4 * (fnum - 1), "%lf");

	log_ten = log(10.0);

	VUT_Setup();
	if (pthread_create(&thr, NULL, do_curses, NULL) != 0)
		VUT_Error(1, "pthread_create(): %s", strerror(errno));
	VUT.dispatch_f = accumulate;
	VUT.dispatch_priv = NULL;
	VUT.sighup_f = sighup;
	VUT_Main();
	end_of_file = 1;
	AZ(pthread_join(thr, NULL));
	VUT_Fini();
	exit(0);
}
Exemple #4
0
int
VUT_Main(void)
{
	struct VSL_cursor *c;
	int i = -1;

	AN(VUT.vslq);

	while (!VUT.sigint) {
		if (VUT.sighup && VUT.sighup_f) {
			/* sighup callback */
			VUT.sighup = 0;
			i = (VUT.sighup_f)();
			if (i)
				break;
		}

		if (VUT.sigusr1) {
			/* Flush and report any incomplete records */
			VUT.sigusr1 = 0;
			VSLQ_Flush(VUT.vslq, vut_dispatch, NULL);
		}

		if (VUT.vsm != NULL && !VSM_IsOpen(VUT.vsm)) {
			/* Reconnect VSM */
			AZ(VUT.r_arg);
			VTIM_sleep(0.1);
			if (VSM_Open(VUT.vsm)) {
				VSM_ResetError(VUT.vsm);
				continue;
			}
			c = VSL_CursorVSM(VUT.vsl, VUT.vsm,
			    VSL_COPT_TAIL | VSL_COPT_BATCH);
			if (c == NULL) {
				VSL_ResetError(VUT.vsl);
				VSM_Close(VUT.vsm);
				continue;
			}
			VSLQ_SetCursor(VUT.vslq, &c);
			AZ(c);
			VUT_Error(0, "Log reacquired");
		}

		i = VSLQ_Dispatch(VUT.vslq, vut_dispatch, NULL);
		if (i == 1)
			/* Call again */
			continue;
		else if (i == 0) {
			/* Nothing to do but wait */
			if (VUT.idle_f) {
				i = (VUT.idle_f)();
				if (i)
					break;
			}
			VTIM_sleep(0.01);
			continue;
		} else if (i == -1) {
			/* EOF */
			break;
		}

		if (VUT.vsm == NULL)
			break;

		/* XXX: Make continuation optional */

		VSLQ_Flush(VUT.vslq, vut_dispatch, NULL);

		if (i == -2)
			/* Abandoned */
			VUT_Error(0, "Log abandoned");
		else if (i < -2)
			/* Overrun */
			VUT_Error(0, "Log overrun");

		VSM_Close(VUT.vsm);
	}

	return (i);
}
Exemple #5
0
void
VUT_Setup(void)
{
	struct VSL_cursor *c;
	double t_start;
	int i;

	AN(VUT.vsl);
	AZ(VUT.vsm);
	AZ(VUT.vslq);

	/* Check input arguments */
	if ((VUT.n_arg == NULL ? 0 : 1) +
	    (VUT.N_arg == NULL ? 0 : 1) +
	    (VUT.r_arg == NULL ? 0 : 1) > 1)
		VUT_Error(1, "Only one of -n, -N and -r options may be used");

	/* Create and validate the query expression */
	VUT.vslq = VSLQ_New(VUT.vsl, NULL, VUT.g_arg, VUT.q_arg);
	if (VUT.vslq == NULL)
		VUT_Error(1, "Query expression error:\n%s", VSL_Error(VUT.vsl));

	/* Setup input */
	if (VUT.r_arg) {
		REPLACE(VUT.name, VUT.r_arg);
		c = VSL_CursorFile(VUT.vsl, VUT.r_arg, 0);
		if (c == NULL)
			VUT_Error(1, "Can't open log file (%s)",
			    VSL_Error(VUT.vsl));
	} else {
		VUT.vsm = VSM_New();
		AN(VUT.vsm);
		if (VUT.n_arg && VSM_n_Arg(VUT.vsm, VUT.n_arg) <= 0)
			VUT_Error(1, "%s", VSM_Error(VUT.vsm));
		if (VUT.N_arg && VSM_N_Arg(VUT.vsm, VUT.N_arg) <= 0)
			VUT_Error(1, "%s", VSM_Error(VUT.vsm));
		REPLACE(VUT.name, VSM_Name(VUT.vsm));
		t_start = NAN;
		c = NULL;
		while (1) {
			i = VSM_Open(VUT.vsm);
			if (!i)
				c = VSL_CursorVSM(VUT.vsl, VUT.vsm,
				    (VUT.d_opt ? VSL_COPT_TAILSTOP :
					VSL_COPT_TAIL)
				    | VSL_COPT_BATCH);
			if (c)
				break;

			if (isnan(t_start) && VUT.t_arg > 0.) {
				VUT_Error(0, "Can't open log -"
				    " retrying for %.0f seconds", VUT.t_arg);
				t_start = VTIM_real();
			}
			VSM_Close(VUT.vsm);
			if (VUT.t_arg <= 0.)
				break;
			if (VTIM_real() - t_start > VUT.t_arg)
				break;

			VSM_ResetError(VUT.vsm);
			VSL_ResetError(VUT.vsl);
			VTIM_sleep(0.5);
		}

		if (VUT.t_arg >= 0. && (i || !c)) {
			if (i)
				VUT_Error(1, "Can't open VSM file (%s)",
				    VSM_Error(VUT.vsm));
			else
				VUT_Error(1, "Can't open log (%s)",
				    VSL_Error(VUT.vsl));
		} else if (!isnan(t_start))
			VUT_Error(0, "Log opened");
	}

	if (c)
		VSLQ_SetCursor(VUT.vslq, &c);
	AZ(c);

	/* Signal handlers */
	(void)signal(SIGHUP, vut_sighup);
	(void)signal(SIGINT, vut_sigint);
	(void)signal(SIGTERM, vut_sigint);
	(void)signal(SIGUSR1, vut_sigusr1);

	/* Open PID file */
	if (VUT.P_arg) {
		AZ(VUT.pfh);
		VUT.pfh = VPF_Open(VUT.P_arg, 0644, NULL);
		if (VUT.pfh == NULL)
			VUT_Error(1, "%s: %s", VUT.P_arg, strerror(errno));
	}

	/* Daemon mode */
	if (VUT.D_opt && varnish_daemon(0, 0) == -1)
		VUT_Error(1, "Daemon mode: %s", strerror(errno));

	/* Write PID and setup exit handler */
	if (VUT.pfh != NULL) {
		VPF_Write(VUT.pfh);
		AZ(atexit(vut_vpf_remove));
	}
}
Exemple #6
0
int
VUT_Arg(int opt, const char *arg)
{
	int i;
	char *p;

	switch (opt) {
	case 'd':
		/* Head */
		VUT.d_opt = 1;
		return (1);
	case 'D':
		/* Daemon mode */
		VUT.D_opt = 1;
		return (1);
	case 'g':
		/* Grouping */
		return (VUT_g_Arg(arg));
	case 'k':
		/* Log transaction limit */
		VUT.k_arg = (int)strtol(arg, &p, 10);
		if (*p != '\0' || VUT.k_arg <= 0)
			VUT_Error(1, "-k: Invalid number '%s'", arg);
		return (1);
	case 'n':
		/* Varnish instance name */
		REPLACE(VUT.n_arg, arg);
		return (1);
	case 'N':
		/* Varnish stale VSM file */
		REPLACE(VUT.N_arg, arg);
		return (1);
	case 'P':
		/* PID file */
		REPLACE(VUT.P_arg, arg);
		return (1);
	case 'q':
		/* Query to use */
		REPLACE(VUT.q_arg, arg);
		return (1);
	case 'r':
		/* Binary file input */
		REPLACE(VUT.r_arg, arg);
		return (1);
	case 't':
		/* VSM connect timeout */
		if (!strcasecmp("off", arg))
			VUT.t_arg = -1.;
		else {
			VUT.t_arg = VNUM(arg);
			if (isnan(VUT.t_arg))
				VUT_Error(1, "-t: Syntax error");
			if (VUT.t_arg < 0.)
				VUT_Error(1, "-t: Range error");
		}
		return (1);
	case 'V':
		/* Print version number and exit */
		VCS_Message(VUT.progname);
		exit(0);
	default:
		AN(VUT.vsl);
		i = VSL_Arg(VUT.vsl, opt, arg);
		if (i < 0)
			VUT_Error(1, "%s", VSL_Error(VUT.vsl));
		return (i);
	}
}
int
main(int argc, char * const *argv)
{
	int opt;

	VUT_Init(progname, argc, argv, &vopt_spec);
	memset(&LOG, 0, sizeof LOG);

	while ((opt = getopt(argc, argv, vopt_spec.vopt_optstring)) != -1) {
		switch (opt) {
		case 'a':
			/* Append to file */
			LOG.a_opt = 1;
			break;
		case 'A':
			/* Text output */
			LOG.A_opt = 1;
			break;
		case 'h':
			/* Usage help */
			usage(0);
			break;
		case 'w':
			/* Write to file */
			REPLACE(LOG.w_arg, optarg);
			break;
		default:
			if (!VUT_Arg(opt, optarg))
				usage(1);
		}
	}

	if (optind != argc)
		usage(1);

	if (VUT.D_opt && !LOG.w_arg)
		VUT_Error(1, "Missing -w option");

	/* Setup output */
	if (LOG.A_opt || !LOG.w_arg)
		VUT.dispatch_f = VSL_PrintTransactions;
	else
		VUT.dispatch_f = VSL_WriteTransactions;
	VUT.sighup_f = sighup;
	if (LOG.w_arg) {
		openout(LOG.a_opt);
		AN(LOG.fo);
		if (VUT.D_opt)
			VUT.sighup_f = rotateout;
	} else
		LOG.fo = stdout;
	VUT.idle_f = flushout;

	VUT_Setup();
	VUT_Main();
	VUT_Fini();

	(void)flushout();

	exit(0);
}
Exemple #8
0
int
main(int argc, char * const *argv)
{
	struct VSM_data *vd;
	double t_arg = 5.0, t_start = NAN;
	int once = 0, xml = 0, json = 0, f_list = 0, curses = 0;
	signed char opt;
	int i;

	VUT_Init(progname, argc, argv, &vopt_spec);
	vd = VSM_New();
	AN(vd);

	while ((opt = getopt(argc, argv, vopt_spec.vopt_optstring)) != -1) {
		switch (opt) {
		case '1':
			once = 1;
			break;
		case 'h':
			/* Usage help */
			usage(0);
		case 'l':
			f_list = 1;
			break;
		case 't':
			if (!strcasecmp(optarg, "off"))
				t_arg = -1.;
			else {
				t_arg = VNUM(optarg);
				if (isnan(t_arg))
					VUT_Error(1, "-t: Syntax error");
				if (t_arg < 0.)
					VUT_Error(1, "-t: Range error");
			}
			break;
		case 'V':
			VCS_Message("varnishstat");
			exit(0);
		case 'x':
			xml = 1;
			break;
		case 'j':
			json = 1;
			break;
		default:
			i = VSC_Arg(vd, opt, optarg);
			if (i < 0)
				VUT_Error(1, "%s", VSM_Error(vd));
			if (!i)
				usage(1);
		}
	}

	if (optind != argc)
		usage(1);

	if (!(xml || json || once || f_list))
		curses = 1;

	while (1) {
		i = VSM_Open(vd);
		if (!i)
			break;
		if (isnan(t_start) && t_arg > 0.) {
			fprintf(stderr, "Can't open log -"
			    " retrying for %.0f seconds\n", t_arg);
			t_start = VTIM_real();
		}
		if (t_arg <= 0.)
			break;
		if (VTIM_real() - t_start > t_arg)
			break;
		VSM_ResetError(vd);
		VTIM_sleep(0.5);
	}

	if (curses) {
		if (i && t_arg >= 0.)
			VUT_Error(1, "%s", VSM_Error(vd));
		do_curses(vd, 1.0);
		exit(0);
	}

	if (i)
		VUT_Error(1, "%s", VSM_Error(vd));

	if (xml)
		do_xml(vd);
	else if (json)
		do_json(vd);
	else if (once)
		do_once(vd);
	else if (f_list)
		list_fields(vd);
	else
		assert(0);

	exit(0);
}