- Allow gstat to print values to different kind of outputs.

- Introduce batch mode, where gstat will collect the numbers, print them, and
  exit.
- Document batch mode in the gstat man page.

Submitted by:	anders
This commit is contained in:
Ulf Lilleengen 2008-10-07 10:25:27 +00:00
parent ffe72750d9
commit a0312e48c1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=183665
2 changed files with 108 additions and 73 deletions

View File

@ -46,6 +46,8 @@ The options are as follows:
.Bl -tag -width indent .Bl -tag -width indent
.It Fl a .It Fl a
Only display providers that are at least 0.1% busy. Only display providers that are at least 0.1% busy.
.It Fl b
Batch mode. Collect numbers, print and exit.
.It Fl c .It Fl c
Enable display of Enable display of
.Xr geom 4 .Xr geom 4

View File

@ -51,9 +51,16 @@
#include <sysexits.h> #include <sysexits.h>
#include <unistd.h> #include <unistd.h>
static int flag_a, flag_c, flag_d; static int flag_a, flag_b, flag_c, flag_d;
static int flag_I = 1000000; static int flag_I = 1000000;
#define PRINTMSG(...) do { \
if (flag_b && !loop) \
printf(__VA_ARGS__); \
else if (!flag_b) \
printw(__VA_ARGS__); \
} while(0)
static void usage(void); static void usage(void);
static const char* static const char*
@ -67,7 +74,7 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int error, i, quit; int error, i, quit;
int curx, cury, maxx, maxy, line_len, max_flen; int curx, cury, maxx, maxy, line_len, loop, max_flen;
struct devstat *gsp, *gsq; struct devstat *gsp, *gsq;
void *sp, *sq; void *sp, *sq;
double dt; double dt;
@ -87,12 +94,20 @@ main(int argc, char **argv)
History *hist; History *hist;
HistEvent hist_ev; HistEvent hist_ev;
hist = NULL;
el = NULL;
maxx = -1;
curx = -1;
loop = 1;
f_s[0] = '\0'; f_s[0] = '\0';
while ((i = getopt(argc, argv, "adcf:I:")) != -1) { while ((i = getopt(argc, argv, "adcf:I:b")) != -1) {
switch (i) { switch (i) {
case 'a': case 'a':
flag_a = 1; flag_a = 1;
break; break;
case 'b':
flag_b = 1;
break;
case 'c': case 'c':
flag_c = 1; flag_c = 1;
break; break;
@ -141,34 +156,36 @@ main(int argc, char **argv)
sq = geom_stats_snapshot_get(); sq = geom_stats_snapshot_get();
if (sq == NULL) if (sq == NULL)
err(1, "geom_stats_snapshot()"); err(1, "geom_stats_snapshot()");
/* Setup curses */ if (!flag_b) {
initscr(); /* Setup curses */
start_color(); initscr();
use_default_colors(); start_color();
pair_content(0, &cf, &cb); use_default_colors();
init_pair(1, COLOR_GREEN, cb); pair_content(0, &cf, &cb);
init_pair(2, COLOR_MAGENTA, cb); init_pair(1, COLOR_GREEN, cb);
init_pair(3, COLOR_RED, cb); init_pair(2, COLOR_MAGENTA, cb);
cbreak(); init_pair(3, COLOR_RED, cb);
noecho(); cbreak();
nonl(); noecho();
nodelay(stdscr, 1); nonl();
intrflush(stdscr, FALSE); nodelay(stdscr, 1);
keypad(stdscr, TRUE); intrflush(stdscr, FALSE);
/* Setup libedit */ keypad(stdscr, TRUE);
hist = history_init(); /* Setup libedit */
if (hist == NULL) hist = history_init();
err(EX_SOFTWARE, "history_init()"); if (hist == NULL)
history(hist, &hist_ev, H_SETSIZE, 100); err(EX_SOFTWARE, "history_init()");
el = el_init("gstat", stdin, stdout, stderr); history(hist, &hist_ev, H_SETSIZE, 100);
if (el == NULL) el = el_init("gstat", stdin, stdout, stderr);
err(EX_SOFTWARE, "el_init"); if (el == NULL)
el_set(el, EL_EDITOR, "emacs"); err(EX_SOFTWARE, "el_init");
el_set(el, EL_SIGNAL, 1); el_set(el, EL_EDITOR, "emacs");
el_set(el, EL_HIST, history, hist); el_set(el, EL_SIGNAL, 1);
el_set(el, EL_PROMPT, el_prompt); el_set(el, EL_HIST, history, hist);
if (f_s[0] != '\0') el_set(el, EL_PROMPT, el_prompt);
history(hist, &hist_ev, H_ENTER, f_s); if (f_s[0] != '\0')
history(hist, &hist_ev, H_ENTER, f_s);
}
geom_stats_snapshot_timestamp(sq, &tq); geom_stats_snapshot_timestamp(sq, &tq);
for (quit = 0; !quit;) { for (quit = 0; !quit;) {
sp = geom_stats_snapshot_get(); sp = geom_stats_snapshot_get();
@ -182,12 +199,13 @@ main(int argc, char **argv)
geom_stats_snapshot_reset(sp); geom_stats_snapshot_reset(sp);
geom_stats_snapshot_reset(sq); geom_stats_snapshot_reset(sq);
move(0,0); move(0,0);
printw("dT: %5.3fs w: %.3fs", PRINTMSG("dT: %5.3fs w: %.3fs", dt, (float)flag_I / 1000000);
dt, (float)flag_I / 1000000);
if (f_s[0] != '\0') { if (f_s[0] != '\0') {
printw(" filter: "); PRINTMSG(" filter: ");
getyx(stdscr, cury, curx); if (!flag_b) {
getmaxyx(stdscr, maxy, maxx); getyx(stdscr, cury, curx);
getmaxyx(stdscr, maxy, maxx);
}
strncpy(pf_s, f_s, sizeof(pf_s)); strncpy(pf_s, f_s, sizeof(pf_s));
max_flen = maxx - curx - 1; max_flen = maxx - curx - 1;
if ((int)strlen(f_s) > max_flen && max_flen >= 0) { if ((int)strlen(f_s) > max_flen && max_flen >= 0) {
@ -199,15 +217,15 @@ main(int argc, char **argv)
pf_s[max_flen - 1] = '.'; pf_s[max_flen - 1] = '.';
pf_s[max_flen] = '\0'; pf_s[max_flen] = '\0';
} }
printw("%s", pf_s); PRINTMSG("%s", pf_s);
} }
printw("\n"); PRINTMSG("\n");
printw(" L(q) ops/s "); PRINTMSG(" L(q) ops/s ");
printw(" r/s kBps ms/r "); PRINTMSG(" r/s kBps ms/r ");
printw(" w/s kBps ms/w "); PRINTMSG(" w/s kBps ms/w ");
if (flag_d) if (flag_d)
printw(" d/s kBps ms/d "); PRINTMSG(" d/s kBps ms/d ");
printw("%%busy Name\n"); PRINTMSG("%%busy Name\n");
for (;;) { for (;;) {
gsp = geom_stats_snapshot_next(sp); gsp = geom_stats_snapshot_next(sp);
gsq = geom_stats_snapshot_next(sq); gsq = geom_stats_snapshot_next(sq);
@ -228,9 +246,11 @@ main(int argc, char **argv)
if (gid->lg_what == ISCONSUMER && !flag_c) if (gid->lg_what == ISCONSUMER && !flag_c)
continue; continue;
/* Do not print past end of window */ /* Do not print past end of window */
getyx(stdscr, cury, curx); if (!flag_b) {
if (curx > 0) getyx(stdscr, cury, curx);
continue; if (curx > 0)
continue;
}
if ((gid->lg_what == ISPROVIDER if ((gid->lg_what == ISPROVIDER
|| gid->lg_what == ISCONSUMER) && f_s[0] != '\0') { || gid->lg_what == ISCONSUMER) && f_s[0] != '\0') {
pp = gid->lg_ptr; pp = gid->lg_ptr;
@ -239,7 +259,7 @@ main(int argc, char **argv)
continue; continue;
} }
if (gsp->sequence0 != gsp->sequence1) { if (gsp->sequence0 != gsp->sequence1) {
printw("*\n"); PRINTMSG("*\n");
continue; continue;
} }
devstat_compute_statistics(gsp, gsq, dt, devstat_compute_statistics(gsp, gsq, dt,
@ -265,28 +285,28 @@ main(int argc, char **argv)
continue; continue;
} }
printw(" %4ju", (uintmax_t)u64); PRINTMSG(" %4ju", (uintmax_t)u64);
printw(" %6.0f", (double)ld[0]); PRINTMSG(" %6.0f", (double)ld[0]);
printw(" %6.0f", (double)ld[1]); PRINTMSG(" %6.0f", (double)ld[1]);
printw(" %6.0f", (double)ld[2] * 1024); PRINTMSG(" %6.0f", (double)ld[2] * 1024);
if (ld[3] > 1e3) if (ld[3] > 1e3)
printw(" %6.0f", (double)ld[3]); PRINTMSG(" %6.0f", (double)ld[3]);
else else
printw(" %6.1f", (double)ld[3]); PRINTMSG(" %6.1f", (double)ld[3]);
printw(" %6.0f", (double)ld[4]); PRINTMSG(" %6.0f", (double)ld[4]);
printw(" %6.0f", (double)ld[5] * 1024); PRINTMSG(" %6.0f", (double)ld[5] * 1024);
if (ld[6] > 1e3) if (ld[6] > 1e3)
printw(" %6.0f", (double)ld[6]); PRINTMSG(" %6.0f", (double)ld[6]);
else else
printw(" %6.1f", (double)ld[6]); PRINTMSG(" %6.1f", (double)ld[6]);
if (flag_d) { if (flag_d) {
printw(" %6.0f", (double)ld[8]); PRINTMSG(" %6.0f", (double)ld[8]);
printw(" %6.0f", (double)ld[9] * 1024); PRINTMSG(" %6.0f", (double)ld[9] * 1024);
if (ld[10] > 1e3) if (ld[10] > 1e3)
printw(" %6.0f", (double)ld[10]); PRINTMSG(" %6.0f", (double)ld[10]);
else else
printw(" %6.1f", (double)ld[10]); PRINTMSG(" %6.1f", (double)ld[10]);
} }
if (ld[7] > 80) if (ld[7] > 80)
@ -295,27 +315,38 @@ main(int argc, char **argv)
i = 2; i = 2;
else else
i = 1; i = 1;
attron(COLOR_PAIR(i)); if (!flag_b)
printw(" %6.1lf", (double)ld[7]); attron(COLOR_PAIR(i));
attroff(COLOR_PAIR(i)); PRINTMSG(" %6.1lf", (double)ld[7]);
printw("|"); if (!flag_b)
attroff(COLOR_PAIR(i));
PRINTMSG("|");
if (gid == NULL) { if (gid == NULL) {
printw(" ??"); PRINTMSG(" ??");
} else if (gid->lg_what == ISPROVIDER) { } else if (gid->lg_what == ISPROVIDER) {
pp = gid->lg_ptr; pp = gid->lg_ptr;
printw(" %s", pp->lg_name); PRINTMSG(" %s", pp->lg_name);
} else if (gid->lg_what == ISCONSUMER) { } else if (gid->lg_what == ISCONSUMER) {
cp = gid->lg_ptr; cp = gid->lg_ptr;
printw(" %s/%s/%s", PRINTMSG(" %s/%s/%s",
cp->lg_geom->lg_class->lg_name, cp->lg_geom->lg_class->lg_name,
cp->lg_geom->lg_name, cp->lg_geom->lg_name,
cp->lg_provider->lg_name); cp->lg_provider->lg_name);
} }
clrtoeol(); if (!flag_b)
printw("\n"); clrtoeol();
PRINTMSG("\n");
*gsq = *gsp; *gsq = *gsp;
} }
geom_stats_snapshot_free(sp); 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); getyx(stdscr, cury, curx);
getmaxyx(stdscr, maxy, maxx); getmaxyx(stdscr, maxy, maxx);
clrtobot(); clrtobot();
@ -378,15 +409,17 @@ main(int argc, char **argv)
} }
} }
endwin(); if (!flag_b) {
el_end(el); endwin();
el_end(el);
}
exit(EX_OK); exit(EX_OK);
} }
static void static void
usage(void) usage(void)
{ {
fprintf(stderr, "usage: gstat [-acd] [-f filter] [-I interval]\n"); fprintf(stderr, "usage: gstat [-abcd] [-f filter] [-I interval]\n");
exit(EX_USAGE); exit(EX_USAGE);
/* NOTREACHED */ /* NOTREACHED */
} }