From: Alan D. Brunelle Date: Thu, 8 May 2008 19:28:32 +0000 (-0400) Subject: Added -X option - generate easily parseable file X-Git-Tag: blktrace-1.0.0~29 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=f028c9584055737f429979e18ab7436583ed41b5;p=blktrace.git Added -X option - generate easily parseable file Writes a portion of the default output into a separate file that more easily parsed. --- diff --git a/btt/args.c b/btt/args.c index 5930f14..6003f43 100644 --- a/btt/args.c +++ b/btt/args.c @@ -29,7 +29,7 @@ #define SETBUFFER_SIZE (64 * 1024) -#define S_OPTS "aAB:d:D:e:hi:I:l:M:o:p:q:s:S:t:T:u:Vv" +#define S_OPTS "aAB:d:D:e:hi:I:l:M:o:p:q:s:S:t:T:u:VvX" static struct option l_opts[] = { { .name = "seek-absolute", @@ -157,6 +157,12 @@ static struct option l_opts[] = { .flag = NULL, .val = 'v' }, + { + .name = "easy-parse-avgs", + .has_arg = no_argument, + .flag = NULL, + .val = 'X' + }, { .name = NULL, } @@ -181,9 +187,11 @@ static char usage_str[] = \ "[ -S | --iostat-interval= ]\n" \ "[ -t | --time-start= ]\n" \ "[ -T | --time-end= ]\n" \ - "[ -u | --unplug-hist= ] \n" \ + "[ -u | --unplug-hist= ]\n" \ "[ -V | --version ]\n" \ - "[ -v | --verbose ]\n\n"; + "[ -v | --verbose ]\n" \ + "[ -X | --easy-parse-avgs ]\n" \ + "\n"; static struct file_info *arg_files = NULL; @@ -295,6 +303,9 @@ void handle_args(int argc, char *argv[]) case 'V': printf("%s version %s\n", argv[0], bt_timeline_version); exit(0); + case 'X': + easy_parse_avgs++; + break; default: usage(argv[0]); exit(1); @@ -308,8 +319,10 @@ void handle_args(int argc, char *argv[]) setup_ifile(input_name); - if (output_name == NULL) + if (output_name == NULL) { ranges_ofp = avgs_ofp = stdout; + easy_parse_avgs = 0; + } else { char *fname = malloc(strlen(output_name) + 32); @@ -320,7 +333,7 @@ void handle_args(int argc, char *argv[]) exit(1); } if (verbose) - printf("Sending range data to %s.dat\n", output_name); + printf("Sending range data to %s\n", fname); sprintf(fname, "%s.avg", output_name); avgs_ofp = fopen(fname, "w"); @@ -329,7 +342,18 @@ void handle_args(int argc, char *argv[]) exit(1); } if (verbose) - printf("Sending stats data to %s.avg\n", output_name); + printf("Sending stats data to %s\n", fname); + + if (easy_parse_avgs) { + sprintf(fname, "%s.xvg", output_name); + xavgs_ofp = fopen(fname, "w"); + if (avgs_ofp == NULL) { + perror(fname); + exit(1); + } + if (verbose) + printf("Sending X stats data to %s\n", fname); + } free(fname); } diff --git a/btt/bt_timeline.c b/btt/bt_timeline.c index 30b1e6e..f3483f0 100644 --- a/btt/bt_timeline.c +++ b/btt/bt_timeline.c @@ -25,12 +25,13 @@ #include #include "globals.h" -char bt_timeline_version[] = "2.02"; +char bt_timeline_version[] = "2.03"; char *devices, *exes, *input_name, *output_name, *seek_name, *bno_dump_name; char *d2c_name, *q2c_name, *per_io_name, *unplug_hist_name; -FILE *ranges_ofp, *avgs_ofp, *per_io_ofp; +FILE *ranges_ofp, *avgs_ofp, *xavgs_ofp, *per_io_ofp; int verbose, done, time_bounded, output_all_data, seek_absolute; +int easy_parse_avgs; double t_astart, t_aend; unsigned long n_traces; struct avgs_info all_avgs; diff --git a/btt/doc/btt.tex b/btt/doc/btt.tex index f549e73..4adcbba 100644 --- a/btt/doc/btt.tex +++ b/btt/doc/btt.tex @@ -439,10 +439,16 @@ pdflush 0.000000790 0.000006752 0.247231307 179791 \end{description} - Besides the default data files output, there are optional data files - which can be generated by btt. These include: + In addition to the default data files output, there are optional data + files which can be generated by btt. These include: \begin{description} + \item[subset of \texttt{.avg} data, easily parsed ] When the + \texttt{-X} option is specified \emph{and} the \texttt{-o} has also + been specified, then a subset of the data produced by default is + copied to another file that is \emph{more easily parsed.} Refer to + section~\ref{sec:o-X} for full details. + \item[iostat] iostat-like data can be distilled by btt, and is described in section~\ref{sec:iostat}. @@ -754,7 +760,7 @@ Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s \newpage\section{\label{sec:cmd-line}Command Line} \begin{verbatim} -Usage: btt 2.01 +Usage: btt 2.03 [ -a | --seek-absolute ] [ -A | --all-data ] [ -B | --dump-blocknos= ] @@ -776,6 +782,7 @@ Usage: btt 2.01 [ -u | --unplug-hist= ] [ -V | --version ] [ -v | --verbose ] +[ -X | --easy-parse-avgs ] \end{verbatim} \subsection{\label{sec:o-a}\texttt{--seek-absolute}/\texttt{-a}} @@ -958,6 +965,49 @@ Sending stats data to bttX.avg 16.379036+0.000005=16.379041 \end{verbatim} +\subsection{\label{sec:o-X}\texttt{--easy-parse-avgs}/\texttt{-X}} + + \emph{Some} of the data produced by default can also be shipped + simultaneously to another file in an easy to parse form. When + the \texttt{-o} option is selected (thus producing a file with a + \texttt{.avg} exentsion), \emph{and} the \texttt{-X} flag is present, + then \texttt{btt} will generate this file. + + The format is space-delimited values starting with a 3-character + \emph{record} indicator, then the device information (either major,minor + or the device name when \texttt{-M} is specified), and then a number of + fields representing data values. The following table shows the record + identifiers and the fields provided: + + \bigskip + \begin{tabular}{|l|l|}\hline + \textbf{Record} & \textbf{Description}\\\hline + \texttt{DMI} & Device Merge Information:\\ + & \#Q \#D Ratio BLKmin BLKavg BLKmax Total\\\hline + \texttt{QSK} & Device Q2Q Seek Information:\\ + & NSEEKS MEAN MEDIAN MODE N-MODE mode\ldots\\\hline + \texttt{DSK} & Device D2D Seek Information:\\ + & NSEEKS MEAN MEDIAN MODE N-MODE mode\ldots\\\hline + \texttt{PLG} & Plug Information:\\ + & \#Plugs \#TimerUnplugs \%TimeQPlugged\\\hline + \texttt{UPG} & Unplug Information:\\ + & IOsPerUnplug IOsPerUnplugTimeout\\\hline + \texttt{ARQ} & Active Requests at Q Information:\\ + & AvgReqs@Q\\\hline + \end{tabular} + + \bigskip + A sample output file would look like: + + \begin{verbatim} +DMI 8,16 310407 106729 2.908366049 0 182 1024 19504768 +QSK 8,16 310407 167141.958551192 0 0 235753 +DSK 8,16 106729 433247.436563633 0 0 33974 +PLG 8,16 40824 382 0.008882101 +UPG 8,16 1.993361748 1.866492147 +ARQ 8,16 22.863331046 + \end{verbatim} + \newpage\section{\label{sec:bno_plot}bno\_plot.py} Included with the distribution is a simple 3D plotting utility based diff --git a/btt/globals.h b/btt/globals.h index 52fb8b0..887353d 100644 --- a/btt/globals.h +++ b/btt/globals.h @@ -179,8 +179,9 @@ extern char bt_timeline_version[], *devices, *exes, *input_name, *output_name; extern char *seek_name, *iostat_name, *d2c_name, *q2c_name, *per_io_name; extern char *bno_dump_name, *unplug_hist_name; extern double range_delta; -extern FILE *ranges_ofp, *avgs_ofp, *iostat_ofp, *per_io_ofp; +extern FILE *ranges_ofp, *avgs_ofp, *xavgs_ofp, *iostat_ofp, *per_io_ofp; extern int verbose, done, time_bounded, output_all_data, seek_absolute; +extern int easy_parse_avgs; extern unsigned int n_devs; extern unsigned long n_traces; extern struct list_head all_devs, all_procs; diff --git a/btt/output.c b/btt/output.c index a3c887f..3de9cce 100644 --- a/btt/output.c +++ b/btt/output.c @@ -92,6 +92,17 @@ char *make_dev_hdr(char *pad, size_t len, struct d_info *dip) return pad; } +char *make_dev_hdrX(char *pad, size_t len, struct d_info *dip) +{ + if (dip->map == NULL) + snprintf(pad, len, "%d,%d", + MAJOR(dip->device), MINOR(dip->device)); + else + snprintf(pad, len, "%s", dip->map->device); + + return pad; +} + struct __oda { FILE *ofp; ai_dip_t (*func)(struct d_info *); @@ -125,10 +136,10 @@ void __output_q2d_histo(struct d_info *dip, void *arg) struct __q2d *q2dp = arg; if (q2d_ok(dip->q2d_priv)) { - char scratch[15]; + char dev_info[15]; FILE *ofp = q2dp->ofp; - fprintf(q2dp->ofp, "%10s | ", make_dev_hdr(scratch, 15, dip)); + fprintf(q2dp->ofp, "%10s | ", make_dev_hdr(dev_info, 15, dip)); q2d_display(ofp, dip->q2d_priv); q2d_acc(q2dp->q2d_all, dip->q2d_priv); q2dp->n++; @@ -165,7 +176,7 @@ struct { void __output_dip_merge_ratio(struct d_info *dip, void *arg) { double blks_avg; - char scratch[15]; + char dev_info[15]; double ratio, q2c_n, d2c_n; if (dip->n_qs == 0 || dip->n_ds == 0) @@ -183,7 +194,7 @@ void __output_dip_merge_ratio(struct d_info *dip, void *arg) blks_avg = (double)dip->avgs.blks.total / d2c_n; fprintf((FILE *)arg, "%10s | %8llu %8llu %7.1lf | %8llu %8llu %8llu %8llu\n", - make_dev_hdr(scratch, 15, dip), + make_dev_hdr(dev_info, 15, dip), (unsigned long long)dip->n_qs, (unsigned long long)dip->n_ds, ratio, @@ -192,6 +203,19 @@ void __output_dip_merge_ratio(struct d_info *dip, void *arg) (unsigned long long)dip->avgs.blks.max, (unsigned long long)dip->avgs.blks.total); + if (easy_parse_avgs) { + fprintf(xavgs_ofp, + "DMI %s %llu %llu %.9lf %llu %llu %llu %llu\n", + make_dev_hdrX(dev_info, 15, dip), + (unsigned long long)dip->n_qs, + (unsigned long long)dip->n_ds, + ratio, + (unsigned long long)dip->avgs.blks.min, + (unsigned long long)blks_avg, + (unsigned long long)dip->avgs.blks.max, + (unsigned long long)dip->avgs.blks.total); + } + if (n_merges++ == 0) { merge_data.blkmin = dip->avgs.blks.min; merge_data.blkmax = dip->avgs.blks.max; @@ -426,6 +450,18 @@ static void do_output_dip_seek_info(struct d_info *dip, FILE *ofp, int is_q2q) fprintf(ofp, " %lld", m.modes[i]); fprintf(ofp, "\n"); + if (easy_parse_avgs) { + char *rec = is_q2q ? "QSK" : "DSK"; + fprintf(xavgs_ofp, + "%s %s %lld %.9lf %lld %lld %d", + rec, make_dev_hdrX(dev_info, 15, dip), + nseeks, mean, median, + nmodes > 0 ? m.modes[0] : 0, m.most_seeks); + for (i = 1; i < nmodes; i++) + fprintf(xavgs_ofp, " %lld", m.modes[i]); + fprintf(xavgs_ofp, "\n"); + } + seek_info.nseeks += nseeks; seek_info.mean += (nseeks * mean); seek_info.median += (nseeks * median); @@ -531,6 +567,13 @@ void __dip_output_plug(struct d_info *dip, void *arg) make_dev_hdr(dev_info, 15, dip), dip->nplugs, dip->n_timer_unplugs, pct); + if (easy_parse_avgs) { + fprintf(xavgs_ofp, + "PLG %s %d %d %.9lf\n", + make_dev_hdrX(dev_info, 15, dip), + dip->nplugs, dip->n_timer_unplugs, pct); + } + n_plugs++; plug_info.n_plugs += dip->nplugs; plug_info.n_timer_unplugs += dip->n_timer_unplugs; @@ -574,6 +617,13 @@ void __dip_output_plug_nios(struct d_info *dip, void *arg) fprintf(ofp, "%10s | %10.1lf %10.1lf\n", make_dev_hdr(dev_info, 15, dip), a_nios_uplug, a_nios_uplug_t); + + if (easy_parse_avgs) { + fprintf(xavgs_ofp, + "UPG %s %.9lf %.9lf\n", + make_dev_hdrX(dev_info, 15, dip), + a_nios_uplug, a_nios_uplug_t); + } } void __dip_output_uplug_all(FILE *ofp, struct nios_plug_info *p) @@ -626,6 +676,12 @@ void __dip_output_actQ(struct d_info *dip, void *arg) fprintf((FILE *)arg, "%10s | %13.1lf\n", make_dev_hdr(dev_info, 15, dip), a_actQs); + if (easy_parse_avgs) { + fprintf(xavgs_ofp, + "ARQ %s %.9lf\n", + make_dev_hdrX(dev_info, 15, dip), a_actQs); + } + n_actQs++; actQ_info.t_qs += dip->n_qs; actQ_info.t_act_qs += dip->t_act_q;