]> arthur.barton.de Git - netdata.git/commitdiff
cleanup propriatery charts.d charts; proc_stat optimization; minor fixes for not...
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Mon, 4 Jul 2016 19:41:49 +0000 (22:41 +0300)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Mon, 4 Jul 2016 19:41:49 +0000 (22:41 +0300)
charts.d/airsearches.chart.sh [deleted file]
charts.d/crsproxy.chart.sh [deleted file]
src/proc_stat.c
src/rrd.c

diff --git a/charts.d/airsearches.chart.sh b/charts.d/airsearches.chart.sh
deleted file mode 100755 (executable)
index 449b142..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/bin/sh
-
-airsearches_url=
-airsearches_cmds=
-airsearches_update_every=15
-
-airsearches_get() {
-       wget 2>/dev/null -O - "$airsearches_url" |\
-               sed -e "s|<br />|\n|g" -e "s|: |=|g" -e "s| \+|_|g" -e "s/^/airsearches_/g" |\
-               tr "[A-Z]\.\!@#\$%^&*()_+\-" "[a-z]_____________" |\
-               egrep "^airsearches_[a-z0-9_]+=[0-9]+$"
-}
-
-airsearches_check() {
-       # make sure we have all the commands we need
-       require_cmd wget || return 1
-
-       # make sure we are configured
-       if [ -z "$airsearches_url" ]
-               then
-               echo >&2 "$PROGRAM_NAME: airsearches: not configured. Please set airsearches_url='url' in $confd/airsearches.conf"
-               return 1
-       fi
-
-       # check once if the url works
-       wget 2>/dev/null -O /dev/null "$airsearches_url"
-       if [ ! $? -eq 0 ]
-       then
-               echo >&2 "$PROGRAM_NAME: airsearches: cannot fetch the url: $airsearches_url. Please set airsearches_url='url' in $confd/airsearches.conf"
-               return 1
-       fi
-
-       # if the admin did not give any commands
-       # find the available ones
-       if [ -z "$airsearches_cmds" ]
-       then
-               airsearches_cmds="$(airsearches_get | cut -d '=' -f 1 | sed "s/^airsearches_//g" | sort -u)"
-               echo
-       fi
-
-       # did we find any commands?
-       if [ -z "$airsearches_cmds" ]
-       then
-               echo >&2 "$PROGRAM_NAME: airsearches: cannot find command list automatically. Please set airsearches_cmds='...' in $confd/airsearches.conf"
-               return 1
-       fi
-
-       # ok we can do it
-       return 0
-}
-
-airsearches_create() {
-       [ -z "$airsearches_cmds" ] && return 1
-
-       # create the charts
-       local x=
-       echo "CHART airsearches.affiliates '' 'Air Searches per affiliate' 'requests / min' airsearches '' stacked 20000 $airsearches_update_every"
-       for x in $airsearches_cmds
-       do
-               echo "DIMENSION $x '' incremental 60 1"
-       done
-
-       return 0
-}
-
-airsearches_update() {
-       # the first argument to this function is the microseconds since last update
-       # pass this parameter to the BEGIN statement (see bellow).
-
-       # do all the work to collect / calculate the values
-       # for each dimension
-       # remember: KEEP IT SIMPLE AND SHORT
-
-       # get the values from airsearches
-       eval "$(airsearches_get)"
-
-       # write the result of the work.
-       local x=
-
-       echo "BEGIN airsearches.affiliates $1"
-       for x in $airsearches_cmds
-       do
-               eval "v=\$airsearches_$x"
-               echo "SET $x = $v"
-       done
-       echo "END"
-
-       airsearches_dt=0
-
-       return 0
-}
diff --git a/charts.d/crsproxy.chart.sh b/charts.d/crsproxy.chart.sh
deleted file mode 100755 (executable)
index 9ad8b33..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/bin/sh
-
-crsproxy_url=
-crsproxy_cmds=
-crsproxy_update_every=15
-
-crsproxy_get() {
-       wget 2>/dev/null -O - "$crsproxy_url" |\
-               sed \
-                       -e "s/ \+/ /g" \
-                       -e "s/\./_/g" \
-                       -e "s/ =/=/g" \
-                       -e "s/= /=/g" \
-                       -e "s/^/crsproxy_/g" |\
-               egrep "^crsproxy_[a-zA-Z][a-zA-Z0-9_]*=[0-9]+$"
-}
-
-crsproxy_check() {
-       # make sure we have all the commands we need
-       require_cmd wget || return 1
-       
-       if [ -z "$crsproxy_url" ]
-               then
-               echo >&2 "$PROGRAM_NAME: crsproxy: not configured. Please set crsproxy_url='url' in $confd/crsproxy.conf"
-               return 1
-       fi
-
-       # check once if the url works
-       wget 2>/dev/null -O /dev/null "$crsproxy_url"
-       if [ ! $? -eq 0 ]
-       then
-               echo >&2 "$PROGRAM_NAME: crsproxy: cannot fetch the url: $crsproxy_url. Please set crsproxy_url='url' in $confd/crsproxy.conf"
-               return 1
-       fi
-
-       # if the user did not request specific commands
-       # find the commands available
-       if [ -z "$crsproxy_cmds" ]
-       then
-               crsproxy_cmds="$(crsproxy_get | cut -d '=' -f 1 | sed "s/^crsproxy_cmd_//g" | sort -u)"
-       fi
-
-       # if no commands are available
-       if [ -z "$crsproxy_cmds" ]
-       then
-               echo >&2 "$PROGRAM_NAME: crsproxy: cannot find command list automatically. Please set crsproxy_cmds='...' in $confd/crsproxy.conf"
-               return 1
-       fi
-       return 0
-}
-
-crsproxy_create() {
-       # create the charts
-       cat <<EOF
-CHART crsproxy.connected '' "CRS Proxy Connected Clients" "clients" crsproxy '' line 20000 $crsproxy_update_every
-DIMENSION web '' absolute 1 1
-DIMENSION native '' absolute 1 1
-DIMENSION virtual '' absolute 1 1
-CHART crsproxy.requests '' "CRS Proxy Requests Rate" "requests / min" crsproxy '' area 20001 $crsproxy_update_every
-DIMENSION web '' incremental 60 1
-DIMENSION native '' incremental -60 1
-CHART crsproxy.clients '' "CRS Proxy Clients Rate" "clients / min" crsproxy '' area 20010 $crsproxy_update_every
-DIMENSION web '' incremental 60 1
-DIMENSION native '' incremental -60 1
-DIMENSION virtual '' incremental 60 1
-CHART crsproxy.replies '' "CRS Replies Rate" "replies / min" crsproxy '' area 20020 $crsproxy_update_every
-DIMENSION ok '' incremental 60 1
-DIMENSION failed '' incremental -60 1
-CHART crsproxy.bconnections '' "Back-End Connections Rate" "connections / min" crsproxy '' area 20030 $crsproxy_update_every
-DIMENSION ok '' incremental 60 1
-DIMENSION failed '' incremental -60 1
-EOF
-
-       local x=
-       echo "CHART crsproxy.commands '' 'CRS Commands Requests' 'requests / min' crsproxy '' stacked 20100 $crsproxy_update_every"
-       for x in $crsproxy_cmds
-       do
-               echo "DIMENSION $x '' incremental 60 $crsproxy_update_every"
-       done
-
-       echo "CHART crsproxy.commands_failed '' 'CRS Failed Commands' 'replies / min' crsproxy '' stacked 20110 $crsproxy_update_every"
-       for x in $crsproxy_cmds
-       do
-               echo "DIMENSION $x '' incremental 60 $crsproxy_update_every"
-       done
-
-       return 0
-}
-
-
-crsproxy_update() {
-       # the first argument to this function is the microseconds since last update
-       # pass this parameter to the BEGIN statement (see bellow).
-
-       # do all the work to collect / calculate the values
-       # for each dimension
-       # remember: KEEP IT SIMPLE AND SHORT
-
-       # get the values from crsproxy
-       eval "$(crsproxy_get)"
-
-
-       # write the result of the work.
-       cat <<VALUESEOF
-BEGIN crsproxy.connected $1
-SET web = $((crsproxy_web_clients_opened - crsproxy_web_clients_closed))
-SET native = $((crsproxy_crs_clients_opened - crsproxy_crs_clients_closed))
-SET virtual = $((crsproxy_virtual_clients_opened - crsproxy_virtual_clients_closed))
-END
-BEGIN crsproxy.requests $1
-SET web = $crsproxy_web_requests
-SET native = $crsproxy_native_requests
-END
-BEGIN crsproxy.clients $1
-SET web = $crsproxy_web_clients_opened
-SET native = $crsproxy_crs_clients_opened
-SET virtual = $crsproxy_virtual_clients_opened
-END
-BEGIN crsproxy.replies $1
-SET ok = $crsproxy_replies_success
-SET failed = $crsproxy_replies_error
-END
-BEGIN crsproxy.bconnections $1
-SET ok = $crsproxy_connections_nonblocking_established
-SET failed = $crsproxy_connections_nonblocking_failed
-END
-VALUESEOF
-
-       local native_requests="_native_requests"
-       local web_requests="_web_requests"
-       local replies_error="_replies_error"
-       local x=
-
-       echo "BEGIN crsproxy.commands $1"
-       for x in $crsproxy_cmds
-       do
-               eval "v=\$(( crsproxy_cmd_$x$native_requests + crsproxy_cmd_$x$web_requests ))"
-               echo "SET $x = $v"
-       done
-       echo "END"
-
-       echo "BEGIN crsproxy.commands_failed $1"
-       for x in $crsproxy_cmds
-       do
-               eval "v=\$crsproxy_cmd_$x$replies_error"
-               echo "SET $x = $v"
-       done
-       echo "END"
-
-       return 0
-}
index 9272dd3c29c4e58bd50aaa7de8ddaa1e9d4df66f..f96297941f776f073402be76db4a160bf813f951 100644 (file)
 #include "rrd.h"
 #include "plugin_proc.h"
 
-#define RRD_TYPE_STAT                          "cpu"
-#define RRD_TYPE_STAT_LEN                      strlen(RRD_TYPE_STAT)
-
 int do_proc_stat(int update_every, unsigned long long dt) {
+       (void)dt;
+
        static procfile *ff = NULL;
        static int do_cpu = -1, do_cpu_cores = -1, do_interrupts = -1, do_context = -1, do_forks = -1, do_processes = -1;
+       static uint32_t hash_intr, hash_ctxt, hash_processes, hash_procs_running, hash_procs_blocked;
+
+       if(unlikely(do_cpu == -1)) {
+               do_cpu                  = config_get_boolean("plugin:proc:/proc/stat", "cpu utilization", 1);
+               do_cpu_cores    = config_get_boolean("plugin:proc:/proc/stat", "per cpu core utilization", 1);
+               do_interrupts   = config_get_boolean("plugin:proc:/proc/stat", "cpu interrupts", 1);
+               do_context              = config_get_boolean("plugin:proc:/proc/stat", "context switches", 1);
+               do_forks                = config_get_boolean("plugin:proc:/proc/stat", "processes started", 1);
+               do_processes    = config_get_boolean("plugin:proc:/proc/stat", "processes running", 1);
+
+               hash_intr = simple_hash("intr");
+               hash_ctxt = simple_hash("ctxt");
+               hash_processes = simple_hash("processes");
+               hash_procs_running = simple_hash("procs_running");
+               hash_procs_blocked = simple_hash("procs_blocked");
+       }
 
-       if(do_cpu == -1)                do_cpu                  = config_get_boolean("plugin:proc:/proc/stat", "cpu utilization", 1);
-       if(do_cpu_cores == -1)  do_cpu_cores    = config_get_boolean("plugin:proc:/proc/stat", "per cpu core utilization", 1);
-       if(do_interrupts == -1) do_interrupts   = config_get_boolean("plugin:proc:/proc/stat", "cpu interrupts", 1);
-       if(do_context == -1)    do_context              = config_get_boolean("plugin:proc:/proc/stat", "context switches", 1);
-       if(do_forks == -1)              do_forks                = config_get_boolean("plugin:proc:/proc/stat", "processes started", 1);
-       if(do_processes == -1)  do_processes    = config_get_boolean("plugin:proc:/proc/stat", "processes running", 1);
-
-       if(dt) {};
-
-       if(!ff) {
+       if(unlikely(!ff)) {
                char filename[FILENAME_MAX + 1];
                snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/stat");
                ff = procfile_open(config_get("plugin:proc:/proc/stat", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
+               if(unlikely(!ff)) return 1;
        }
-       if(!ff) return 1;
 
        ff = procfile_readall(ff);
-       if(!ff) return 0; // we return 0, so that we will retry to open it next time
+       if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
 
        uint32_t lines = procfile_lines(ff), l;
        uint32_t words;
@@ -45,9 +51,13 @@ int do_proc_stat(int update_every, unsigned long long dt) {
        RRDSET *st;
 
        for(l = 0; l < lines ;l++) {
-               if(strncmp(procfile_lineword(ff, l, 0), "cpu", 3) == 0) {
+               char *row_key = procfile_lineword(ff, l, 0);
+               uint32_t hash = simple_hash(row_key);
+
+               // faster strncmp(row_key, "cpu", 3) == 0
+               if(likely(row_key[0] == 'c' && row_key[1] == 'p' && row_key[2] == 'u')) {
                        words = procfile_linewords(ff, l);
-                       if(words < 9) {
+                       if(unlikely(words < 9)) {
                                error("Cannot read /proc/stat cpu line. Expected 9 params, read %u.", words);
                                continue;
                        }
@@ -55,7 +65,7 @@ int do_proc_stat(int update_every, unsigned long long dt) {
                        char *id;
                        unsigned long long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0, steal = 0, guest = 0, guest_nice = 0;
 
-                       id                      = procfile_lineword(ff, l, 0);
+                       id                      = row_key;
                        user            = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
                        nice            = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
                        system          = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
@@ -67,25 +77,30 @@ int do_proc_stat(int update_every, unsigned long long dt) {
                        if(words >= 10) guest           = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
                        if(words >= 11) guest_nice      = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
 
-                       char *title = "Core utilization";
-                       char *type = RRD_TYPE_STAT;
-                       char *context = "cpu.cpu";
-                       char *family = "utilization";
-                       long priority = 1000;
-                       int isthistotal = 0;
+                       char *title, *type, *context, *family;
+                       long priority;
+                       int isthistotal;
 
-                       if(strcmp(id, "cpu") == 0) {
-                               isthistotal = 1;
-                               type = "system";
+                       if(unlikely(strcmp(id, "cpu")) == 0) {
                                title = "Total CPU utilization";
+                               type = "system";
                                context = "system.cpu";
                                family = id;
                                priority = 100;
+                               isthistotal = 1;
+                       }
+                       else {
+                               title = "Core utilization";
+                               type = "cpu";
+                               context = "cpu.cpu";
+                               family = "utilization";
+                               priority = 1000;
+                               isthistotal = 0;
                        }
 
-                       if((isthistotal && do_cpu) || (!isthistotal && do_cpu_cores)) {
+                       if(likely((isthistotal && do_cpu) || (!isthistotal && do_cpu_cores))) {
                                st = rrdset_find_bytype(type, id);
-                               if(!st) {
+                               if(unlikely(!st)) {
                                        st = rrdset_create(type, id, NULL, family, context, title, "percentage", priority, update_every, RRDSET_TYPE_STACKED);
 
                                        long multiplier = 1;
@@ -119,14 +134,14 @@ int do_proc_stat(int update_every, unsigned long long dt) {
                                rrdset_done(st);
                        }
                }
-               else if(strcmp(procfile_lineword(ff, l, 0), "intr") == 0) {
+               else if(hash == hash_intr && strcmp(row_key, "intr") == 0) {
                        unsigned long long value = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
 
                        // --------------------------------------------------------------------
 
-                       if(do_interrupts) {
+                       if(likely(do_interrupts)) {
                                st = rrdset_find_bytype("system", "intr");
-                               if(!st) {
+                               if(unlikely(!st)) {
                                        st = rrdset_create("system", "intr", NULL, "interrupts", NULL, "CPU Interrupts", "interrupts/s", 900, update_every, RRDSET_TYPE_LINE);
                                        st->isdetail = 1;
 
@@ -138,14 +153,14 @@ int do_proc_stat(int update_every, unsigned long long dt) {
                                rrdset_done(st);
                        }
                }
-               else if(strcmp(procfile_lineword(ff, l, 0), "ctxt") == 0) {
+               else if(hash == hash_ctxt && strcmp(row_key, "ctxt") == 0) {
                        unsigned long long value = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
 
                        // --------------------------------------------------------------------
 
-                       if(do_context) {
+                       if(likely(do_context)) {
                                st = rrdset_find_bytype("system", "ctxt");
-                               if(!st) {
+                               if(unlikely(!st)) {
                                        st = rrdset_create("system", "ctxt", NULL, "processes", NULL, "CPU Context Switches", "context switches/s", 800, update_every, RRDSET_TYPE_LINE);
 
                                        rrddim_add(st, "switches", NULL, 1, 1, RRDDIM_INCREMENTAL);
@@ -156,22 +171,22 @@ int do_proc_stat(int update_every, unsigned long long dt) {
                                rrdset_done(st);
                        }
                }
-               else if(!processes && strcmp(procfile_lineword(ff, l, 0), "processes") == 0) {
+               else if(hash == hash_processes && !processes && strcmp(row_key, "processes") == 0) {
                        processes = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
                }
-               else if(!running && strcmp(procfile_lineword(ff, l, 0), "procs_running") == 0) {
+               else if(hash == hash_procs_running && !running && strcmp(row_key, "procs_running") == 0) {
                        running = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
                }
-               else if(!blocked && strcmp(procfile_lineword(ff, l, 0), "procs_blocked") == 0) {
+               else if(hash == hash_procs_blocked && !blocked && strcmp(row_key, "procs_blocked") == 0) {
                        blocked = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
                }
        }
 
        // --------------------------------------------------------------------
 
-       if(do_forks) {
+       if(likely(do_forks)) {
                st = rrdset_find_bytype("system", "forks");
-               if(!st) {
+               if(unlikely(!st)) {
                        st = rrdset_create("system", "forks", NULL, "processes", NULL, "Started Processes", "processes/s", 700, update_every, RRDSET_TYPE_LINE);
                        st->isdetail = 1;
 
@@ -185,9 +200,9 @@ int do_proc_stat(int update_every, unsigned long long dt) {
 
        // --------------------------------------------------------------------
 
-       if(do_processes) {
+       if(likely(do_processes)) {
                st = rrdset_find_bytype("system", "processes");
-               if(!st) {
+               if(unlikely(!st)) {
                        st = rrdset_create("system", "processes", NULL, "processes", NULL, "System Processes", "processes", 600, update_every, RRDSET_TYPE_LINE);
 
                        rrddim_add(st, "running", NULL, 1, 1, RRDDIM_ABSOLUTE);
index c0f4f363353436b8a50bd915ffee39cd8d4eb2a1..208d741c9a4d7a11b460a811b01a4c3c77d5ac43 100644 (file)
--- a/src/rrd.c
+++ b/src/rrd.c
@@ -920,7 +920,7 @@ unsigned long long rrdset_done(RRDSET *st)
        int dimensions;
        st->collected_total = 0;
        for( rd = st->dimensions, dimensions = 0 ; likely(rd) ; rd = rd->next, dimensions++ )
-               st->collected_total += rd->collected_value;
+               if(likely(rd->updated)) st->collected_total += rd->collected_value;
 
        uint32_t storage_flags = SN_EXISTS;
 
@@ -929,6 +929,11 @@ unsigned long long rrdset_done(RRDSET *st)
        // at this stage we do not interpolate anything
        for( rd = st->dimensions ; likely(rd) ; rd = rd->next ) {
 
+               if(unlikely(!rd->updated)) {
+                       rd->calculated_value = 0;
+                       continue;
+               }
+
                if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: START "
                        " last_collected_value = " COLLECTED_NUMBER_FORMAT
                        " collected_value = " COLLECTED_NUMBER_FORMAT
@@ -942,34 +947,35 @@ unsigned long long rrdset_done(RRDSET *st)
                        );
 
                switch(rd->algorithm) {
-               case RRDDIM_ABSOLUTE:
-                       rd->calculated_value = (calculated_number)rd->collected_value
-                               * (calculated_number)rd->multiplier
-                               / (calculated_number)rd->divisor;
-
-                       if(unlikely(st->debug))
-                               debug(D_RRD_STATS, "%s/%s: CALC ABS/ABS-NO-IN "
-                                       CALCULATED_NUMBER_FORMAT " = "
-                                       COLLECTED_NUMBER_FORMAT
-                                       " * " CALCULATED_NUMBER_FORMAT
-                                       " / " CALCULATED_NUMBER_FORMAT
-                                       , st->id, rd->name
-                                       , rd->calculated_value
-                                       , rd->collected_value
-                                       , (calculated_number)rd->multiplier
-                                       , (calculated_number)rd->divisor
-                                       );
-                       break;
+                       case RRDDIM_ABSOLUTE:
+                               rd->calculated_value = (calculated_number)rd->collected_value
+                                       * (calculated_number)rd->multiplier
+                                       / (calculated_number)rd->divisor;
+
+                               if(unlikely(st->debug))
+                                       debug(D_RRD_STATS, "%s/%s: CALC ABS/ABS-NO-IN "
+                                               CALCULATED_NUMBER_FORMAT " = "
+                                               COLLECTED_NUMBER_FORMAT
+                                               " * " CALCULATED_NUMBER_FORMAT
+                                               " / " CALCULATED_NUMBER_FORMAT
+                                               , st->id, rd->name
+                                               , rd->calculated_value
+                                               , rd->collected_value
+                                               , (calculated_number)rd->multiplier
+                                               , (calculated_number)rd->divisor
+                                               );
+                               break;
 
                        case RRDDIM_PCENT_OVER_ROW_TOTAL:
-                               if(unlikely(!st->collected_total)) rd->calculated_value = 0;
+                               if(unlikely(!st->collected_total))
+                                       rd->calculated_value = 0;
                                else
-                               // the percentage of the current value
-                               // over the total of all dimensions
-                               rd->calculated_value =
-                                         (calculated_number)100
-                                       * (calculated_number)rd->collected_value
-                                       / (calculated_number)st->collected_total;
+                                       // the percentage of the current value
+                                       // over the total of all dimensions
+                                       rd->calculated_value =
+                                             (calculated_number)100
+                                           * (calculated_number)rd->collected_value
+                                           / (calculated_number)st->collected_total;
 
                                if(unlikely(st->debug))
                                        debug(D_RRD_STATS, "%s/%s: CALC PCENT-ROW "
@@ -984,7 +990,7 @@ unsigned long long rrdset_done(RRDSET *st)
                                break;
 
                        case RRDDIM_INCREMENTAL:
-                               if(unlikely(!rd->updated || rd->counter <= 1)) {
+                               if(unlikely(rd->counter <= 1)) {
                                        rd->calculated_value = 0;
                                        continue;
                                }
@@ -1000,9 +1006,10 @@ unsigned long long rrdset_done(RRDSET *st)
                                        rd->last_collected_value = rd->collected_value;
                                }
 
-                               rd->calculated_value = (calculated_number)(rd->collected_value - rd->last_collected_value)
-                                       * (calculated_number)rd->multiplier
-                                       / (calculated_number)rd->divisor;
+                               rd->calculated_value =
+                                     (calculated_number)(rd->collected_value - rd->last_collected_value)
+                                   * (calculated_number)rd->multiplier
+                                   / (calculated_number)rd->divisor;
 
                                if(unlikely(st->debug))
                                        debug(D_RRD_STATS, "%s/%s: CALC INC PRE "
@@ -1020,18 +1027,20 @@ unsigned long long rrdset_done(RRDSET *st)
                                break;
 
                        case RRDDIM_PCENT_OVER_DIFF_TOTAL:
-                               if(unlikely(!rd->updated || rd->counter <= 1)) {
+                               if(unlikely(rd->counter <= 1)) {
                                        rd->calculated_value = 0;
                                        continue;
                                }
 
                                // the percentage of the current increment
                                // over the increment of all dimensions together
-                               if(unlikely(st->collected_total == st->last_collected_total)) rd->calculated_value = rd->last_calculated_value;
-                               else rd->calculated_value =
-                                         (calculated_number)100
-                                       * (calculated_number)(rd->collected_value - rd->last_collected_value)
-                                       / (calculated_number)(st->collected_total  - st->last_collected_total);
+                               if(unlikely(st->collected_total == st->last_collected_total))
+                                       rd->calculated_value = 0;
+                               else
+                                       rd->calculated_value =
+                                                 (calculated_number)100
+                                               * (calculated_number)(rd->collected_value - rd->last_collected_value)
+                                               / (calculated_number)(st->collected_total - st->last_collected_total);
 
                                if(unlikely(st->debug))
                                        debug(D_RRD_STATS, "%s/%s: CALC PCENT-DIFF "