diff options
Diffstat (limited to 'src/bootchart/svg.c')
-rw-r--r-- | src/bootchart/svg.c | 173 |
1 files changed, 74 insertions, 99 deletions
diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c index 9fee810795..231d3daa80 100644 --- a/src/bootchart/svg.c +++ b/src/bootchart/svg.c @@ -1,5 +1,7 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + /*** - bootchart.c - This file is part of systemd-bootchart + This file is part of systemd. Copyright (C) 2009-2013 Intel Coproration @@ -31,14 +33,15 @@ #include <sys/stat.h> #include <fcntl.h> -#include "bootchart.h" #include "util.h" #include "macro.h" +#include "store.h" +#include "svg.h" +#include "bootchart.h" - -#define time_to_graph(t) ((t) * scale_x) -#define ps_to_graph(n) ((n) * scale_y) -#define kb_to_graph(m) ((m) * scale_y * 0.0001) +#define time_to_graph(t) ((t) * arg_scale_x) +#define ps_to_graph(n) ((n) * arg_scale_y) +#define kb_to_graph(m) ((m) * arg_scale_y * 0.0001) #define to_color(n) (192.0 - ((n) * 192.0)) #define max(x, y) (((x) > (y)) ? (x) : (y)) @@ -48,7 +51,7 @@ static char str[8092]; #define svg(a...) do { snprintf(str, 8092, ## a); fputs(str, of); fflush(of); } while (0) -static const char *colorwheel[12] = { +static const char * const colorwheel[12] = { "rgb(255,32,32)", // red "rgb(32,192,192)", // cyan "rgb(255,128,32)", // orange @@ -71,9 +74,7 @@ static float psize = 0; static float ksize = 0; static float esize = 0; - -static void svg_header(void) -{ +static void svg_header(void) { float w; float h; @@ -82,8 +83,8 @@ static void svg_header(void) w = ((w < 1600.0) ? 1600.0 : w); /* height is variable based on pss, psize, ksize */ - h = 400.0 + (scale_y * 30.0) /* base graphs and title */ - + (pss ? (100.0 * scale_y) + (scale_y * 7.0) : 0.0) /* pss estimate */ + h = 400.0 + (arg_scale_y * 30.0) /* base graphs and title */ + + (arg_pss ? (100.0 * arg_scale_y) + (arg_scale_y * 7.0) : 0.0) /* pss estimate */ + psize + ksize + esize; svg("<?xml version=\"1.0\" standalone=\"no\"?>\n"); @@ -103,11 +104,11 @@ static void svg_header(void) svg("<!-- your browser to file:///run/log/ and click. This bootchart was -->\n\n"); svg("<!-- generated by bootchart version %s, running with options: -->\n", VERSION); - svg("<!-- hz=\"%f\" n=\"%d\" -->\n", hz, samples_len); - svg("<!-- x=\"%f\" y=\"%f\" -->\n", scale_x, scale_y); - svg("<!-- rel=\"%d\" f=\"%d\" -->\n", relative, filter); - svg("<!-- p=\"%d\" e=\"%d\" -->\n", pss, entropy); - svg("<!-- o=\"%s\" i=\"%s\" -->\n\n", output_path, init_path); + svg("<!-- hz=\"%f\" n=\"%d\" -->\n", arg_hz, arg_samples_len); + svg("<!-- x=\"%f\" y=\"%f\" -->\n", arg_scale_x, arg_scale_y); + svg("<!-- rel=\"%d\" f=\"%d\" -->\n", arg_relative, arg_filter); + svg("<!-- p=\"%d\" e=\"%d\" -->\n", arg_pss, arg_entropy); + svg("<!-- o=\"%s\" i=\"%s\" -->\n\n", arg_output_path, arg_init_path); /* style sheet */ svg("<defs>\n <style type=\"text/css\">\n <![CDATA[\n"); @@ -136,12 +137,9 @@ static void svg_header(void) svg(" text.idle { font-size: 18; }\n"); svg(" ]]>\n </style>\n</defs>\n\n"); - } - -static void svg_title(const char *build) -{ +static void svg_title(const char *build) { char cmdline[256] = ""; char filename[PATH_MAX]; char buf[256]; @@ -222,12 +220,10 @@ static void svg_title(const char *build) svg("Not detected"); svg("</text>\n"); svg("<text class=\"sec\" x=\"20\" y=\"155\">Graph data: %.03f samples/sec, recorded %i total, dropped %i samples, %i processes, %i filtered</text>\n", - hz, samples_len, overrun, pscount, pfiltered); + arg_hz, arg_samples_len, overrun, pscount, pfiltered); } - -static void svg_graph_box(int height) -{ +static void svg_graph_box(int height) { double d = 0.0; int i = 0; @@ -238,7 +234,7 @@ static void svg_graph_box(int height) ps_to_graph(height)); for (d = graph_start; d <= sampletime[samples-1]; - d += (scale_x < 2.0 ? 60.0 : scale_x < 10.0 ? 1.0 : 0.1)) { + d += (arg_scale_x < 2.0 ? 60.0 : arg_scale_x < 10.0 ? 1.0 : 0.1)) { /* lines for each second */ if (i % 50 == 0) svg(" <line class=\"sec5\" x1=\"%.03f\" y1=\"0\" x2=\"%.03f\" y2=\"%.03f\" />\n", @@ -282,8 +278,7 @@ static char* xml_comment_encode(const char* name) { return enc_name; } -static void svg_pss_graph(void) -{ +static void svg_pss_graph(void) { struct ps_struct *ps; int i; @@ -320,7 +315,7 @@ static void svg_pss_graph(void) ps = ps->next_ps; if (!ps) continue; - if (ps->sample[i].pss <= (100 * scale_y)) + if (ps->sample[i].pss <= (100 * arg_scale_y)) top += ps->sample[i].pss; }; svg(" <rect class=\"clrw\" style=\"fill: %s\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n", @@ -339,7 +334,7 @@ static void svg_pss_graph(void) if (!ps) continue; /* don't draw anything smaller than 2mb */ - if (ps->sample[i].pss > (100 * scale_y)) { + if (ps->sample[i].pss > (100 * arg_scale_y)) { top = bottom + ps->sample[i].pss; svg(" <rect class=\"clrw\" style=\"fill: %s\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n", colorwheel[ps->pid % 12], @@ -366,7 +361,7 @@ static void svg_pss_graph(void) ps = ps->next_ps; if (!ps) continue; - if (ps->sample[i].pss <= (100 * scale_y)) + if (ps->sample[i].pss <= (100 * arg_scale_y)) top += ps->sample[i].pss; }; @@ -379,10 +374,10 @@ static void svg_pss_graph(void) if (!ps) continue; /* don't draw anything smaller than 2mb */ - if (ps->sample[i].pss > (100 * scale_y)) { + if (ps->sample[i].pss > (100 * arg_scale_y)) { top = bottom + ps->sample[i].pss; /* draw a label with the process / PID */ - if ((i == 1) || (ps->sample[i - 1].pss <= (100 * scale_y))) + if ((i == 1) || (ps->sample[i - 1].pss <= (100 * arg_scale_y))) svg(" <text x=\"%.03f\" y=\"%.03f\"><![CDATA[%s]]> [%i]</text>\n", time_to_graph(sampletime[i] - graph_start), kb_to_graph(1000000.0 - bottom - ((top - bottom) / 2)), @@ -416,8 +411,7 @@ static void svg_pss_graph(void) } -static void svg_io_bi_bar(void) -{ +static void svg_io_bi_bar(void) { double max = 0.0; double range; int max_here = 0; @@ -434,7 +428,7 @@ static void svg_io_bi_bar(void) * each poll. Applying a smoothing function loses some burst data, * so keep the smoothing range short. */ - range = 0.25 / (1.0 / hz); + range = 0.25 / (1.0 / arg_hz); if (range < 2.0) range = 2.0; /* no smoothing */ @@ -479,22 +473,21 @@ static void svg_io_bi_bar(void) if (pbi > 0.001) svg("<rect class=\"bi\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n", time_to_graph(sampletime[i - 1] - graph_start), - (scale_y * 5) - (pbi * (scale_y * 5)), + (arg_scale_y * 5) - (pbi * (arg_scale_y * 5)), time_to_graph(sampletime[i] - sampletime[i - 1]), - pbi * (scale_y * 5)); + pbi * (arg_scale_y * 5)); /* labels around highest value */ if (i == max_here) { svg(" <text class=\"sec\" x=\"%.03f\" y=\"%.03f\">%0.2fmb/sec</text>\n", time_to_graph(sampletime[i] - graph_start) + 5, - ((scale_y * 5) - (pbi * (scale_y * 5))) + 15, + ((arg_scale_y * 5) - (pbi * (arg_scale_y * 5))) + 15, max / 1024.0 / (interval / 1000000000.0)); } } } -static void svg_io_bo_bar(void) -{ +static void svg_io_bo_bar(void) { double max = 0.0; double range; int max_here = 0; @@ -511,7 +504,7 @@ static void svg_io_bo_bar(void) * each poll. Applying a smoothing function loses some burst data, * so keep the smoothing range short. */ - range = 0.25 / (1.0 / hz); + range = 0.25 / (1.0 / arg_hz); if (range < 2.0) range = 2.0; /* no smoothing */ @@ -556,23 +549,21 @@ static void svg_io_bo_bar(void) if (pbo > 0.001) svg("<rect class=\"bo\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n", time_to_graph(sampletime[i - 1] - graph_start), - (scale_y * 5) - (pbo * (scale_y * 5)), + (arg_scale_y * 5) - (pbo * (arg_scale_y * 5)), time_to_graph(sampletime[i] - sampletime[i - 1]), - pbo * (scale_y * 5)); + pbo * (arg_scale_y * 5)); /* labels around highest bo value */ if (i == max_here) { svg(" <text class=\"sec\" x=\"%.03f\" y=\"%.03f\">%0.2fmb/sec</text>\n", time_to_graph(sampletime[i] - graph_start) + 5, - ((scale_y * 5) - (pbo * (scale_y * 5))), + ((arg_scale_y * 5) - (pbo * (arg_scale_y * 5))), max / 1024.0 / (interval / 1000000000.0)); } } } - -static void svg_cpu_bar(void) -{ +static void svg_cpu_bar(void) { int i; svg("<!-- CPU utilization graph -->\n"); @@ -605,15 +596,14 @@ static void svg_cpu_bar(void) if (ptrt > 0.001) { svg("<rect class=\"cpu\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n", time_to_graph(sampletime[i - 1] - graph_start), - (scale_y * 5) - (ptrt * (scale_y * 5)), + (arg_scale_y * 5) - (ptrt * (arg_scale_y * 5)), time_to_graph(sampletime[i] - sampletime[i - 1]), - ptrt * (scale_y * 5)); + ptrt * (arg_scale_y * 5)); } } } -static void svg_wait_bar(void) -{ +static void svg_wait_bar(void) { int i; svg("<!-- Wait time aggregation box -->\n"); @@ -647,16 +637,15 @@ static void svg_wait_bar(void) if (ptwt > 0.001) { svg("<rect class=\"wait\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n", time_to_graph(sampletime[i - 1] - graph_start), - ((scale_y * 5) - (ptwt * (scale_y * 5))), + ((arg_scale_y * 5) - (ptwt * (arg_scale_y * 5))), time_to_graph(sampletime[i] - sampletime[i - 1]), - ptwt * (scale_y * 5)); + ptwt * (arg_scale_y * 5)); } } } -static void svg_entropy_bar(void) -{ +static void svg_entropy_bar(void) { int i; svg("<!-- entropy pool graph -->\n"); @@ -670,15 +659,13 @@ static void svg_entropy_bar(void) /* svg("<!-- entropy %.03f %i -->\n", sampletime[i], entropy_avail[i]); */ svg("<rect class=\"cpu\" x=\"%.03f\" y=\"%.03f\" width=\"%.03f\" height=\"%.03f\" />\n", time_to_graph(sampletime[i - 1] - graph_start), - ((scale_y * 5) - ((entropy_avail[i] / 4096.) * (scale_y * 5))), + ((arg_scale_y * 5) - ((entropy_avail[i] / 4096.) * (arg_scale_y * 5))), time_to_graph(sampletime[i] - sampletime[i - 1]), - (entropy_avail[i] / 4096.) * (scale_y * 5)); + (entropy_avail[i] / 4096.) * (arg_scale_y * 5)); } } - -static struct ps_struct *get_next_ps(struct ps_struct *ps) -{ +static struct ps_struct *get_next_ps(struct ps_struct *ps) { /* * walk the list of processes and return the next one to be * painted @@ -707,10 +694,8 @@ static struct ps_struct *get_next_ps(struct ps_struct *ps) return NULL; } - -static int ps_filter(struct ps_struct *ps) -{ - if (!filter) +static int ps_filter(struct ps_struct *ps) { + if (!arg_filter) return 0; /* can't draw data when there is only 1 sample (need start + stop) */ @@ -728,9 +713,7 @@ static int ps_filter(struct ps_struct *ps) return 0; } - -static void svg_do_initcall(int count_only) -{ +static void svg_do_initcall(int count_only) { FILE _cleanup_pclose_ *f = NULL; double t; char func[256]; @@ -738,7 +721,7 @@ static void svg_do_initcall(int count_only) int usecs; /* can't plot initcall when disabled or in relative mode */ - if (!initcall || relative) { + if (!initcall || arg_relative) { kcount = 0; return; } @@ -818,9 +801,7 @@ static void svg_do_initcall(int count_only) } } - -static void svg_ps_bars(void) -{ +static void svg_ps_bars(void) { struct ps_struct *ps; int i = 0; int j = 0; @@ -966,7 +947,7 @@ static void svg_ps_bars(void) break; } - for (i = ps->first; i < samples - (hz / 2); i++) { + for (i = ps->first; i < samples - (arg_hz / 2); i++) { double crt; double brt; int c; @@ -974,8 +955,8 @@ static void svg_ps_bars(void) /* subtract bootchart cpu utilization from total */ crt = 0.0; for (c = 0; c < cpus; c++) - crt += cpustat[c].sample[i + ((int)hz / 2)].runtime - cpustat[c].sample[i].runtime; - brt = ps->sample[i + ((int)hz / 2)].runtime - ps->sample[i].runtime; + crt += cpustat[c].sample[i + ((int)arg_hz / 2)].runtime - cpustat[c].sample[i].runtime; + brt = ps->sample[i + ((int)arg_hz / 2)].runtime - ps->sample[i].runtime; /* * our definition of "idle": @@ -989,21 +970,19 @@ static void svg_ps_bars(void) idletime); svg("<line class=\"idle\" x1=\"%.03f\" y1=\"%.03f\" x2=\"%.03f\" y2=\"%.03f\" />\n", time_to_graph(idletime), - -scale_y, + -arg_scale_y, time_to_graph(idletime), - ps_to_graph(pcount) + scale_y); + ps_to_graph(pcount) + arg_scale_y); svg("<text class=\"idle\" x=\"%.03f\" y=\"%.03f\">%.01fs</text>\n", time_to_graph(idletime) + 5.0, - ps_to_graph(pcount) + scale_y, + ps_to_graph(pcount) + arg_scale_y, idletime); break; } } } - -static void svg_top_ten_cpu(void) -{ +static void svg_top_ten_cpu(void) { struct ps_struct *top[10]; struct ps_struct emptyps; struct ps_struct *ps; @@ -1036,9 +1015,7 @@ static void svg_top_ten_cpu(void) top[n]->pid); } - -static void svg_top_ten_pss(void) -{ +static void svg_top_ten_pss(void) { struct ps_struct *top[10]; struct ps_struct emptyps; struct ps_struct *ps; @@ -1071,9 +1048,7 @@ static void svg_top_ten_pss(void) top[n]->pid); } - -void svg_do(const char *build) -{ +void svg_do(const char *build) { struct ps_struct *ps; memset(&str, 0, sizeof(str)); @@ -1082,7 +1057,7 @@ void svg_do(const char *build) /* count initcall thread count first */ svg_do_initcall(1); - ksize = (kcount ? ps_to_graph(kcount) + (scale_y * 2) : 0); + ksize = (kcount ? ps_to_graph(kcount) + (arg_scale_y * 2) : 0); /* then count processes */ while ((ps = get_next_ps(ps))) { @@ -1091,9 +1066,9 @@ void svg_do(const char *build) else pfiltered++; } - psize = ps_to_graph(pcount) + (scale_y * 2); + psize = ps_to_graph(pcount) + (arg_scale_y * 2); - esize = (entropy ? scale_y * 7 : 0); + esize = (arg_entropy ? arg_scale_y * 7 : 0); /* after this, we can draw the header with proper sizing */ svg_header(); @@ -1102,25 +1077,25 @@ void svg_do(const char *build) svg_io_bi_bar(); svg("</g>\n\n"); - svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (scale_y * 7.0)); + svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * 7.0)); svg_io_bo_bar(); svg("</g>\n\n"); - svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (scale_y * 14.0)); + svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * 14.0)); svg_cpu_bar(); svg("</g>\n\n"); - svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (scale_y * 21.0)); + svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * 21.0)); svg_wait_bar(); svg("</g>\n\n"); if (kcount) { - svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (scale_y * 28.0)); + svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * 28.0)); svg_do_initcall(0); svg("</g>\n\n"); } - svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (scale_y * 28.0) + ksize); + svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * 28.0) + ksize); svg_ps_bars(); svg("</g>\n\n"); @@ -1132,14 +1107,14 @@ void svg_do(const char *build) svg_top_ten_cpu(); svg("</g>\n\n"); - if (entropy) { - svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (scale_y * 28.0) + ksize + psize); + if (arg_entropy) { + svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * 28.0) + ksize + psize); svg_entropy_bar(); svg("</g>\n\n"); } - if (pss) { - svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (scale_y * 28.0) + ksize + psize + esize); + if (arg_pss) { + svg("<g transform=\"translate(10,%.03f)\">\n", 400.0 + (arg_scale_y * 28.0) + ksize + psize + esize); svg_pss_graph(); svg("</g>\n\n"); |