close_plot(plot);
}
+static int __plot_cpu(struct plot *plot, int seconds, char *label,
+ int active_index, int gld_index)
+{
+ struct trace_file *tf;
+ int max = 0;
+ int i;
+ int gld_i;
+ char *color;
+ double avg = 0;
+ int ymax;
+ int plotted = 0;
+
+ list_for_each_entry(tf, &all_traces, list) {
+ if (tf->trace->mpstat_num_cpus > max)
+ max = tf->trace->mpstat_num_cpus;
+ }
+ if (max == 0)
+ return 1;
+
+ tf = list_entry(all_traces.next, struct trace_file, list);
+
+ ymax = tf->mpstat_gld[gld_index]->max;
+ if (ymax == 0)
+ return 1;
+
+ svg_alloc_legend(plot, num_traces * max);
+
+ plot->add_xlabel = last_active_graph == active_index;
+ setup_axis(plot);
+ set_plot_label(plot, label);
+
+ seconds = tf->mpstat_seconds;
+
+ set_yticks(plot, 4, 0, tf->mpstat_gld[gld_index]->max, "");
+ set_ylabel(plot, "Percent");
+ set_xticks(plot, 9, 0, seconds);
+
+ cpu_color_index = 0;
+ list_for_each_entry(tf, &all_traces, list) {
+ for (i = 0; i < tf->mpstat_gld[0]->stop_seconds; i++) {
+ if (tf->mpstat_gld[gld_index]->data[i].count) {
+ avg += (tf->mpstat_gld[gld_index]->data[i].sum /
+ tf->mpstat_gld[gld_index]->data[i].count);
+ }
+ }
+ avg /= tf->mpstat_gld[gld_index]->stop_seconds;
+ color = pick_cpu_color();
+ svg_line_graph(plot, tf->mpstat_gld[0], color, 0, 0);
+ svg_add_legend(plot, tf->label, " avg", color);
+
+ for (i = 1; i < tf->trace->mpstat_num_cpus + 1; i++) {
+ struct graph_line_data *gld = tf->mpstat_gld[i * MPSTAT_GRAPHS + gld_index];
+ double this_avg = 0;
+
+ for (gld_i = 0; gld_i < gld->stop_seconds; gld_i++)
+ this_avg += gld->data[i].sum /
+ gld->data[i].count;;
+
+ this_avg /= gld->stop_seconds;
+
+ for (gld_i = 0; gld_i < gld->stop_seconds; gld_i++) {
+ double val;
+
+ if (gld->data[gld_i].count == 0)
+ continue;
+ val = (double)gld->data[gld_i].sum /
+ gld->data[gld_i].count;
+
+ if (this_avg > avg + 30 || val > 95) {
+ color = pick_cpu_color();
+ svg_line_graph(plot, gld, color, avg + 30, 95);
+ snprintf(line, line_len, " CPU %d\n", i - 1);
+ svg_add_legend(plot, tf->label, line, color);
+ plotted++;
+ break;
+ }
+
+ }
+ }
+ }
+
+ if (plot->add_xlabel)
+ set_xlabel(plot, "Time (seconds)");
+
+ if (!plot->no_legend) {
+ svg_write_legend(plot);
+ svg_free_legend(plot);
+ }
+ return 0;
+}
+
+static void plot_cpu(struct plot *plot, int seconds, char *label,
+ int active_index, int gld_index)
+{
+ if (active_graphs[active_index] == 0)
+ return;
+
+ plot->add_xlabel = last_active_graph == active_index;
+ if (!__plot_cpu(plot, seconds, label, active_index, gld_index))
+ close_plot(plot);
+}
+
+static void __plot_queue_depth(struct plot *plot, int seconds)
+{
+ struct trace_file *tf;
+
+ plot->add_xlabel = last_active_graph == QUEUE_DEPTH_GRAPH_INDEX;
+
+ setup_axis(plot);
+ set_plot_label(plot, "Queue Depth");
+ if (num_traces > 1)
+ svg_alloc_legend(plot, num_traces);
+
+ tf = list_entry(all_traces.next, struct trace_file, list);
+ set_ylabel(plot, "Pending IO");
+ set_yticks(plot, 4, 0, tf->queue_depth_gld->max, "");
+ set_xticks(plot, 9, 0, seconds);
+
+ list_for_each_entry(tf, &all_traces, list) {
+ svg_line_graph(plot, tf->queue_depth_gld, tf->read_color, 0, 0);
+ if (num_traces > 1)
+ svg_add_legend(plot, tf->label, "", tf->read_color);
+ }
+
+ if (plot->add_xlabel)
+ set_xlabel(plot, "Time (seconds)");
+ if (num_traces > 1)
+ svg_write_legend(plot);
+}
+
+static void plot_queue_depth(struct plot *plot, int seconds)
+{
+ if (active_graphs[QUEUE_DEPTH_GRAPH_INDEX] == 0)
+ return;
+ __plot_queue_depth(plot, seconds);
+ close_plot(plot);
+}
+
static void convert_movie_files(char *movie_dir)
{
fprintf(stderr, "Converting svg files in %s\n", movie_dir);
int total_frames = movie_len * movie_frames_per_sec;
int rows, cols;
int batch_count;
+ int graph_width_factor = 5;
+ int orig_y_offset;
get_graph_size(&cols, &rows);
batch_count = cols / total_frames;
while (i < cols) {
snprintf(line, line_len, "%s/%010d-%s.svg", movie_dir, i, output_filename);
set_plot_output(plot, line);
-
set_plot_title(plot, graph_title);
+ orig_y_offset = plot->start_y_offset;
+
+ plot->no_legend = 1;
+
+ set_graph_size(cols / graph_width_factor, rows / 8);
+
+ __plot_tput(plot, tf->gdd_reads->seconds);
+ svg_write_time_line(plot, i / graph_width_factor);
+ close_plot(plot);
+
+ if (!__plot_cpu(plot, tf->gdd_reads->seconds,
+ "CPU System Time", CPU_SYS_GRAPH_INDEX, MPSTAT_SYS)) {
+ svg_write_time_line(plot, i / graph_width_factor);
+ close_plot(plot);
+ }
+
+ __plot_queue_depth(plot, tf->gdd_reads->seconds);
+ svg_write_time_line(plot, i / graph_width_factor);
+
+ close_plot_col(plot);
+
+ /* movie graph starts here */
+ plot->start_y_offset = orig_y_offset;
+ set_graph_size(cols - cols / graph_width_factor, rows);
+ plot->no_legend = 0;
+
if (movie_style == MOVIE_SPINDLE)
setup_axis_spindle(plot);
else
svg_write_legend(plot);
close_plot(plot);
-
- set_graph_size(cols, rows / 7);
- plot->add_xlabel = 1;
- __plot_tput(plot, tf->gdd_reads->seconds);
- svg_write_time_line(plot, i);
close_plot(plot);
- set_graph_size(cols, rows);
- close_plot(plot);
close_plot_file(plot);
}
free_all_plot_history(&movie_history_reads);
free(movie_dir);
}
-static void plot_cpu(struct plot *plot, int seconds, char *label,
- int active_index, int gld_index)
-{
- struct trace_file *tf;
- int max = 0;
- int i;
- int gld_i;
- char *color;
- double avg = 0;
- int ymax;
- int plotted = 0;
-
- if (active_graphs[active_index] == 0)
- return;
-
- list_for_each_entry(tf, &all_traces, list) {
- if (tf->trace->mpstat_num_cpus > max)
- max = tf->trace->mpstat_num_cpus;
- }
- if (max == 0)
- return;
-
- tf = list_entry(all_traces.next, struct trace_file, list);
-
- ymax = tf->mpstat_gld[gld_index]->max;
- if (ymax == 0)
- return;
-
- svg_alloc_legend(plot, num_traces * max);
-
- plot->add_xlabel = last_active_graph == active_index;
- setup_axis(plot);
- set_plot_label(plot, label);
-
- seconds = tf->mpstat_seconds;
-
- set_yticks(plot, 4, 0, tf->mpstat_gld[gld_index]->max, "");
- set_ylabel(plot, "Percent");
- set_xticks(plot, 9, 0, seconds);
-
- cpu_color_index = 0;
- list_for_each_entry(tf, &all_traces, list) {
- for (i = 0; i < tf->mpstat_gld[0]->stop_seconds; i++) {
- if (tf->mpstat_gld[gld_index]->data[i].count) {
- avg += (tf->mpstat_gld[gld_index]->data[i].sum /
- tf->mpstat_gld[gld_index]->data[i].count);
- }
- }
- avg /= tf->mpstat_gld[gld_index]->stop_seconds;
- color = pick_cpu_color();
- svg_line_graph(plot, tf->mpstat_gld[0], color, 0, 0);
- svg_add_legend(plot, tf->label, " avg", color);
-
- for (i = 1; i < tf->trace->mpstat_num_cpus + 1; i++) {
- struct graph_line_data *gld = tf->mpstat_gld[i * MPSTAT_GRAPHS + gld_index];
- double this_avg = 0;
-
- for (gld_i = 0; gld_i < gld->stop_seconds; gld_i++)
- this_avg += gld->data[i].sum /
- gld->data[i].count;;
-
- this_avg /= gld->stop_seconds;
-
- for (gld_i = 0; gld_i < gld->stop_seconds; gld_i++) {
- double val;
-
- if (gld->data[gld_i].count == 0)
- continue;
- val = (double)gld->data[gld_i].sum /
- gld->data[gld_i].count;
-
- if (this_avg > avg + 30 || val > 95) {
- color = pick_cpu_color();
- svg_line_graph(plot, gld, color, avg + 30, 95);
- snprintf(line, line_len, " CPU %d\n", i - 1);
- svg_add_legend(plot, tf->label, line, color);
- plotted++;
- break;
- }
-
- }
- }
- }
-
- if (plot->add_xlabel)
- set_xlabel(plot, "Time (seconds)");
-
- svg_write_legend(plot);
- svg_free_legend(plot);
- close_plot(plot);
-}
-
static void plot_latency(struct plot *plot, int seconds)
{
struct trace_file *tf;
close_plot(plot);
}
-static void plot_queue_depth(struct plot *plot, int seconds)
-{
- struct trace_file *tf;
-
- if (active_graphs[QUEUE_DEPTH_GRAPH_INDEX] == 0)
- return;
-
- plot->add_xlabel = last_active_graph == QUEUE_DEPTH_GRAPH_INDEX;
-
- setup_axis(plot);
- set_plot_label(plot, "Queue Depth");
- if (num_traces > 1)
- svg_alloc_legend(plot, num_traces);
-
- tf = list_entry(all_traces.next, struct trace_file, list);
- set_ylabel(plot, "Pending IO");
- set_yticks(plot, 4, 0, tf->queue_depth_gld->max, "");
- set_xticks(plot, 9, 0, seconds);
-
- list_for_each_entry(tf, &all_traces, list) {
- svg_line_graph(plot, tf->queue_depth_gld, tf->read_color, 0, 0);
- if (num_traces > 1)
- svg_add_legend(plot, tf->label, "", tf->read_color);
- }
-
- if (plot->add_xlabel)
- set_xlabel(plot, "Time (seconds)");
- if (num_traces > 1)
- svg_write_legend(plot);
- close_plot(plot);
-}
-
static void plot_iops(struct plot *plot, int seconds)
{
struct trace_file *tf;
if (make_movie) {
set_io_graph_scale(256);
if (movie_style == MOVIE_SPINDLE)
- set_graph_size(550, 550);
+ set_graph_size(750, 550);
else
set_graph_size(700, 400);
}
write(fd, header, strlen(header));
/* write a bunch of spaces so we can stuff in the width and height later */
write(fd, spaces, strlen(spaces));
+ write(fd, spaces, strlen(spaces));
+ write(fd, spaces, strlen(spaces));
write(fd, defs_start, strlen(defs_start));
write(fd, filter1, strlen(filter1));
int len;
int fd = plot->fd;
int bump_height = tick_font_size * 3 + axis_label_font_size;
+ int local_legend_width = legend_width;
- plot->total_width = axis_x_off(graph_width) + graph_left_pad / 2 + legend_width;
+ if (plot->no_legend)
+ local_legend_width = 0;
+
+ plot->total_width = axis_x_off(graph_width) + graph_left_pad / 2 + local_legend_width;;
plot->total_height = axis_y() + tick_label_pad + tick_font_size;
if (plot->add_xlabel)
plot->total_height += bump_height;
/* backing rect */
- snprintf(line, line_len, "<rect x=\"0\" y=\"%d\" width=\"%d\" "
+ snprintf(line, line_len, "<rect x=\"%d\" y=\"%d\" width=\"%d\" "
"height=\"%d\" fill=\"white\" stroke=\"none\"/>",
+ plot->start_x_offset,
plot->start_y_offset, plot->total_width + 40,
plot->total_height + 20);
len = strlen(line);
write(fd, line, len);
- snprintf(line, line_len, "<rect x=\"15\" y=\"%d\" width=\"%d\" "
+ snprintf(line, line_len, "<rect x=\"%d\" y=\"%d\" width=\"%d\" "
"filter=\"url(#shadow)\" "
"height=\"%d\" fill=\"white\" stroke=\"none\"/>",
+ plot->start_x_offset + 15,
plot->start_y_offset, plot->total_width, plot->total_height);
len = strlen(line);
write(fd, line, len);
plot->total_height += 20;
+ plot->total_width += 20;
if (plot->total_height + plot->start_y_offset > final_height)
final_height = plot->total_height + plot->start_y_offset;
- if (plot->total_width + 40 > final_width)
- final_width = plot->total_width + 40;
+ if (plot->start_x_offset + plot->total_width + 40 > final_width)
+ final_width = plot->start_x_offset + plot->total_width + 40;
/* create an svg object for all our coords to be relative against */
snprintf(line, line_len, "<svg x=\"%d\" y=\"%d\">\n", plot->start_x_offset, plot->start_y_offset);
int fd = plot->fd;
int bump_height = tick_font_size * 3 + axis_label_font_size;
- plot->total_width = axis_x_off(graph_width) + graph_left_pad / 2 + legend_width;
+ legend_x_off = -60;
+
+ plot->total_width = axis_x_off(graph_width) + legend_width;
plot->total_height = axis_y() + tick_label_pad + tick_font_size;
if (plot->add_xlabel)
plot->total_height += bump_height;
/* backing rect */
- snprintf(line, line_len, "<rect x=\"0\" y=\"%d\" width=\"%d\" "
+ snprintf(line, line_len, "<rect x=\"%d\" y=\"%d\" width=\"%d\" "
"height=\"%d\" fill=\"white\" stroke=\"none\"/>",
- plot->start_y_offset, plot->total_width + 40,
+ plot->start_x_offset,
+ plot->start_y_offset, plot->total_width + 10,
plot->total_height + 20);
len = strlen(line);
write(fd, line, len);
- snprintf(line, line_len, "<rect x=\"15\" y=\"%d\" width=\"%d\" "
+ snprintf(line, line_len, "<rect x=\"%d\" y=\"%d\" width=\"%d\" "
"filter=\"url(#shadow)\" "
"height=\"%d\" fill=\"white\" stroke=\"none\"/>",
- plot->start_y_offset, plot->total_width, plot->total_height);
+ plot->start_x_offset + 15,
+ plot->start_y_offset, plot->total_width - 30,
+ plot->total_height);
len = strlen(line);
write(fd, line, len);
plot->total_height += 20;
if (plot->total_height + plot->start_y_offset > final_height)
final_height = plot->total_height + plot->start_y_offset;
- if (plot->total_width + 40 > final_width)
- final_width = plot->total_width + 40;
+ if (plot->start_x_offset + plot->total_width + 40 > final_width)
+ final_width = plot->start_x_offset + plot->total_width + 40;
/* create an svg object for all our coords to be relative against */
snprintf(line, line_len, "<svg x=\"%d\" y=\"%d\">\n", plot->start_x_offset, plot->start_y_offset);
return 0;
}
+int close_plot_no_height(struct plot *plot)
+{
+ close_svg(plot->fd);
+ plot->add_xlabel = 0;
+ return 0;
+}
+
+int close_plot_col(struct plot *plot)
+{
+ close_svg(plot->fd);
+ plot->start_x_offset += plot->total_width;
+ plot->add_xlabel = 0;
+ return 0;
+}
+
+
struct plot *alloc_plot(void)
{
struct plot *plot;
"width=\"%d\" height=\"%d\">\n",
final_width, final_height);
write(plot->fd, line, strlen(line));
+ snprintf(line, line_len, "<rect x=\"0\" y=\"0\" width=\"%d\" "
+ "height=\"%d\" fill=\"white\"/>\n", final_width, final_height);
+ write(plot->fd, line, strlen(line));
close(plot->fd);
plot->fd = 0;
return 0;