From b6076fdcf6de8361144c0d49c0b61623b5b26342 Mon Sep 17 00:00:00 2001 From: oetiker Date: Sun, 21 May 2006 21:15:39 +0000 Subject: [PATCH] new GPRINT option :strftime to print time associated with a VDEF value git-svn-id: svn://svn.oetiker.ch/rrdtool/branches/1.2/program@831 a5681a0c-68f1-0310-ab6d-d61299d08faa --- doc/rrdgraph_graph.pod | 128 ++++++++++++++++++++++++++++++++++++------------- src/rrd_graph.c | 59 +++++++++++------------ src/rrd_graph.h | 1 + src/rrd_graph_helper.c | 7 ++- 4 files changed, 129 insertions(+), 66 deletions(-) diff --git a/doc/rrdgraph_graph.pod b/doc/rrdgraph_graph.pod index 7e3aaf2..4543d74 100644 --- a/doc/rrdgraph_graph.pod +++ b/doc/rrdgraph_graph.pod @@ -50,7 +50,7 @@ Similarly, no report is generated if you don't use print options. =over 4 -=item BIB<:>I +=item BIB<:>I[B<:strftime>] Depending on the context, either the value component or the time component of a B is printed using I. It is an error @@ -64,29 +64,29 @@ For printing values: =over 4 -=item * +=item B<%%> -B<%%> just prints a literal '%' character +just prints a literal '%' character -=item * +=item B<%#.#le> -B<%#.#le> prints numbers like 1.2346e+04. The optional integers # denote field +prints numbers like 1.2346e+04. The optional integers # denote field width and decimal precision. -=item * +=item B<%#.#lf> -B<%#.#lf> prints numbers like 12345.6789, with optional field width +prints numbers like 12345.6789, with optional field width and precision. -=item * +=item B<%s> -B<%s> place this after B<%le>, B<%lf> or B<%lg>. This will be replaced by the +place this after B<%le>, B<%lf> or B<%lg>. This will be replaced by the appropriate SI magnitude unit and the value will be scaled accordingly (123456 -> 123.456 k). -=item * +=item B<%S> -B<%S> is similar to B<%s>. It does, however, use a previously defined +is similar to B<%s>. It does, however, use a previously defined magnitude unit. If there is no such unit yet, it tries to define one (just like B<%s>) unless the value is zero, in which case the magnitude unit stays undefined. Thus, formatter strings using B<%S> and no B<%s> @@ -94,51 +94,111 @@ will all use the same magnitude unit except for zero values. =back -For printing times: +If you PRINT a VDEF value, you can also print the time associated with it by appending the string +B<:strftime> to the format. Note that rrdtool uses the strftime function of your OSs clibrary. This means that +the conversion specifier may vary. Check the manual page if you are uncertain. The following is a list of +conversion specifiers usually supported across the board. =over 4 -=item * +=item B<%a> -B<%%> just prints a literal '%' character +The abbreviated weekday name according to the current locale. -=item * +=item B<%A> -B<%a, %A> print the abbreviated or full name of the day of the week. +The full weekday name according to the current locale. -=item * +=item B<%b> -B<%b, %B> print the abbreviated or full name of the month. +The abbreviated month name according to the current locale. -=item * +=item B<%B> -B<%d, %m, %y, %H, %M, %S> print day, month, year, hour, minute, and -second in two-digit format. +The full month name according to the current locale. -=item * +=item B<%c> -B<%Y> prints the year in 4-digit format. +The preferred date and time representation for the current locale. -=item * +=item B<%d> -B<%I, %p> print the hour (01..12), 'am' or 'pm'. +The day of the month as a decimal number (range 01 to 31). -=item * +=item B<%H> -B<%j, %w> print day of the week (0..6), day of the year (1..366) +The hour as a decimal number using a 24-hour clock (range 00 to 23). -=item * +=item B<%I> -B<%c, %x, %X> print date+time, date only, time only. +The hour as a decimal number using a 12-hour clock (range 01 to 12). -=item * +=item B<%j> -B<%U, %W> number of the week of the current year, with either the -first Sunday (%U) or the first Monday (%W) determining the first week. +The day of the year as a decimal number (range 001 to 366). -=item * +=item B<%m> -B<%Z> prints the time zone. +The month as a decimal number (range 01 to 12). + +=item B<%M> + +The minute as a decimal number (range 00 to 59). + +=item B<%p> + +Either `AM' or `PM' according to the given time value, or the corresponding +strings for the current locale. Noon is treated as `pm' and midnight as +`am'. Note that in many locales and `pm' notation is unsupported and in +such cases %p will return an empty string. + +=item B<%S> + +The second as a decimal number (range 00 to 61). + +=item B<%U> + +The week number of the current year as a decimal number, range 00 to 53, starting with the +first Sunday as the first day of week 01. See also %V and %W. + +=item B<%V> + +The ISO 8601:1988 week number of the current year as a decimal number, range 01 to 53, where +week 1 is the first week that has at least 4 days in the current year, and with Monday as the +first day of the week. See also %U and %W. + +=item B<%w> + +The day of the week as a decimal, range 0 to 6, Sunday being 0. See also %u. + +=item B<%W> + +The week number of the current year as a decimal number, range 00 to 53, starting with the +first Monday as the first day of week 01. + +=item B<%x> + +The preferred date representation for the current locale without the time. + +=item B<%X> + +The preferred time representation for the current locale without the date. + +=item B<%y> + +The year as a decimal number without a century (range 00 to 99). + +=item B<%Y> + +The year as a decimal number including the century. + +=item B<%Z> + +The time zone or name or abbreviation. + +=item B<%%> + +A literal `%' character. =back diff --git a/src/rrd_graph.c b/src/rrd_graph.c index 938132a..e8a07b6 100644 --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -1227,7 +1227,7 @@ print_calc(image_desc_t *im, char ***prdata) { long i,ii,validsteps; double printval; - time_t printtime; + struct tm tmvdef; int graphelement = 0; long vidx; int max_ii; @@ -1235,6 +1235,9 @@ print_calc(image_desc_t *im, char ***prdata) char *si_symb = ""; char *percent_s; int prlines = 1; + /* wow initializing tmvdef is quite a task :-) */ + time_t now = time(NULL); + localtime_r(&now,&tmvdef); if (im->imginfo) prlines++; for(i=0;igdes_c;i++){ switch(im->gdes[i].gf){ @@ -1252,7 +1255,7 @@ print_calc(image_desc_t *im, char ***prdata) vidx = im->gdes[i].vidx; if (im->gdes[vidx].gf==GF_VDEF) { /* simply use vals */ printval = im->gdes[vidx].vf.val; - printtime = im->gdes[vidx].vf.when; + localtime_r(&im->gdes[vidx].vf.when,&tmvdef); } else { /* need to calculate max,min,avg etcetera */ max_ii =((im->gdes[vidx].end - im->gdes[vidx].start) @@ -1298,21 +1301,6 @@ print_calc(image_desc_t *im, char ***prdata) } } /* prepare printval */ - if (!strcmp(im->gdes[i].format,"%c")) { /* VDEF time print */ - char ctime_buf[128]; /* PS: for ctime_r, must be >= 26 chars */ - int iii=0; - ctime_r(&printtime,ctime_buf); - while(isprint(ctime_buf[iii])){iii++;} - ctime_buf[iii]='\0'; - if (im->gdes[i].gf == GF_PRINT){ - (*prdata)[prlines-2] = malloc((FMT_LEG_LEN+2)*sizeof(char)); - sprintf((*prdata)[prlines-2],"%s (%lu)",ctime_buf,printtime); - (*prdata)[prlines-1] = NULL; - } else { - sprintf(im->gdes[i].legend,"%s (%lu)",ctime_buf,printtime); - graphelement = 1; - } - } else { if ((percent_s = strstr(im->gdes[i].format,"%S")) != NULL) { /* Magfact is set to -1 upon entry to print_calc. If it * is still less than 0, then we need to run auto_scale. @@ -1331,33 +1319,41 @@ print_calc(image_desc_t *im, char ***prdata) auto_scale(im,&printval,&si_symb,&magfact); } - if (im->gdes[i].gf == GF_PRINT){ + if (im->gdes[i].gf == GF_PRINT){ (*prdata)[prlines-2] = malloc((FMT_LEG_LEN+2)*sizeof(char)); (*prdata)[prlines-1] = NULL; - if (bad_format(im->gdes[i].format)) { - rrd_set_error("bad format for PRINT in '%s'", im->gdes[i].format); + if (im->gdes[i].strftm){ + strftime((*prdata)[prlines-2],FMT_LEG_LEN,im->gdes[i].format,&tmvdef); + } else { + if (bad_format(im->gdes[i].format)) { + rrd_set_error("bad format for PRINT in '%s'", im->gdes[i].format); return -1; - } + } + #ifdef HAVE_SNPRINTF - snprintf((*prdata)[prlines-2],FMT_LEG_LEN,im->gdes[i].format,printval,si_symb); + snprintf((*prdata)[prlines-2],FMT_LEG_LEN,im->gdes[i].format,printval,si_symb); #else - sprintf((*prdata)[prlines-2],im->gdes[i].format,printval,si_symb); + sprintf((*prdata)[prlines-2],im->gdes[i].format,printval,si_symb); #endif - } else { + } + } else { /* GF_GPRINT */ - if (bad_format(im->gdes[i].format)) { + if (im->gdes[i].strftm){ + strftime(im->gdes[i].legend,FMT_LEG_LEN,im->gdes[i].format,&tmvdef); + } else { + if (bad_format(im->gdes[i].format)) { rrd_set_error("bad format for GPRINT in '%s'", im->gdes[i].format); return -1; - } + } #ifdef HAVE_SNPRINTF - snprintf(im->gdes[i].legend,FMT_LEG_LEN-2,im->gdes[i].format,printval,si_symb); + snprintf(im->gdes[i].legend,FMT_LEG_LEN-2,im->gdes[i].format,printval,si_symb); #else - sprintf(im->gdes[i].legend,im->gdes[i].format,printval,si_symb); + sprintf(im->gdes[i].legend,im->gdes[i].format,printval,si_symb); #endif - graphelement = 1; - } - } + } + graphelement = 1; + } break; case GF_LINE: case GF_AREA: @@ -2943,6 +2939,7 @@ gdes_alloc(image_desc_t *im){ im->gdes[im->gdes_c-1].col = 0x0; im->gdes[im->gdes_c-1].legend[0]='\0'; im->gdes[im->gdes_c-1].format[0]='\0'; + im->gdes[im->gdes_c-1].strftm=0; im->gdes[im->gdes_c-1].rrd[0]='\0'; im->gdes[im->gdes_c-1].ds=-1; im->gdes[im->gdes_c-1].cf_reduce=CF_AVERAGE; diff --git a/src/rrd_graph.h b/src/rrd_graph.h index e143b7b..ef6a696 100644 --- a/src/rrd_graph.h +++ b/src/rrd_graph.h @@ -118,6 +118,7 @@ typedef struct graph_desc_t { gfx_color_t col; /* graph color */ char format[FMT_LEG_LEN+5]; /* format for PRINT AND GPRINT */ char legend[FMT_LEG_LEN+5]; /* legend*/ + int strftm; /* should the VDEF legend be formated with strftime */ double leg_x,leg_y; /* location of legend */ double yrule; /* value for y rule line and for VDEF */ time_t xrule; /* time for x rule line and for VDEF */ diff --git a/src/rrd_graph_helper.c b/src/rrd_graph_helper.c index 3af2b1e..d6411a0 100644 --- a/src/rrd_graph_helper.c +++ b/src/rrd_graph_helper.c @@ -256,7 +256,7 @@ int rrd_parse_print(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) { /* vname:CF:format in case of DEF-based vname ** vname:CF:format in case of CDEF-based vname - ** vname:format in case of VDEF-based vname + ** vname:format[:strftime] in case of VDEF-based vname */ if ((gdp->vidx=rrd_parse_find_vname(line,eaten,gdp,im))<0) return 1; @@ -279,6 +279,11 @@ rrd_parse_print(const char *const line, unsigned int *const eaten, graph_desc_t get the format at this juncture */ strcpy(gdp->format,gdp->legend); gdp->legend[0]='\0'; + /* this is a very crud test, parsing :style flags should be in a function */ + if (im->gdes[gdp->vidx].gf == GF_VDEF && strcmp(line+(*eaten),":strftime")==0){ + gdp->strftm = 1; + (*eaten)+=strlen(":strftime"); + } return 0; } -- 2.11.0