[rrd-developers] [PATCH] time offset

Tobias Oetiker tobi at oetiker.ch
Wed Dec 3 13:20:07 CET 2008


Hi Zou,

Thanks for your patch. You try to address a problem arising from
the fact that all time in RRD files is based on GMT.

With your patch you are changing the structure of the rrd file
which would render this version incompatible with all existing rrd
files without prividing a complete solution to the problem.

I don't know how it should be done, but this is what I would
expect.

* a method to tell rrdtool to base it's days on whatever is
  regarded to be a day in a selectable timezone.

* sensible handling of switching between summer and winter time.

cheers
tobi


Nov 25 Zou Guangxian wrote:

> Hi!
>
> create the rrdtool with the following statement, I wanna to store the data
> from '00:00' of the day, and hope to store values at '00:00' everyday with
> "RRA:LAST:0.5:288:37200". but after fetch the data, I found it will output
> the value with timestamp '08:00' in that day.
>
>
>
> [CODE]
>
> #!/bin/sh
>
> start=`date +'00:00 %m/%e/%Y'`
>
> /usr/bin/rrdtool create $1.rrd \
>
>   --start "$start" \
>
>   --step 300 \
>
>   DS:total:GAUGE:600:0:U \
>
>   DS:new:GAUGE:600:0:U \
>
>   RRA:LAST:0.5:1:288 \
>
>   RRA:LAST:0.5:12:720 \
>
>   RRA:LAST:0.5:288:37200 \
>
>   RRA:AVERAGE:0.5:1:288 \
>
>   RRA:AVERAGE:0.5:12:720 \
>
>   RRA:AVERAGE:0.5:288:37200
>
> [/CODE]
>
>
>
> this problem is caused by the lines in rrd_fetch.c:
>
> 243            cal_end = (rrd.live_head->last_up - (rrd.live_head->last_up
>
> 244                                                 %
> (rrd.rra_def[i].pdp_cnt
>
> 245                                                    *
>
> 246                                                    rrd.stat_head->
>
> 248                                                    pdp_step)));
>
>
>
> pdp_step = 300, pdp_cnt = 288, so pdp_cnt* pdp_step = 86400.
>
>
>
> 0 seconds since 1970-1-1 0:0:0 UTC, but it is also since 1970-1-1 8:0:0 CST.
>
>
> For example,
>
> 2008-11-25 0: 0: 0 CST= 1227542400,
>
> 1227542400 % 86400 = 57600,
>
> 1227542400 - 57600 = 1227484800 = 2008-11-24 8: 0: 0: 0 CST.
>
>
>
> Even set timezone to UTC+0, but rrd start from 1:00,
> "RRA:LAST:0.5:288:37200 " still can't produce data at 1:00 everyday. I hope
> it should generate a data every 86400 from the start time. the following
> patch will add create_time field to rrd database, and time calculation will
> based on create_time.
>
>
>
> [CODE]
>
> diff -Nur rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_create.c
> rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_create.c
>
> --- rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_create.c      Sun Oct  5 00:04:04
> 2008
>
> +++ rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_create.c Tue Nov 25 17:08:12 2008
>
> @@ -152,6 +152,7 @@
>
>      rrd.rra_def = NULL;
>
>
>
>      rrd.live_head->last_up = last_up;
>
> +    rrd.stat_head->create_time = last_up;
>
>
>
>      /* optind points to the first non-option command line arg,
>
>       * in this case, the file name. */
>
> @@ -708,7 +709,7 @@
>
>
>
>      rrd->pdp_prep->scratch[PDP_val].u_val = 0.0;
>
>      rrd->pdp_prep->scratch[PDP_unkn_sec_cnt].u_cnt =
>
> -        rrd->live_head->last_up % rrd->stat_head->pdp_step;
>
> +        (rrd->live_head->last_up - rrd->stat_head->create_time) %
> rrd->stat_head->pdp_step;
>
>
>
>      for (i = 0; i < rrd->stat_head->ds_cnt; i++)
>
>          write(rrd_file, rrd->pdp_prep, sizeof(pdp_prep_t));
>
> @@ -745,7 +746,7 @@
>
>              rrd->cdp_prep->scratch[CDP_val].u_val = DNAN;
>
>              /* startup missing pdp count */
>
>              rrd->cdp_prep->scratch[CDP_unkn_pdp_cnt].u_cnt =
>
> -                ((rrd->live_head->last_up -
>
> +                ((rrd->live_head->last_up - rrd->stat_head->create_time -
>
>                    rrd->pdp_prep->scratch[PDP_unkn_sec_cnt].u_cnt)
>
>                   % (rrd->stat_head->pdp_step
>
>                      * rrd->rra_def[i].pdp_cnt)) / rrd->stat_head->pdp_step;
>
> diff -Nur rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_dump.c
> rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_dump.c
>
> --- rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_dump.c        Sun Oct  5 00:04:04
> 2008
>
> +++ rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_dump.c  Tue Nov 25 17:08:20 2008
>
> @@ -96,6 +96,14 @@
>
>      fprintf(out_file, "\t<step> %lu </step> <!-- Seconds -->\n",
>
>              rrd.stat_head->pdp_step);
>
>  #if HAVE_STRFTIME
>
> +    localtime_r(&rrd.stat_head->create_time, &tm);
>
> +    strftime(somestring, 200, "%Y-%m-%d %H:%M:%S %Z", &tm);
>
> +#else
>
> +# error "Need strftime"
>
> +#endif
>
> +       fprintf(out_file, "\t<createtime> %lu </createtime> <!-- %s
> -->\n\n",
>
> +            (unsigned long) rrd.stat_head->create_time, somestring);
>
> +#if HAVE_STRFTIME
>
>      localtime_r(&rrd.live_head->last_up, &tm);
>
>      strftime(somestring, 200, "%Y-%m-%d %H:%M:%S %Z", &tm);
>
>  #else
>
> @@ -393,7 +401,7 @@
>
>                  ii = 0; /* wrap if max row cnt is reached */
>
>              }
>
>              now = (rrd.live_head->last_up
>
> -                   - rrd.live_head->last_up
>
> +                                   - (rrd.live_head->last_up -
> rrd.stat_head->create_time)
>
>                     % (rrd.rra_def[i].pdp_cnt * rrd.stat_head->pdp_step))
>
>                  + (timer * rrd.rra_def[i].pdp_cnt *
> rrd.stat_head->pdp_step);
>
>
>
> diff -Nur rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_fetch.c
> rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_fetch.c
>
> --- rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_fetch.c         Sun Oct  5 00:04:04
> 2008
>
> +++ rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_fetch.c   Tue Nov 25 17:08:30 2008
>
> @@ -240,7 +240,7 @@
>
>      for (i = 0; (unsigned) i < rrd.stat_head->rra_cnt; i++) {
>
>          if (cf_conv(rrd.rra_def[i].cf_nam) == cf_idx) {
>
>
>
> -            cal_end = (rrd.live_head->last_up - (rrd.live_head->last_up
>
> +            cal_end = (rrd.live_head->last_up - ((rrd.live_head->last_up -
> rrd.stat_head->create_time)
>
>                                                   % (rrd.rra_def[i].pdp_cnt
>
>                                                      *
>
>                                                      rrd.stat_head->
>
> @@ -310,8 +310,8 @@
>
>
>
>      /* set the wish parameters to their real values */
>
>      *step = rrd.stat_head->pdp_step * rrd.rra_def[chosen_rra].pdp_cnt;
>
> -    *start -= (*start % *step);
>
> -    *end += (*step - *end % *step);
>
> +    *start -= (((*start) - rrd.stat_head->create_time) % *step);
>
> +    *end += (*step - ((*end) - rrd.stat_head->create_time) % *step);
>
>      rows = (*end - *start) / *step + 1;
>
>
>
>  #ifdef DEBUG
>
> @@ -341,11 +341,11 @@
>
>
>
>      /* find start and end offset */
>
>      rra_end_time = (rrd.live_head->last_up
>
> -                    - (rrd.live_head->last_up % *step));
>
> +                    - ((rrd.live_head->last_up -
> rrd.stat_head->create_time) % *step));
>
>      rra_start_time = (rra_end_time
>
>                        - (*step * (rrd.rra_def[chosen_rra].row_cnt - 1)));
>
>      /* here's an error by one if we don't be careful */
>
> -    start_offset = (long) (*start + *step - rra_start_time) / (long) *step;
>
> +    start_offset = (long)(((double)(*start)/(long)*step) + 1 -
> ((double)(rra_start_time)/(long)*step));
>
>      end_offset = (long) (rra_end_time - *end) / (long) *step;
>
>  #ifdef DEBUG
>
>      fprintf(stderr,
>
> diff -Nur rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_format.h
> rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_format.h
>
> --- rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_format.h     Sun Oct  5 00:04:04
> 2008
>
> +++ rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_format.h         Tue Nov 25
> 17:08:42 2008
>
> @@ -117,6 +117,7 @@
>
>      char      version[5];   /* version of the format */
>
>      double    float_cookie; /* is it the correct double
>
>                               * representation ?  */
>
> +    time_t    create_time;  /* when was rrd created */
>
>
>
>      /* Data Base Structure Definition **** */
>
>      unsigned long ds_cnt;   /* how many different ds provide
>
> diff -Nur rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_restore.c
> rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_restore.c
>
> --- rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_restore.c    Sun Oct  5 00:04:04
> 2008
>
> +++ rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_restore.c        Tue Nov 25
> 17:08:52 2008
>
> @@ -872,6 +872,9 @@
>
>          else if (xmlStrcmp(child->name, (const xmlChar *) "step") == 0)
>
>              status = get_int_from_node(doc, child,
>
>                                         (int *) &rrd->stat_head->pdp_step);
>
> +                else if (xmlStrcmp(child->name, (const xmlChar *)
> "createtime") == 0)
>
> +            status = get_int_from_node(doc, child,
>
> +                                       (int *)
> &rrd->stat_head->create_time);
>
>          else if (xmlStrcmp(child->name, (const xmlChar *) "lastupdate") ==
> 0)
>
>              status = get_int_from_node(doc, child,
>
>                                         (int *) &rrd->live_head->last_up);
>
> diff -Nur rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_update.c
> rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_update.c
>
> --- rrdtool-1.3.4/rrdtool-1.3.4/src/rrd_update.c     Sun Oct  5 00:04:04
> 2008
>
> +++ rrdtool-1.3.4_/rrdtool-1.3.4/src/rrd_update.c         Tue Nov 25
> 17:08:56 2008
>
> @@ -1131,11 +1131,11 @@
>
>      unsigned long occu_pdp_age; /* how long ago was the last pdp_step time
> */
>
>
>
>      /* when was the current pdp started */
>
> -    proc_pdp_age = rrd->live_head->last_up % rrd->stat_head->pdp_step;
>
> +       proc_pdp_age = (rrd->live_head->last_up -
> rrd->stat_head->create_time) % rrd->stat_head->pdp_step;
>
>      proc_pdp_st = rrd->live_head->last_up - proc_pdp_age;
>
>
>
>      /* when did the last pdp_st occur */
>
> -    occu_pdp_age = current_time % rrd->stat_head->pdp_step;
>
> +    occu_pdp_age = (current_time - rrd->stat_head->create_time) %
> rrd->stat_head->pdp_step;
>
>      occu_pdp_st = current_time - occu_pdp_age;
>
>
>
>      if (occu_pdp_st > proc_pdp_st) {
>
> [/CODE]
>
>
>
> --
>
> zou guangxian
>
>

-- 
Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
http://it.oetiker.ch tobi at oetiker.ch ++41 62 775 9902 / sb: -9900



More information about the rrd-developers mailing list