[rrd-developers] How to create a new Data Type and Consolidation Function?

Long long_at_work at yahoo.ca
Sat Feb 5 20:49:37 CET 2011


Hi, 

I have created a new DST called DIFFERENCE and a new CF called SUM (see the
patch file at the end of this post). The patch has been created from the
trunk (SVN checkout) and applied to
http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.4.4.tar.gz

I have written a very simple test and my patch is not working, it's not
adding the differences, all CDP are zeros.

Before I dig further, could you tell me if I am on the right track for
completely lost?

Here's my test result (notice I used the new DST DIFFERENCE and the new CF
SUM when creating the RRD file):

set -x ; rm -f test_difference_ds_sum_cf.rrd; ./rrdtool create
test_difference_ds_sum_cf.rrd --step 60 DS:test_new_ds_cf:DIFFERENCE:120:U:U
RRA:SUM:0.5:2:30; ./rrdtool info test_difference_ds_sum_cf.rrd; NOW=`date
+%s`; for i in `seq 5`; do TIME_DELTA=`expr $i \* 60`; NEW_VAL=`expr
$TIME_DELTA + $NOW`; ./rrdtool update test_difference_ds_sum_cf.rrd
$NEW_VAL:$NEW_VAL; done; ./rrdtool fetch test_difference_ds_sum_cf.rrd SUM
--start $NOW --end $NEW_VAL; set +x
+ rm -i -f test_difference_ds_sum_cf.rrd
+ ./rrdtool create test_difference_ds_sum_cf.rrd --step 60
DS:test_new_ds_cf:DIFFERENCE:120:U:U RRA:SUM:0.5:2:30
+ ./rrdtool info test_difference_ds_sum_cf.rrd
filename = "test_difference_ds_sum_cf.rrd"
rrd_version = "0003"
step = 60
last_update = 1296894230
header_size = 592
ds[test_new_ds_cf].index = 0
ds[test_new_ds_cf].type = "DIFFERENCE"
ds[test_new_ds_cf].minimal_heartbeat = 120
ds[test_new_ds_cf].min = NaN
ds[test_new_ds_cf].max = NaN
ds[test_new_ds_cf].last_ds = "U"
ds[test_new_ds_cf].value = 0.0000000000e+00
ds[test_new_ds_cf].unknown_sec = 50
rra[0].cf = "SUM"
rra[0].rows = 30
rra[0].cur_row = 17
rra[0].pdp_per_row = 2
rra[0].xff = 5.0000000000e-01
rra[0].cdp_prep[0].value = NaN
rra[0].cdp_prep[0].unknown_datapoints = 1
++ date +%s
+ NOW=1296894240
++ seq 5
+ for i in '`seq 5`'
++ expr 1 '*' 60
+ TIME_DELTA=60
++ expr 60 + 1296894240
+ NEW_VAL=1296894300
+ ./rrdtool update test_difference_ds_sum_cf.rrd 1296894300:1296894300
+ for i in '`seq 5`'
++ expr 2 '*' 60
+ TIME_DELTA=120
++ expr 120 + 1296894240
+ NEW_VAL=1296894360
+ ./rrdtool update test_difference_ds_sum_cf.rrd 1296894360:1296894360
+ for i in '`seq 5`'
++ expr 3 '*' 60
+ TIME_DELTA=180
++ expr 180 + 1296894240
+ NEW_VAL=1296894420
+ ./rrdtool update test_difference_ds_sum_cf.rrd 1296894420:1296894420
+ for i in '`seq 5`'
++ expr 4 '*' 60
+ TIME_DELTA=240
++ expr 240 + 1296894240
+ NEW_VAL=1296894480
+ ./rrdtool update test_difference_ds_sum_cf.rrd 1296894480:1296894480
+ for i in '`seq 5`'
++ expr 5 '*' 60
+ TIME_DELTA=300
++ expr 300 + 1296894240
+ NEW_VAL=1296894540
+ ./rrdtool update test_difference_ds_sum_cf.rrd 1296894540:1296894540
+ ./rrdtool fetch test_difference_ds_sum_cf.rrd SUM --start 1296894240 --end
1296894540
                 test_new_ds_cf

1296894360: 0.0000000000e+00
1296894480: 0.0000000000e+00
1296894600: nan
+ set +x



Here's my patch file. Thanks !

diff -Naur rrdtool-trunk-original/src/rrd_create.c
rrdtool-trunk/src/rrd_create.c
--- rrdtool-trunk-original/src/rrd_create.c     2011-02-05
13:23:01.000000000 -0500
+++ rrdtool-trunk/src/rrd_create.c     2011-02-04 15:34:56.000000000 -0500
@@ -252,6 +252,7 @@
             /* parse the remainder of the arguments */
             switch (dst_conv(rrd.ds_def[rrd.stat_head->ds_cnt].dst)) {
             case DST_COUNTER:
+            case DST_DIFFERENCE:
             case DST_ABSOLUTE:
             case DST_GAUGE:
             case DST_DERIVE:
diff -Naur rrdtool-trunk-original/src/rrd_dump.c
rrdtool-trunk/src/rrd_dump.c
--- rrdtool-trunk-original/src/rrd_dump.c     2011-02-05 13:23:01.000000000
-0500
+++ rrdtool-trunk/src/rrd_dump.c     2011-02-04 15:38:43.000000000 -0500
@@ -271,6 +271,7 @@
         case CF_MAXIMUM:
         case CF_MINIMUM:
         case CF_LAST:
+        case CF_SUM:
         default:
             CB_FMTS("\t\t<xff>%0.10e</xff>\n",
                 rrd.rra_def[i].par[RRA_cdp_xff_val].u_val);
@@ -390,6 +391,7 @@
             case CF_MAXIMUM:
             case CF_MINIMUM:
             case CF_LAST:
+            case CF_SUM:
             default:
                 value = rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
ii].scratch[CDP_val].u_val;
                 if (isnan(value)) {
diff -Naur rrdtool-trunk-original/src/rrd_format.c
rrdtool-trunk/src/rrd_format.c
--- rrdtool-trunk-original/src/rrd_format.c     2011-02-05
13:23:01.000000000 -0500
+++ rrdtool-trunk/src/rrd_format.c     2011-02-04 14:46:57.000000000 -0500
@@ -61,6 +61,7 @@
         converter(GAUGE, DST_GAUGE)
         converter(DERIVE, DST_DERIVE)
         converter(COMPUTE, DST_CDEF)
+        converter(DIFFERENCE, DST_DIFFERENCE)
         rrd_set_error("unknown data acquisition function '%s'", string);
     return (enum dst_en)(-1);
 }
@@ -80,6 +81,7 @@
         converter(SEASONAL, CF_SEASONAL)
         converter(DEVSEASONAL, CF_DEVSEASONAL)
         converter(FAILURES, CF_FAILURES)
+        converter(SUM, CF_SUM)
         rrd_set_error("unknown consolidation function '%s'", string);
     return (enum cf_en)(-1);
 }
@@ -98,6 +100,7 @@
         case CF_DEVSEASONAL: return "DEVSEASONAL";
         case CF_FAILURES:    return "FAILURES";
         case CF_MHWPREDICT:  return "MHWPREDICT";
+        case CF_SUM:         return "SUM";
 
         default:
             return NULL;
diff -Naur rrdtool-trunk-original/src/rrd_format.h
rrdtool-trunk/src/rrd_format.h
--- rrdtool-trunk-original/src/rrd_format.h     2011-02-05
13:23:01.000000000 -0500
+++ rrdtool-trunk/src/rrd_format.h     2011-02-04 14:51:01.000000000 -0500
@@ -138,6 +138,7 @@
     DST_ABSOLUTE,
     DST_GAUGE,
     DST_DERIVE,
+    DST_DIFFERENCE,
     DST_CDEF
 };
 
@@ -192,8 +193,9 @@
      * */
     CF_FAILURES,
     /* HWPREDICT that follows a moving baseline */
-    CF_MHWPREDICT
+    CF_MHWPREDICT,
         /* new entries must come last !!! */
+    CF_SUM
 };
 
                        /* A binary array of failure indicators: 1 indicates
diff -Naur rrdtool-trunk-original/src/rrd_graph.c
rrdtool-trunk/src/rrd_graph.c
--- rrdtool-trunk-original/src/rrd_graph.c     2011-02-05 13:23:01.000000000
-0500
+++ rrdtool-trunk/src/rrd_graph.c     2011-02-05 13:22:37.000000000 -0500
@@ -749,6 +749,7 @@
                     case CF_DEVSEASONAL:
                     case CF_DEVPREDICT:
                     case CF_SEASONAL:
+                    case CF_SUM:
                     case CF_AVERAGE:
                         newval += srcptr[i * (*ds_cnt) + col];
                         break;
@@ -782,6 +783,7 @@
                 case CF_FAILURES:
                 case CF_MAXIMUM:
                 case CF_LAST:
+                case CF_SUM:
                     break;
                 }
             }
@@ -1567,8 +1569,11 @@
                     case CF_DEVPREDICT:
                     case CF_DEVSEASONAL:
                     case CF_SEASONAL:
+                    case CF_SUM:
                     case CF_AVERAGE:
-                        validsteps++;
+                        if ( CF_SUM != im->gdes[i].cf ) {
+                            validsteps++;
+                        }
                         printval += im->gdes[vidx].data[ii];
                         break;
                     case CF_MINIMUM:
@@ -4901,6 +4906,8 @@
         gdes->vf.op = VDEF_MAXIMUM;
     else if (!strcmp("AVERAGE", func))
         gdes->vf.op = VDEF_AVERAGE;
+    else if (!strcmp("SUM", func))
+        gdes->vf.op = VDEF_SUM;
     else if (!strcmp("STDEV", func))
         gdes->vf.op = VDEF_STDEV;
     else if (!strcmp("MINIMUM", func))
@@ -4945,6 +4952,7 @@
         break;
     case VDEF_MAXIMUM:
     case VDEF_AVERAGE:
+    case VDEF_SUM:
     case VDEF_STDEV:
     case VDEF_MINIMUM:
     case VDEF_TOTAL:
@@ -5067,6 +5075,7 @@
         break;
     case VDEF_TOTAL:
     case VDEF_STDEV:
+    case VDEF_SUM:
     case VDEF_AVERAGE:{
         int       cnt = 0;
         double    sum = 0.0;
@@ -5079,7 +5088,7 @@
             };
         }
         if (cnt) {
-            if (dst->vf.op == VDEF_TOTAL) {
+            if (dst->vf.op == VDEF_TOTAL || dst->vf.op == VDEF_SUM) {
                 dst->vf.val = sum * src->step;
                 dst->vf.when = 0;   /* no time component */
                 dst->vf.never = 1;
diff -Naur rrdtool-trunk-original/src/rrd_graph.h
rrdtool-trunk/src/rrd_graph.h
--- rrdtool-trunk-original/src/rrd_graph.h     2011-02-05 13:23:01.000000000
-0500
+++ rrdtool-trunk/src/rrd_graph.h     2011-02-04 16:06:07.000000000 -0500
@@ -70,6 +70,7 @@
         , VDEF_STDEV    /* the standard deviation */
         , VDEF_PERCENT  /* Nth percentile */
         , VDEF_TOTAL    /* average multiplied by time */
+        , VDEF_SUM      /* average multiplied by time */
         , VDEF_FIRST    /* first non-unknown value and time */
         , VDEF_LAST     /* last  non-unknown value and time */
         , VDEF_LSLSLOPE /* least squares line slope */
diff -Naur rrdtool-trunk-original/src/rrd_update.c
rrdtool-trunk/src/rrd_update.c
--- rrdtool-trunk-original/src/rrd_update.c     2011-02-05
13:23:01.000000000 -0500
+++ rrdtool-trunk/src/rrd_update.c     2011-02-04 23:07:13.000000000 -0500
@@ -1131,6 +1131,9 @@
                 }
                 rate = pdp_new[ds_idx] / interval;
                 break;
+            case DST_DIFFERENCE:
+                pdp_new[ds_idx] = pdp_new[ds_idx] * interval;
+                break;
             default:
                 rrd_set_error("rrd contains unknown DS type : '%s'",
                               rrd->ds_def[ds_idx].dst);
@@ -1664,12 +1667,16 @@
     rrd_value_t cum_val, cur_val;
 
     switch (current_cf) {
+    case CF_SUM:
     case CF_AVERAGE:
         cum_val = IFDNAN(scratch[CDP_val].u_val, 0.0);
         cur_val = IFDNAN(pdp_temp_val, 0.0);
         scratch[CDP_primary_val].u_val =
-            (cum_val + cur_val * start_pdp_offset) /
+            (cum_val + cur_val * start_pdp_offset);
+        if ( current_cf == CF_AVERAGE ) {
+          scratch[CDP_primary_val].u_val /=
             (pdp_cnt - scratch[CDP_unkn_pdp_cnt].u_cnt);
+        }
         break;
     case CF_MAXIMUM:
         cum_val = IFDNAN(scratch[CDP_val].u_val, -DINF);
@@ -1786,6 +1793,7 @@
             return -DINF;
         case CF_MINIMUM:
             return DINF;
+        case CF_SUM:
         case CF_AVERAGE:
             return 0;
         default:
@@ -1794,6 +1802,7 @@
     }
     else {
         switch (current_cf) {
+        case CF_SUM:
         case CF_AVERAGE:
             return pdp_temp_val *  pdp_into_cdp_cnt ;
         default:
@@ -1823,7 +1832,7 @@
     )
 {
     if (isnan(cdp_val)) {
-        if (current_cf == CF_AVERAGE) {
+        if (current_cf == CF_AVERAGE || current_cf == CF_SUM) {
             pdp_temp_val *= elapsed_pdp_st;
         }
 #ifdef DEBUG
@@ -1832,7 +1841,7 @@
 #endif
         return pdp_temp_val;
     }
-    if (current_cf == CF_AVERAGE)
+    if (current_cf == CF_AVERAGE || current_cf == CF_SUM)
         return cdp_val + pdp_temp_val * elapsed_pdp_st;
     if (current_cf == CF_MINIMUM)
         return (pdp_temp_val < cdp_val) ? pdp_temp_val : cdp_val;

-- 
View this message in context: http://rrd-mailinglists.937164.n2.nabble.com/How-to-create-a-new-Data-Type-and-Consolidation-Function-tp5990330p5996203.html
Sent from the RRDtool Developers Mailinglist mailing list archive at Nabble.com.



More information about the rrd-developers mailing list