Exemplo n.º 1
0
static void
devstats(void)
{
	int dn, state;
	long double transfers_per_second;
	long double busy_seconds;
	long tmp;

	for (state = 0; state < CPUSTATES; ++state) {
		tmp = cur.cp_time[state];
		cur.cp_time[state] -= last.cp_time[state];
		last.cp_time[state] = tmp;
	}

	busy_seconds = cur.snap_time - last.snap_time;

	for (dn = 0; dn < num_devices; dn++) {
		int di;

		if ((dev_select[dn].selected == 0)
		 || (dev_select[dn].selected > maxshowdevs))
			continue;

		di = dev_select[dn].position;

		if (devstat_compute_statistics(&cur.dinfo->devices[di],
		    &last.dinfo->devices[di], busy_seconds,
		    DSM_TRANSFERS_PER_SECOND, &transfers_per_second,
		    DSM_NONE) != 0)
			errx(1, "%s", devstat_errbuf);

		(void)printf("%3.0Lf ", transfers_per_second);
	}
}
Exemplo n.º 2
0
static void
dinfo(int dn, int lc, struct statinfo *now, struct statinfo *then)
{
	long double transfers_per_second;
	long double kb_per_transfer, mb_per_second;
	long double elapsed_time, device_busy;
	int di;

	di = dev_select[dn].position;

	if (then != NULL) {
		/* Calculate relative to previous sample */
		elapsed_time = now->snap_time - then->snap_time;
	} else {
		/* Calculate relative to device creation */
		elapsed_time = now->snap_time - devstat_compute_etime(
		    &now->dinfo->devices[di].creation_time, NULL);
	}

	if (devstat_compute_statistics(&now->dinfo->devices[di], then ?
	    &then->dinfo->devices[di] : NULL, elapsed_time,
	    DSM_KB_PER_TRANSFER, &kb_per_transfer,
	    DSM_TRANSFERS_PER_SECOND, &transfers_per_second,
	    DSM_MB_PER_SECOND, &mb_per_second,
	    DSM_BUSY_PCT, &device_busy,
	    DSM_NONE) != 0)
		errx(1, "%s", devstat_errbuf);

	lc = DISKCOL + lc * 6;
	putlongdouble(kb_per_transfer, DISKROW + 1, lc, 5, 2, 0);
	putlongdouble(transfers_per_second, DISKROW + 2, lc, 5, 0, 0);
	putlongdouble(mb_per_second, DISKROW + 3, lc, 5, 2, 0);
	putlongdouble(device_busy, DISKROW + 4, lc, 5, 0, 0);
}
Exemplo n.º 3
0
static int
devstats(int row, int _col, int dn)
{
	long double transfers_per_second;
	long double kb_per_transfer, mb_per_second;
	long double busy_seconds;
	int di;

	di = dev_select[dn].position;

	busy_seconds = cur.snap_time - last.snap_time;

	if (devstat_compute_statistics(&cur.dinfo->devices[di],
	    &last.dinfo->devices[di], busy_seconds,
	    DSM_KB_PER_TRANSFER, &kb_per_transfer,
	    DSM_TRANSFERS_PER_SECOND, &transfers_per_second,
	    DSM_MB_PER_SECOND, &mb_per_second, DSM_NONE) != 0)
		errx(1, "%s", devstat_errbuf);

	if (numbers) {
		mvwprintw(wnd, row, _col, " %5.2Lf %3.0Lf %5.2Lf ",
			 kb_per_transfer, transfers_per_second,
			 mb_per_second);
		return(row);
	}
	wmove(wnd, row++, _col);
	histogram(mb_per_second, 50, .5);
	wmove(wnd, row++, _col);
	histogram(transfers_per_second, 50, .5);
	if (kbpt) {
		wmove(wnd, row++, _col);
		histogram(kb_per_transfer, 50, .5);
	}

	return(row);

}
Exemplo n.º 4
0
static void
devstats(int perf_select, long double etime, int havelast)
{
    int dn;
    long double transfers_per_second, transfers_per_second_read;
    long double transfers_per_second_write;
    long double kb_per_transfer, mb_per_second, mb_per_second_read;
    long double mb_per_second_write;
    u_int64_t total_bytes, total_transfers, total_blocks;
    u_int64_t total_bytes_read, total_transfers_read;
    u_int64_t total_bytes_write, total_transfers_write;
    long double busy_pct, busy_time;
    u_int64_t queue_len;
    long double total_mb, blocks_per_second, total_duration;
    long double ms_per_other, ms_per_read, ms_per_write, ms_per_transaction;
    int firstline = 1;
    char *devicename;

    if (xflag > 0) {
        printf("                        extended device statistics  ");
        if (Tflag > 0)
            printf("      tty ");
        if (Cflag > 0)
            printf("           cpu ");
        printf("\n");
        if (Iflag == 0) {
            printf("device     r/s   w/s     kr/s     kw/s "
                   " ms/r  ms/w  ms/o  ms/t qlen  %%b  ");
        } else {
            printf("device           r/i         w/i         kr/i"
                   "         kw/i qlen   tsvc_t/i      sb/i  ");
        }
        if (Tflag > 0)
            printf("tin  tout ");
        if (Cflag > 0)
            printf("us ni sy in id ");
        printf("\n");
    }

    for (dn = 0; dn < num_devices; dn++) {
        int di;

        if (((perf_select == 0) && (dev_select[dn].selected == 0))
                || (dev_select[dn].selected > maxshowdevs))
            continue;

        di = dev_select[dn].position;

        if (devstat_compute_statistics(&cur.dinfo->devices[di],
                                       havelast ? &last.dinfo->devices[di] : NULL, etime,
                                       DSM_TOTAL_BYTES, &total_bytes,
                                       DSM_TOTAL_BYTES_READ, &total_bytes_read,
                                       DSM_TOTAL_BYTES_WRITE, &total_bytes_write,
                                       DSM_TOTAL_TRANSFERS, &total_transfers,
                                       DSM_TOTAL_TRANSFERS_READ, &total_transfers_read,
                                       DSM_TOTAL_TRANSFERS_WRITE, &total_transfers_write,
                                       DSM_TOTAL_BLOCKS, &total_blocks,
                                       DSM_KB_PER_TRANSFER, &kb_per_transfer,
                                       DSM_TRANSFERS_PER_SECOND, &transfers_per_second,
                                       DSM_TRANSFERS_PER_SECOND_READ, &transfers_per_second_read,
                                       DSM_TRANSFERS_PER_SECOND_WRITE, &transfers_per_second_write,
                                       DSM_MB_PER_SECOND, &mb_per_second,
                                       DSM_MB_PER_SECOND_READ, &mb_per_second_read,
                                       DSM_MB_PER_SECOND_WRITE, &mb_per_second_write,
                                       DSM_BLOCKS_PER_SECOND, &blocks_per_second,
                                       DSM_MS_PER_TRANSACTION, &ms_per_transaction,
                                       DSM_MS_PER_TRANSACTION_READ, &ms_per_read,
                                       DSM_MS_PER_TRANSACTION_WRITE, &ms_per_write,
                                       DSM_MS_PER_TRANSACTION_OTHER, &ms_per_other,
                                       DSM_BUSY_PCT, &busy_pct,
                                       DSM_QUEUE_LENGTH, &queue_len,
                                       DSM_TOTAL_DURATION, &total_duration,
                                       DSM_TOTAL_BUSY_TIME, &busy_time,
                                       DSM_NONE) != 0)
            errx(1, "%s", devstat_errbuf);

        if (perf_select != 0) {
            dev_select[dn].bytes = total_bytes;
            if ((dev_select[dn].selected == 0)
                    || (dev_select[dn].selected > maxshowdevs))
                continue;
        }

        if (Kflag > 0 || xflag > 0) {
            int block_size = cur.dinfo->devices[di].block_size;
            total_blocks = total_blocks * (block_size ?
                                           block_size : 512) / 1024;
        }

        if (xflag > 0) {
            if (asprintf(&devicename, "%s%d",
                         cur.dinfo->devices[di].device_name,
                         cur.dinfo->devices[di].unit_number) == -1)
                err(1, "asprintf");
            /*
             * If zflag is set, skip any devices with zero I/O.
             */
            if (zflag == 0 || transfers_per_second_read > 0.05 ||
                    transfers_per_second_write > 0.05 ||
                    mb_per_second_read > ((long double).0005)/1024 ||
                    mb_per_second_write > ((long double).0005)/1024 ||
                    busy_pct > 0.5) {
                if (Iflag == 0)
                    printf("%-8.8s %5d %5d %8.1Lf "
                           "%8.1Lf %5d %5d %5d %5d "
                           "%4" PRIu64 " %3.0Lf ",
                           devicename,
                           (int)transfers_per_second_read,
                           (int)transfers_per_second_write,
                           mb_per_second_read * 1024,
                           mb_per_second_write * 1024,
                           (int)ms_per_read, (int)ms_per_write,
                           (int)ms_per_other,
                           (int)ms_per_transaction,
                           queue_len, busy_pct);
                else
                    printf("%-8.8s %11.1Lf %11.1Lf "
                           "%12.1Lf %12.1Lf %4" PRIu64
                           " %10.1Lf %9.1Lf ",
                           devicename,
                           (long double)total_transfers_read,
                           (long double)total_transfers_write,
                           (long double)
                           total_bytes_read / 1024,
                           (long double)
                           total_bytes_write / 1024,
                           queue_len,
                           total_duration, busy_time);
                if (firstline) {
                    /*
                     * If this is the first device
                     * we're printing, also print
                     * CPU or TTY stats if requested.
                     */
                    firstline = 0;
                    if (Tflag > 0)
                        printf("%4.0Lf%5.0Lf",
                               cur.tk_nin / etime,
                               cur.tk_nout / etime);
                    if (Cflag > 0)
                        cpustats();
                }
                printf("\n");
            }
            free(devicename);
        } else if (oflag > 0) {
            int msdig = (ms_per_transaction < 100.0) ? 1 : 0;

            if (Iflag == 0)
                printf("%4.0Lf%4.0Lf%5.*Lf ",
                       blocks_per_second,
                       transfers_per_second,
                       msdig,
                       ms_per_transaction);
            else
                printf("%4.1" PRIu64 "%4.1" PRIu64 "%5.*Lf ",
                       total_blocks,
                       total_transfers,
                       msdig,
                       ms_per_transaction);
        } else {
            if (Iflag == 0)
                printf(" %5.2Lf %3.0Lf %5.2Lf ",
                       kb_per_transfer,
                       transfers_per_second,
                       mb_per_second);
            else {
                total_mb = total_bytes;
                total_mb /= 1024 * 1024;

                printf(" %5.2Lf %3.1" PRIu64 " %5.2Lf ",
                       kb_per_transfer,
                       total_transfers,
                       total_mb);
            }
        }
    }
    if (xflag > 0 && zflag > 0 && firstline == 1 &&
            (Tflag > 0 || Cflag > 0)) {
        /*
         * If zflag is set and we did not print any device
         * lines I/O because they were all zero,
         * print TTY/CPU stats.
         */
        printf("%52s","");
        if (Tflag > 0)
            printf("%4.0Lf %5.0Lf", cur.tk_nin / etime,
                   cur.tk_nout / etime);
        if (Cflag > 0)
            cpustats();
        printf("\n");
    }
}
Exemplo n.º 5
0
int
main(int argc, char **argv)
{
	int error, i, quit;
	int curx, cury, maxx, maxy, line_len, loop, max_flen;
	struct devstat *gsp, *gsq;
	void *sp, *sq;
	double dt;
	struct timespec tp, tq;
	struct gmesh gmp;
	struct gprovider *pp;
	struct gconsumer *cp;
	struct gident *gid;
	regex_t f_re, tmp_f_re;
	short cf, cb;
	char *p;
	char f_s[100], pf_s[100], tmp_f_s[100];
	const char *line;
	long double ld[13];
	uint64_t u64;
	EditLine *el;
	History *hist;
	HistEvent hist_ev;

	hist = NULL;
	el = NULL;
	maxx = -1;
	curx = -1;
	loop = 1;
	/* Turn on batch mode if output is not tty. */
	if (!isatty(fileno(stdout)))
		flag_b = 1;

	f_s[0] = '\0';
	while ((i = getopt(argc, argv, "abdcf:I:op")) != -1) {
		switch (i) {
		case 'a':
			flag_a = 1;
			break;
		case 'b':
			flag_b = 1;
			break;
		case 'c':
			flag_c = 1;
			break;
		case 'd':
			flag_d = 1;
			break;
		case 'f':
			if (strlen(optarg) > sizeof(f_s) - 1)
				errx(EX_USAGE, "Filter string too long");
			if (regcomp(&f_re, optarg, REG_EXTENDED) != 0)
				errx(EX_USAGE,
				    "Invalid filter - see re_format(7)");
			strncpy(f_s, optarg, sizeof(f_s));
			break;
		case 'o':
			flag_o = 1;
			break;
		case 'I':
			p = NULL;
			i = strtoul(optarg, &p, 0);
			if (p == optarg || errno == EINVAL ||
			    errno == ERANGE) {
				errx(1, "Invalid argument to -I");
			} else if (!strcmp(p, "s"))
				i *= 1000000;
			else if (!strcmp(p, "ms"))
				i *= 1000;
			else if (!strcmp(p, "us"))
				i *= 1;
			flag_I = i;
			break;
		case 'p':
			flag_p = 1;
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		usage();

	i = geom_gettree(&gmp);
	if (i != 0)
		err(1, "geom_gettree = %d", i);
	error = geom_stats_open();
	if (error)
		err(1, "geom_stats_open()");
	sq = NULL;
	sq = geom_stats_snapshot_get();
	if (sq == NULL)
		err(1, "geom_stats_snapshot()");
	if (!flag_b) {
		/* Setup curses */
		initscr();
		start_color();
		use_default_colors();
		pair_content(0, &cf, &cb);
		init_pair(1, COLOR_GREEN, cb);
		init_pair(2, COLOR_MAGENTA, cb);
		init_pair(3, COLOR_RED, cb);
		cbreak();
		noecho();
		nonl();
		nodelay(stdscr, 1);
		intrflush(stdscr, FALSE);
		keypad(stdscr, TRUE);
		/* Setup libedit */
		hist = history_init();
		if (hist == NULL)
			err(EX_SOFTWARE, "history_init()");
		history(hist, &hist_ev, H_SETSIZE, 100);
		el = el_init("gstat", stdin, stdout, stderr);
		if (el == NULL)
			err(EX_SOFTWARE, "el_init");
		el_set(el, EL_EDITOR, "emacs");
		el_set(el, EL_SIGNAL, 1);
		el_set(el, EL_HIST, history, hist);
		el_set(el, EL_PROMPT, el_prompt);
		if (f_s[0] != '\0')
			history(hist, &hist_ev, H_ENTER, f_s);
	}
	geom_stats_snapshot_timestamp(sq, &tq);
	for (quit = 0; !quit;) {
		sp = geom_stats_snapshot_get();
		if (sp == NULL)
			err(1, "geom_stats_snapshot()");
		geom_stats_snapshot_timestamp(sp, &tp);
		dt = tp.tv_sec - tq.tv_sec;
		dt += (tp.tv_nsec - tq.tv_nsec) * 1e-9;
		tq = tp;
	
		geom_stats_snapshot_reset(sp);
		geom_stats_snapshot_reset(sq);
		move(0,0);
		PRINTMSG("dT: %5.3fs  w: %.3fs", dt, (float)flag_I / 1000000);
		if (f_s[0] != '\0') {
			PRINTMSG("  filter: ");
			if (!flag_b) {
				getyx(stdscr, cury, curx);
				getmaxyx(stdscr, maxy, maxx);
			}
			strncpy(pf_s, f_s, sizeof(pf_s));
			max_flen = maxx - curx - 1;
			if ((int)strlen(f_s) > max_flen && max_flen >= 0) {
				if (max_flen > 3)
					pf_s[max_flen - 3] = '.';
				if (max_flen > 2)
					pf_s[max_flen - 2] = '.';
				if (max_flen > 1)
					pf_s[max_flen - 1] = '.';
				pf_s[max_flen] = '\0';
			}
			PRINTMSG("%s", pf_s);
		}
		PRINTMSG("\n");
		PRINTMSG(" L(q)  ops/s   ");
		PRINTMSG(" r/s   kBps   ms/r   ");
		PRINTMSG(" w/s   kBps   ms/w   ");
		if (flag_d)
			PRINTMSG(" d/s   kBps   ms/d   ");
		if (flag_o)
			PRINTMSG(" o/s   ms/o   ");
		PRINTMSG("%%busy Name\n");
		for (;;) {
			gsp = geom_stats_snapshot_next(sp);
			gsq = geom_stats_snapshot_next(sq);
			if (gsp == NULL || gsq == NULL)
				break;
			if (gsp->id == NULL)
				continue;
			gid = geom_lookupid(&gmp, gsp->id);
			if (gid == NULL) {
				geom_deletetree(&gmp);
				i = geom_gettree(&gmp);
				if (i != 0)
					err(1, "geom_gettree = %d", i);
				gid = geom_lookupid(&gmp, gsp->id);
			}
			if (gid == NULL)
				continue;
			if (gid->lg_what == ISCONSUMER && !flag_c)
				continue;
			if (flag_p && gid->lg_what == ISPROVIDER &&
			   ((struct gprovider *)(gid->lg_ptr))->lg_geom->lg_rank != 1)
				continue;
			/* Do not print past end of window */
			if (!flag_b) {
				getyx(stdscr, cury, curx);
				if (curx > 0)
					continue;
			}
			if ((gid->lg_what == ISPROVIDER
			    || gid->lg_what == ISCONSUMER) && f_s[0] != '\0') {
				pp = gid->lg_ptr;
				if ((regexec(&f_re, pp->lg_name, 0, NULL, 0)
				     != 0))
				  continue;
			}
			if (gsp->sequence0 != gsp->sequence1) {
				PRINTMSG("*\n");
				continue;
			}
			devstat_compute_statistics(gsp, gsq, dt, 
			    DSM_QUEUE_LENGTH, &u64,
			    DSM_TRANSFERS_PER_SECOND, &ld[0],

			    DSM_TRANSFERS_PER_SECOND_READ, &ld[1],
			    DSM_MB_PER_SECOND_READ, &ld[2],
			    DSM_MS_PER_TRANSACTION_READ, &ld[3],

			    DSM_TRANSFERS_PER_SECOND_WRITE, &ld[4],
			    DSM_MB_PER_SECOND_WRITE, &ld[5],
			    DSM_MS_PER_TRANSACTION_WRITE, &ld[6],

			    DSM_BUSY_PCT, &ld[7],

			    DSM_TRANSFERS_PER_SECOND_FREE, &ld[8],
			    DSM_MB_PER_SECOND_FREE, &ld[9],
			    DSM_MS_PER_TRANSACTION_FREE, &ld[10],

			    DSM_TRANSFERS_PER_SECOND_OTHER, &ld[11],
			    DSM_MS_PER_TRANSACTION_OTHER, &ld[12],

			    DSM_NONE);

			if (flag_a && ld[7] < 0.1) {
				*gsq = *gsp;
				continue;
			}

			PRINTMSG(" %4ju", (uintmax_t)u64);
			PRINTMSG(" %6.0f", (double)ld[0]);
			PRINTMSG(" %6.0f", (double)ld[1]);
			PRINTMSG(" %6.0f", (double)ld[2] * 1024);
			if (ld[3] > 1e3) 
				PRINTMSG(" %6.0f", (double)ld[3]);
			else
				PRINTMSG(" %6.1f", (double)ld[3]);
			PRINTMSG(" %6.0f", (double)ld[4]);
			PRINTMSG(" %6.0f", (double)ld[5] * 1024);
			if (ld[6] > 1e3) 
				PRINTMSG(" %6.0f", (double)ld[6]);
			else
				PRINTMSG(" %6.1f", (double)ld[6]);

			if (flag_d) {
				PRINTMSG(" %6.0f", (double)ld[8]);
				PRINTMSG(" %6.0f", (double)ld[9] * 1024);
				if (ld[10] > 1e3) 
					PRINTMSG(" %6.0f", (double)ld[10]);
				else
					PRINTMSG(" %6.1f", (double)ld[10]);
			}

			if (flag_o) {
				PRINTMSG(" %6.0f", (double)ld[11]);
				if (ld[12] > 1e3) 
					PRINTMSG(" %6.0f", (double)ld[12]);
				else
					PRINTMSG(" %6.1f", (double)ld[12]);
			}

			if (ld[7] > 80)
				i = 3;
			else if (ld[7] > 50)
				i = 2;
			else 
				i = 1;
			if (!flag_b)
				attron(COLOR_PAIR(i));
			PRINTMSG(" %6.1lf", (double)ld[7]);
			if (!flag_b) {
				attroff(COLOR_PAIR(i));
				PRINTMSG("|");
			} else
				PRINTMSG(" ");
			if (gid == NULL) {
				PRINTMSG(" ??");
			} else if (gid->lg_what == ISPROVIDER) {
				pp = gid->lg_ptr;
				PRINTMSG(" %s", pp->lg_name);
			} else if (gid->lg_what == ISCONSUMER) {
				cp = gid->lg_ptr;
				PRINTMSG(" %s/%s/%s",
				    cp->lg_geom->lg_class->lg_name,
				    cp->lg_geom->lg_name,
				    cp->lg_provider->lg_name);
			}
			if (!flag_b)
				clrtoeol();
			PRINTMSG("\n");
			*gsq = *gsp;
		}
		geom_stats_snapshot_free(sp);
		if (flag_b) {
			/* We loop extra to make sure we get the information. */
			if (!loop)
				break;
			loop = 0;
			usleep(flag_I);
			continue;
		}
		getyx(stdscr, cury, curx);
		getmaxyx(stdscr, maxy, maxx);
		clrtobot();
		if (maxy - 1 <= cury)
			move(maxy - 1, 0);
		refresh();
		usleep(flag_I);
		while((i = getch()) != ERR) {
			switch (i) {
			case '>':
				flag_I *= 2;
				break;
			case '<':
				flag_I /= 2;
				if (flag_I < 1000)
					flag_I = 1000;
				break;
			case 'c':
				flag_c = !flag_c;
				break;
			case 'f':
				move(0,0);
				clrtoeol();
				refresh();
				line = el_gets(el, &line_len);
				if (line == NULL)
					err(1, "el_gets");
				if (line_len > 1)
					history(hist, &hist_ev, H_ENTER, line);
				strncpy(tmp_f_s, line, sizeof(f_s));
				if ((p = strchr(tmp_f_s, '\n')) != NULL)
					*p = '\0';
				/*
				 * We have to clear since we messed up
				 * curses idea of the screen by using
				 * libedit.
				 */
				clear();
				refresh();
				if (regcomp(&tmp_f_re, tmp_f_s, REG_EXTENDED)
				    != 0) {
					move(0, 0);
					printw("Invalid filter");
					refresh();
					sleep(1);
				} else {
					strncpy(f_s, tmp_f_s, sizeof(f_s));
					f_re = tmp_f_re;
				}
				break;
			case 'F':
				f_s[0] = '\0';
				break;
			case 'q':
				quit = 1;
				break;
			default:
				break;
			}
		}
	}

	if (!flag_b) {
		endwin();
		el_end(el);
	}
	exit(EX_OK);
}