@cryptotaxi247 / netdata-1 / commits / bf0a2ce90

new storage on a custom 29 bit signed number similar to float, having a detail of 7 decimal points and a max value of 1 trillion with a accuracy of 1/1000000 of the number stored. 3 bits are reserved for flags (not used currently).

Costa Tsaousis (ktsaou) committed May 31, 2014 at 05:15 UTC bf0a2ce9097485e1d970647a5165845a69d56153
3 files changed +201 -158
apps_plugin.c
+9 -9
@@ -1496,14 +1496,14 @@ void show_charts(void)
1496 for (w = target_root; w ; w = w->next) {
1497 if(w->target || (!w->processes && !w->exposed)) continue;
1498
1499 - fprintf(stdout, "DIMENSION %s '' absolute-no-interpolation 1 1\n", w->name);
1499 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
1500 }
1501
1502 fprintf(stdout, "CHART apps.processes '' 'Apps Processes' 'processes' apps apps stacked 20004 %d\n", update_every);
1503 for (w = target_root; w ; w = w->next) {
1504 if(w->target || (!w->processes && !w->exposed)) continue;
1505
1506 - fprintf(stdout, "DIMENSION %s '' absolute-no-interpolation 1 1\n", w->name);
1506 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
1507 }
1508
1509 fprintf(stdout, "CHART apps.cpu_user '' 'Apps CPU User Time (%ld%% = %ld core%s)' 'cpu time %%' apps none stacked 20020 %d\n", (processors * 100), processors, (processors>1)?"s":"", update_every);
@@ -1566,21 +1566,21 @@ void show_charts(void)
1566 for (w = target_root; w ; w = w->next) {
1567 if(w->target || (!w->processes && !w->exposed)) continue;
1568
1569 - fprintf(stdout, "DIMENSION %s '' absolute-no-interpolation 1 1\n", w->name);
1569 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
1570 }
1571
1572 fprintf(stdout, "CHART apps.sockets '' 'Apps Open Sockets' 'open sockets' apps apps stacked 20051 %d\n", update_every);
1573 for (w = target_root; w ; w = w->next) {
1574 if(w->target || (!w->processes && !w->exposed)) continue;
1575
1576 - fprintf(stdout, "DIMENSION %s '' absolute-no-interpolation 1 1\n", w->name);
1576 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
1577 }
1578
1579 fprintf(stdout, "CHART apps.pipes '' 'Apps Pipes' 'open pipes' apps none stacked 20053 %d\n", update_every);
1580 for (w = target_root; w ; w = w->next) {
1581 if(w->target || (!w->processes && !w->exposed)) continue;
1582
1583 - fprintf(stdout, "DIMENSION %s '' absolute-no-interpolation 1 1\n", w->name);
1583 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
1584 }
1585
1586 fprintf(stdout, "CHART netdata.apps_cpu '' 'Apps Plugin CPU' 'milliseconds/s' netdata netdata stacked 10000 %d\n", update_every);
@@ -1588,10 +1588,10 @@ void show_charts(void)
1588 fprintf(stdout, "DIMENSION system '' incremental 1 1000\n");
1589
1590 fprintf(stdout, "CHART netdata.apps_files '' 'Apps Plugin Files' 'files/s' netdata netdata line 10001 %d\n", update_every);
1591 - fprintf(stdout, "DIMENSION files '' incremental-no-interpolation 1 1\n");
1592 - fprintf(stdout, "DIMENSION pids '' absolute-no-interpolation 1 1\n");
1593 - fprintf(stdout, "DIMENSION fds '' absolute-no-interpolation 1 1\n");
1594 - fprintf(stdout, "DIMENSION targets '' absolute-no-interpolation 1 1\n");
1591 + fprintf(stdout, "DIMENSION files '' incremental 1 1\n");
1592 + fprintf(stdout, "DIMENSION pids '' absolute 1 1\n");
1593 + fprintf(stdout, "DIMENSION fds '' absolute 1 1\n");
1594 + fprintf(stdout, "DIMENSION targets '' absolute 1 1\n");
1595
1596 fflush(stdout);
1597 }
netdata.c
+190 -143
@@ -327,6 +327,8 @@ void log_access( const char *fmt, ... )
327 // ----------------------------------------------------------------------------
328 // helpers
329
330 +#define abs(x) ((x < 0)? -x : x)
331 +
332 unsigned long long usecdiff(struct timeval *now, struct timeval *last) {
333 return ((((now->tv_sec * 1000000ULL) + now->tv_usec) - ((last->tv_sec * 1000000ULL) + last->tv_usec)));
334 }
@@ -886,23 +888,16 @@ const char *chart_type_name(int chart_type)
888 #define RRD_DIMENSION_INCREMENTAL_NAME "incremental"
889 #define RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL_NAME "percentage-of-incremental-row"
890 #define RRD_DIMENSION_PCENT_OVER_ROW_TOTAL_NAME "percentage-of-absolute-row"
889 -#define RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION_NAME "incremental-no-interpolation"
890 -#define RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION_NAME "absolute-no-interpolation"
891 -
891
892 #define RRD_DIMENSION_ABSOLUTE 0
893 #define RRD_DIMENSION_INCREMENTAL 1
894 #define RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL 2
895 #define RRD_DIMENSION_PCENT_OVER_ROW_TOTAL 3
897 -#define RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION 4
898 -#define RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION 5
896
897 int algorithm_id(const char *name)
898 {
899 if(strcmp(name, RRD_DIMENSION_ABSOLUTE_NAME) == 0) return RRD_DIMENSION_ABSOLUTE;
903 - if(strcmp(name, RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION_NAME) == 0) return RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION;
900 if(strcmp(name, RRD_DIMENSION_INCREMENTAL_NAME) == 0) return RRD_DIMENSION_INCREMENTAL;
905 - if(strcmp(name, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION_NAME) == 0) return RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION;
901 if(strcmp(name, RRD_DIMENSION_PCENT_OVER_ROW_TOTAL_NAME) == 0) return RRD_DIMENSION_PCENT_OVER_ROW_TOTAL;
902 if(strcmp(name, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL_NAME) == 0) return RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL;
903 return RRD_DIMENSION_ABSOLUTE;
@@ -914,22 +909,14 @@ const char *algorithm_name(int chart_type)
909 static char incremental[] = RRD_DIMENSION_INCREMENTAL_NAME;
910 static char percentage_of_absolute_row[] = RRD_DIMENSION_PCENT_OVER_ROW_TOTAL_NAME;
911 static char percentage_of_incremental_row[] = RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL_NAME;
917 - static char incremental_last_value[] = RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION_NAME;
918 - static char absolute_last_value[] = RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION_NAME;
912
913 switch(chart_type) {
914 case RRD_DIMENSION_ABSOLUTE:
915 return absolute;
916
924 - case RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION:
925 - return absolute_last_value;
926 -
917 case RRD_DIMENSION_INCREMENTAL:
918 return incremental;
919
930 - case RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION:
931 - return incremental_last_value;
932 -
920 case RRD_DIMENSION_PCENT_OVER_ROW_TOTAL:
921 return percentage_of_absolute_row;
922
@@ -1069,7 +1056,7 @@ int savememory(const char *filename, void *mem, unsigned long size)
1056 #define RRD_STATS_NAME_MAX 1024
1057
1058 typedef long double calculated_number;
1072 -#define CALCULATED_NUMBER_FORMAT "%0.3Lf"
1059 +#define CALCULATED_NUMBER_FORMAT "%0.7Lf"
1060 //typedef long long calculated_number;
1061 //#define CALCULATED_NUMBER_FORMAT "%lld"
1062
@@ -1083,8 +1070,91 @@ typedef int32_t storage_number;
1070 typedef uint32_t ustorage_number;
1071 #define STORAGE_NUMBER_FORMAT "%d"
1072
1086 -#define RRD_STATS_MAGIC "NETDATA CACHE STATS FILE V007"
1087 -#define RRD_DIMENSION_MAGIC "NETDATA CACHE DIMENSION FILE V005"
1073 +storage_number pack_storage_number(calculated_number value)
1074 +{
1075 + storage_number r = 0;
1076 + if(!value) return r;
1077 +
1078 + // bit 32 = sign
1079 + // bit 31 = 0:divide, 1:multiply
1080 + // bit 30, 29, 28 = (multiplier or divider) 0-7
1081 + // bit 27 to 25 = reserved for flags
1082 + // bit 24 to bit 1 = the value
1083 +
1084 + storage_number sign = 0, exp = 0, mul;
1085 + int m = 0;
1086 + calculated_number n = value;
1087 +
1088 + if(n < 0) {
1089 + sign = 1;
1090 + n = -n;
1091 + }
1092 +
1093 + while(m < 7 && n > (calculated_number)0x00ffffff) {
1094 + n /= 10;
1095 + m++;
1096 + }
1097 + while(m > -7 && n < (calculated_number)0x00199999) {
1098 + n *= 10;
1099 + m--;
1100 + }
1101 +
1102 + if(m <= 0) {
1103 + exp = 0;
1104 + m = -m;
1105 + }
1106 + else exp = 1;
1107 +
1108 + if(n > (calculated_number)0x00ffffff) {
1109 + error("Number " CALCULATED_NUMBER_FORMAT " is too big.", value);
1110 + n = (calculated_number)0x00ffffff;
1111 + }
1112 +
1113 + mul = m;
1114 +
1115 + r = (sign << 31) + (exp << 30) + (mul << 27) + n;
1116 + // fprintf(stderr, "PACK: %08X, sign = %d, exp = %d, mul = %d, n = " CALCULATED_NUMBER_FORMAT "\n", r, sign, exp, mul, n);
1117 +
1118 + return r;
1119 +}
1120 +
1121 +calculated_number unpack_storage_number(storage_number value)
1122 +{
1123 + if(!value) return 0;
1124 +
1125 + int sign = 0;
1126 + int exp = 0;
1127 +
1128 + if(value & (1 << 31)) {
1129 + sign = 1;
1130 + value ^= 1 << 31;
1131 + }
1132 +
1133 + if(value & (1 << 30)) {
1134 + exp = 1;
1135 + value ^= 1 << 30;
1136 + }
1137 +
1138 + int mul = value >> 27;
1139 + value ^= mul << 27;
1140 +
1141 + calculated_number n = value;
1142 +
1143 + // fprintf(stderr, "UNPACK: %08X, sign = %d, exp = %d, mul = %d, n = " CALCULATED_NUMBER_FORMAT "\n", value, sign, exp, mul, n);
1144 +
1145 + while(mul > 0) {
1146 + if(exp) n *= 10;
1147 + else n /= 10;
1148 + mul--;
1149 + }
1150 +
1151 + if(sign) n = -n;
1152 + return n;
1153 +}
1154 +
1155 +
1156 +#define RRD_STATS_MAGIC "NETDATA CACHE STATS FILE V008"
1157 +#define RRD_DIMENSION_MAGIC "NETDATA CACHE DIMENSION FILE V008"
1158
1159 struct rrd_dimension {
1160 char magic[sizeof(RRD_DIMENSION_MAGIC) + 1];// our magic
@@ -1756,25 +1826,7 @@ unsigned long long rrd_stats_done(RRD_STATS *st)
1826 );
1827 break;
1828
1759 - case RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION:
1760 - // if the new is smaller than the old (an overflow, or reset), set the old equal to the new
1761 - // to reset the calculation (it will give zero as the calculation for this second)
1762 - if(rd->last_collected_value > rd->collected_value) rd->last_collected_value = rd->collected_value;
1763 -
1764 - rd->calculated_value = (calculated_number)(rd->collected_value - rd->last_collected_value);
1765 -
1766 - if(st->debug)
1767 - debug(D_RRD_STATS, "%s/%s: CALC INC-NO-IN "
1768 - CALCULATED_NUMBER_FORMAT " = "
1769 - COLLECTED_NUMBER_FORMAT " - " COLLECTED_NUMBER_FORMAT
1770 - , st->id, rd->name
1771 - , rd->calculated_value
1772 - , rd->collected_value, rd->last_collected_value
1773 - );
1774 - break;
1775 -
1829 case RRD_DIMENSION_ABSOLUTE:
1777 - case RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION:
1830 rd->calculated_value = (calculated_number)rd->collected_value;
1831
1832 if(st->debug)
@@ -1844,41 +1896,6 @@ unsigned long long rrd_stats_done(RRD_STATS *st)
1896 calculated_number new_value;
1897
1898 switch(rd->algorithm) {
1847 - case RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION:
1848 - if(next_ut + st->update_every * 1000000ULL < now_ut)
1849 - new_value = rd->last_calculated_value;
1850 - else
1851 - new_value = rd->calculated_value;
1852 -
1853 - if(st->debug)
1854 - debug(D_RRD_STATS, "%s/%s: CALC2 ABS-NO-IN "
1855 - CALCULATED_NUMBER_FORMAT
1856 - , st->id, rd->name
1857 - , new_value
1858 - );
1859 -
1860 - if(next_ut + st->update_every * 1000000ULL > now_ut) rd->calculated_value = new_value;
1861 - break;
1862 -
1863 - case RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION:
1864 - new_value = rd->calculated_value
1865 - * (calculated_number)(st->update_every * 1000000)
1866 - / (calculated_number)st->usec_since_last_update;
1867 -
1868 - if(st->debug)
1869 - debug(D_RRD_STATS, "%s/%s: CALC2 INC-NO-IN "
1870 - CALCULATED_NUMBER_FORMAT " = "
1871 - CALCULATED_NUMBER_FORMAT " * "
1872 - "%llu / %llu"
1873 - , st->id, rd->name
1874 - , new_value
1875 - , rd->calculated_value
1876 - , (unsigned long long)(st->update_every * 1000000)
1877 - , (unsigned long long)st->usec_since_last_update
1878 - );
1879 -
1880 - break;
1881 -
1899 case RRD_DIMENSION_INCREMENTAL:
1900 new_value = (calculated_number)
1901 ( rd->calculated_value
@@ -1932,22 +1949,21 @@ unsigned long long rrd_stats_done(RRD_STATS *st)
1949
1950 }
1951
1935 - rd->values[st->current_entry] = (storage_number)
1936 - ( new_value
1937 - * (calculated_number)10
1952 +
1953 + rd->values[st->current_entry] = pack_storage_number(
1954 + new_value
1955 * (calculated_number)rd->multiplier
1956 / (calculated_number)rd->divisor
1957 );
1958
1959 if(st->debug)
1960 debug(D_RRD_STATS, "%s/%s: STORE[%ld] "
1944 - STORAGE_NUMBER_FORMAT " = " CALCULATED_NUMBER_FORMAT
1945 - " * 10 "
1961 + CALCULATED_NUMBER_FORMAT " = " CALCULATED_NUMBER_FORMAT
1962 " * %ld"
1963 " / %ld"
1964 , st->id, rd->name
1965 , st->current_entry
1950 - , rd->values[st->current_entry], new_value
1966 + , unpack_storage_number(rd->values[st->current_entry]), new_value
1967 , rd->multiplier
1968 , rd->divisor
1969 );
@@ -2051,21 +2067,18 @@ void web_buffer_strcpy(struct web_buffer *wb, const char *txt)
2067 wb->bytes = bytes;
2068 }
2069
2054 -void web_buffer_rrd_value(struct web_buffer *wb, storage_number value)
2070 +int print_calculated_number(char *str, calculated_number value)
2071 {
2056 - if(wb->size - wb->bytes < 11) return;
2057 -
2058 - char *str = &wb->buffer[wb->bytes];
2072 char *wstr = str;
2073
2074 // make sure it is unsigned
2062 - ustorage_number uvalue = (value < 0) ? -value : value;
2075 + unsigned long long uvalue = (unsigned long long)(((value < 0) ? -value : value) * (calculated_number)10000);
2076
2077 // print each digit
2078 do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
2079
2067 - // if it is just one byte, add a zero
2068 - if((wstr - str) == 1) *wstr++ = '0';
2080 + // make sure we have 8 bytes at least
2081 + while((wstr - str) < 5) *wstr++ = '0';
2082
2083 // put the sign back
2084 if (value < 0) *wstr++ = '-';
@@ -2074,20 +2087,25 @@ void web_buffer_rrd_value(struct web_buffer *wb, storage_number value)
2087 wstr--;
2088 strreverse(str, wstr);
2089
2077 - if(*wstr != '0') {
2078 - // move the last digit one byte to the right
2079 - wstr[1] = wstr[0];
2080 -
2081 - // put the dot in the hole
2082 - wstr[0] = '.';
2090 + // terminate it, one position to the right
2091 + // to let space for a dot
2092 + wstr[2] = '\0';
2093
2084 - // terminate it
2085 - wstr += 2;
2094 + int i;
2095 + for(i = 0; i < 4 ;i++) {
2096 + wstr[1] = wstr[0];
2097 + wstr--;
2098 }
2087 - *wstr='\0';
2099 + wstr[1] = '.';
2100
2089 - // update the buffer length
2090 - wb->bytes += (wstr - str);
2101 + // return the buffer length
2102 + return ( (wstr - str) + 6 );
2103 +}
2104 +
2105 +void web_buffer_rrd_value(struct web_buffer *wb, calculated_number value)
2106 +{
2107 + if(wb->size - wb->bytes < 50) return;
2108 + wb->bytes += print_calculated_number(&wb->buffer[wb->bytes], value);
2109 }
2110
2111 // generate a javascript date, the fastest possible way...
@@ -2302,6 +2320,7 @@ struct web_client *web_client_free(struct web_client *w)
2320
2321 #define GROUP_AVERAGE 0
2322 #define GROUP_MAX 1
2323 +#define GROUP_SUM 2
2324
2325 // find the oldest entry in the data, skipping all empty slots
2326 time_t rrd_stats_first_entry_t(RRD_STATS *st)
@@ -2563,7 +2582,7 @@ unsigned long rrd_stats_json(int type, RRD_STATS *st, struct web_buffer *wb, int
2582 // temp arrays for keeping values per dimension
2583
2584 calculated_number group_values[dimensions]; // keep sums when grouping
2566 - storage_number print_values[dimensions]; // keep the final value to be printed
2585 + calculated_number print_values[dimensions]; // keep the final value to be printed
2586 int print_hidden[dimensions]; // keep hidden flags
2587 int found_non_zero[dimensions];
2588
@@ -2682,13 +2701,17 @@ unsigned long rrd_stats_json(int type, RRD_STATS *st, struct web_buffer *wb, int
2701 }
2702
2703 for(rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
2685 - long value = rd->values[t];
2704 + calculated_number value = unpack_storage_number(rd->values[t]);
2705
2706 switch(group_method) {
2707 case GROUP_MAX:
2708 if(abs(value) > abs(group_values[c])) group_values[c] = value;
2709 break;
2710
2711 + case GROUP_SUM:
2712 + group_values[c] += value;
2713 + break;
2714 +
2715 default:
2716 case GROUP_AVERAGE:
2717 group_values[c] += value;
@@ -2726,7 +2749,7 @@ unsigned long rrd_stats_json(int type, RRD_STATS *st, struct web_buffer *wb, int
2749 }
2750 if(!pc) {
2751 web_buffer_strcpy(wb, pre_value);
2729 - web_buffer_rrd_value(wb, (storage_number)0);
2752 + web_buffer_rrd_value(wb, (calculated_number)0);
2753 web_buffer_strcpy(wb, post_value);
2754 }
2755
@@ -3072,6 +3095,7 @@ int web_client_data_request(struct web_client *w, char *url, int datasource_type
3095 tok = mystrsep(&url, "/");
3096 if(strcmp(tok, "max") == 0) group_method = GROUP_MAX;
3097 else if(strcmp(tok, "average") == 0) group_method = GROUP_AVERAGE;
3098 + else if(strcmp(tok, "sum") == 0) group_method = GROUP_SUM;
3099 else debug(D_WEB_CLIENT, "%llu: Unknown group method '%s'", w->id, tok);
3100 }
3101 if(url) {
@@ -5020,7 +5044,7 @@ int do_proc_net_stat_conntrack() {
5044 if(!st) {
5045 st = rrd_stats_create(RRD_TYPE_NET_STAT_CONNTRACK, "sockets", NULL, RRD_TYPE_NET_STAT_CONNTRACK, "Netfilter Connections", "active connections", 1000, update_every, CHART_TYPE_LINE);
5046
5023 - rrd_stats_dimension_add(st, "connections", NULL, 1, 1, RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION);
5047 + rrd_stats_dimension_add(st, "connections", NULL, 1, 1, RRD_DIMENSION_ABSOLUTE);
5048 }
5049 else rrd_stats_next(st);
5050
@@ -5035,9 +5059,9 @@ int do_proc_net_stat_conntrack() {
5059 if(!st) {
5060 st = rrd_stats_create(RRD_TYPE_NET_STAT_CONNTRACK, "new", NULL, RRD_TYPE_NET_STAT_CONNTRACK, "Netfilter New Connections", "connections/s", 1001, update_every, CHART_TYPE_LINE);
5061
5038 - rrd_stats_dimension_add(st, "new", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5039 - rrd_stats_dimension_add(st, "ignore", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5040 - rrd_stats_dimension_add(st, "invalid", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5062 + rrd_stats_dimension_add(st, "new", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5063 + rrd_stats_dimension_add(st, "ignore", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5064 + rrd_stats_dimension_add(st, "invalid", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5065 }
5066 else rrd_stats_next(st);
5067
@@ -5055,9 +5079,9 @@ int do_proc_net_stat_conntrack() {
5079 st = rrd_stats_create(RRD_TYPE_NET_STAT_CONNTRACK, "changes", NULL, RRD_TYPE_NET_STAT_CONNTRACK, "Netfilter Connection Changes", "changes/s", 1002, update_every, CHART_TYPE_LINE);
5080 st->isdetail = 1;
5081
5058 - rrd_stats_dimension_add(st, "inserted", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5059 - rrd_stats_dimension_add(st, "deleted", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5060 - rrd_stats_dimension_add(st, "delete_list", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5082 + rrd_stats_dimension_add(st, "inserted", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5083 + rrd_stats_dimension_add(st, "deleted", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5084 + rrd_stats_dimension_add(st, "delete_list", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5085 }
5086 else rrd_stats_next(st);
5087
@@ -5075,9 +5099,9 @@ int do_proc_net_stat_conntrack() {
5099 st = rrd_stats_create(RRD_TYPE_NET_STAT_CONNTRACK, "expect", NULL, RRD_TYPE_NET_STAT_CONNTRACK, "Netfilter Connection Expectations", "expectations/s", 1003, update_every, CHART_TYPE_LINE);
5100 st->isdetail = 1;
5101
5078 - rrd_stats_dimension_add(st, "created", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5079 - rrd_stats_dimension_add(st, "deleted", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5080 - rrd_stats_dimension_add(st, "new", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5102 + rrd_stats_dimension_add(st, "created", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5103 + rrd_stats_dimension_add(st, "deleted", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5104 + rrd_stats_dimension_add(st, "new", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5105 }
5106 else rrd_stats_next(st);
5107
@@ -5095,9 +5119,9 @@ int do_proc_net_stat_conntrack() {
5119 st = rrd_stats_create(RRD_TYPE_NET_STAT_CONNTRACK, "search", NULL, RRD_TYPE_NET_STAT_CONNTRACK, "Netfilter Connection Searches", "searches/s", 1010, update_every, CHART_TYPE_LINE);
5120 st->isdetail = 1;
5121
5098 - rrd_stats_dimension_add(st, "searched", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5099 - rrd_stats_dimension_add(st, "restarted", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5100 - rrd_stats_dimension_add(st, "found", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5122 + rrd_stats_dimension_add(st, "searched", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5123 + rrd_stats_dimension_add(st, "restarted", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5124 + rrd_stats_dimension_add(st, "found", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5125 }
5126 else rrd_stats_next(st);
5127
@@ -5115,10 +5139,10 @@ int do_proc_net_stat_conntrack() {
5139 st = rrd_stats_create(RRD_TYPE_NET_STAT_CONNTRACK, "errors", NULL, RRD_TYPE_NET_STAT_CONNTRACK, "Netfilter Errors", "events/s", 1005, update_every, CHART_TYPE_LINE);
5140 st->isdetail = 1;
5141
5118 - rrd_stats_dimension_add(st, "icmp_error", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5119 - rrd_stats_dimension_add(st, "insert_failed", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5120 - rrd_stats_dimension_add(st, "drop", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5121 - rrd_stats_dimension_add(st, "early_drop", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5142 + rrd_stats_dimension_add(st, "icmp_error", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5143 + rrd_stats_dimension_add(st, "insert_failed", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5144 + rrd_stats_dimension_add(st, "drop", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5145 + rrd_stats_dimension_add(st, "early_drop", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5146 }
5147 else rrd_stats_next(st);
5148
@@ -5190,7 +5214,7 @@ int do_proc_net_ip_vs_stats() {
5214 if(!st) {
5215 st = rrd_stats_create(RRD_TYPE_NET_IPVS, "sockets", NULL, RRD_TYPE_NET_IPVS, "IPVS New Connections", "connections/s", 1001, update_every, CHART_TYPE_LINE);
5216
5193 - rrd_stats_dimension_add(st, "connections", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5217 + rrd_stats_dimension_add(st, "connections", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5218 }
5219 else rrd_stats_next(st);
5220
@@ -5205,8 +5229,8 @@ int do_proc_net_ip_vs_stats() {
5229 if(!st) {
5230 st = rrd_stats_create(RRD_TYPE_NET_IPVS, "packets", NULL, RRD_TYPE_NET_IPVS, "IPVS Packets", "packets/s", 1002, update_every, CHART_TYPE_LINE);
5231
5208 - rrd_stats_dimension_add(st, "received", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5209 - rrd_stats_dimension_add(st, "sent", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5232 + rrd_stats_dimension_add(st, "received", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5233 + rrd_stats_dimension_add(st, "sent", NULL, -1, 1, RRD_DIMENSION_INCREMENTAL);
5234 }
5235 else rrd_stats_next(st);
5236
@@ -5334,7 +5358,7 @@ int do_proc_stat() {
5358 st = rrd_stats_create("system", id, NULL, "cpu", "CPU Interrupts", "interrupts/s", 900, update_every, CHART_TYPE_LINE);
5359 st->isdetail = 1;
5360
5337 - rrd_stats_dimension_add(st, "interrupts", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5361 + rrd_stats_dimension_add(st, "interrupts", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5362 }
5363 else rrd_stats_next(st);
5364
@@ -5358,7 +5382,7 @@ int do_proc_stat() {
5382 if(!st) {
5383 st = rrd_stats_create("system", id, NULL, "cpu", "CPU Context Switches", "context switches/s", 800, update_every, CHART_TYPE_LINE);
5384
5361 - rrd_stats_dimension_add(st, "switches", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5385 + rrd_stats_dimension_add(st, "switches", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5386 }
5387 else rrd_stats_next(st);
5388
@@ -5410,7 +5434,7 @@ int do_proc_stat() {
5434 st = rrd_stats_create("system", "forks", NULL, "cpu", "New Processes", "processes/s", 700, update_every, CHART_TYPE_LINE);
5435 st->isdetail = 1;
5436
5413 - rrd_stats_dimension_add(st, "started", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
5437 + rrd_stats_dimension_add(st, "started", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
5438 }
5439 else rrd_stats_next(st);
5440
@@ -5425,8 +5449,8 @@ int do_proc_stat() {
5449 if(!st) {
5450 st = rrd_stats_create("system", "processes", NULL, "cpu", "Processes", "processes", 600, update_every, CHART_TYPE_LINE);
5451
5428 - rrd_stats_dimension_add(st, "running", NULL, 1, 1, RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION);
5429 - rrd_stats_dimension_add(st, "blocked", NULL, -1, 1, RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION);
5452 + rrd_stats_dimension_add(st, "running", NULL, 1, 1, RRD_DIMENSION_ABSOLUTE);
5453 + rrd_stats_dimension_add(st, "blocked", NULL, -1, 1, RRD_DIMENSION_ABSOLUTE);
5454 }
5455 else rrd_stats_next(st);
5456
@@ -5972,7 +5996,7 @@ void *proc_main(void *ptr)
5996 if(!stclients) {
5997 stclients = rrd_stats_create("netdata", "clients", NULL, "netdata", "NetData Web Clients", "connected clients", 11000, update_every, CHART_TYPE_LINE);
5998
5975 - rrd_stats_dimension_add(stclients, "clients", NULL, 1, 1, RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION);
5999 + rrd_stats_dimension_add(stclients, "clients", NULL, 1, 1, RRD_DIMENSION_ABSOLUTE);
6000 }
6001 else rrd_stats_next(stclients);
6002
@@ -5985,7 +6009,7 @@ void *proc_main(void *ptr)
6009 if(!streqs) {
6010 streqs = rrd_stats_create("netdata", "requests", NULL, "netdata", "NetData Web Requests", "requests/s", 12000, update_every, CHART_TYPE_LINE);
6011
5988 - rrd_stats_dimension_add(streqs, "requests", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
6012 + rrd_stats_dimension_add(streqs, "requests", NULL, 1, 1, RRD_DIMENSION_INCREMENTAL);
6013 }
6014 else rrd_stats_next(streqs);
6015
@@ -7258,6 +7282,43 @@ int become_daemon(int close_all_files, const char *input, const char *output, co
7282 return(0);
7283 }
7284
7285 +int unit_test_storage()
7286 +{
7287 + char buffer[100];
7288 + storage_number s;
7289 + calculated_number c, a = 0, d, f;
7290 + int i, j, g, r = 0, l;
7291 +
7292 + for(g = -1; g <= 1 ; g++) {
7293 + a = 0;
7294 +
7295 + if(!g) continue;
7296 +
7297 + for(j = 0; j < 9 ;j++) {
7298 + a += 0.0000001;
7299 + c = a * g;
7300 + for(i = 0; i < 21 ;i++, c *= 10) {
7301 + s = pack_storage_number(c);
7302 + d = unpack_storage_number(s);
7303 +
7304 + f = d / c;
7305 +
7306 + l = print_calculated_number(buffer, d);
7307 +
7308 + if(f < 0.99999 || f > 1.00001) {
7309 + fprintf(stderr, "\nERROR\n" CALCULATED_NUMBER_FORMAT " original\n" CALCULATED_NUMBER_FORMAT " unpacked, (stored as 0x%08X)\n%s printed as %d bytes\n", c, d, s, buffer, l);
7310 + r++;
7311 + }
7312 + else {
7313 + fprintf(stderr, "\nOK\n" CALCULATED_NUMBER_FORMAT " original\n" CALCULATED_NUMBER_FORMAT " unpacked, (stored as 0x%08X)\n%s printed as %d bytes\n", c, d, s, buffer, l);
7314 + }
7315 + }
7316 + }
7317 + }
7318 +
7319 + return r;
7320 +}
7321 +
7322 int unit_test(long delay, long shift)
7323 {
7324 static int repeat = 0;
@@ -7271,8 +7332,6 @@ int unit_test(long delay, long shift)
7332
7333 int do_abs = 1;
7334 int do_inc = 1;
7274 - int do_abs2 = 1;
7275 - int do_inc2 = 1;
7335 int do_abst = 1;
7336 int do_absi = 1;
7337
@@ -7281,15 +7340,11 @@ int unit_test(long delay, long shift)
7340
7341 RRD_DIMENSION *rdabs = NULL;
7342 RRD_DIMENSION *rdinc = NULL;
7284 - RRD_DIMENSION *rdabs2 = NULL;
7285 - RRD_DIMENSION *rdinc2 = NULL;
7343 RRD_DIMENSION *rdabst = NULL;
7344 RRD_DIMENSION *rdabsi = NULL;
7345
7346 if(do_abs) rdabs = rrd_stats_dimension_add(st, "absolute", "absolute", 1, 1, RRD_DIMENSION_ABSOLUTE);
7347 if(do_inc) rdinc = rrd_stats_dimension_add(st, "incremental", "incremental", 1, 1, RRD_DIMENSION_INCREMENTAL);
7291 - if(do_abs2) rdabs2 = rrd_stats_dimension_add(st, "absolute-no-interpolation", "absolute-no-interpolation", 1, 1, RRD_DIMENSION_ABSOLUTE_NO_INTERPOLATION);
7292 - if(do_inc2) rdinc2 = rrd_stats_dimension_add(st, "incremental-no-interpolation", "incremental-no-interpolation", 1, 1, RRD_DIMENSION_INCREMENTAL_NO_INTERPOLATION);
7348 if(do_abst) rdabst = rrd_stats_dimension_add(st, "percentage-of-absolute-row", "percentage-of-absolute-row", 1, 1, RRD_DIMENSION_PCENT_OVER_ROW_TOTAL);
7349 if(do_absi) rdabsi = rrd_stats_dimension_add(st, "percentage-of-incremental-row", "percentage-of-incremental-row", 1, 1, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL);
7350
@@ -7309,8 +7364,6 @@ int unit_test(long delay, long shift)
7364 }
7365 if(do_abs) rrd_stats_dimension_set(st, "absolute", i);
7366 if(do_inc) rrd_stats_dimension_set(st, "incremental", i);
7312 - if(do_abs2) rrd_stats_dimension_set(st, "absolute-no-interpolation", i);
7313 - if(do_inc2) rrd_stats_dimension_set(st, "incremental-no-interpolation", i);
7367 if(do_abst) rrd_stats_dimension_set(st, "percentage-of-absolute-row", i);
7368 if(do_absi) rrd_stats_dimension_set(st, "percentage-of-incremental-row", i);
7369
@@ -7344,22 +7397,14 @@ int unit_test(long delay, long shift)
7397 ) * 10;
7398
7399 else if(rd == rdinc) v = (c?(increment):(increment * (1000000 - shift) / 1000000)) * 10;
7347 - else if(rd == rdabs2) v = (((oincrement + c * increment + increment * (1000000 - shift) / 1000000 ) + oincrement - 1) / oincrement) * oincrement * 10;
7348 - else if(rd == rdinc2) v = increment * 10;
7400 else if(rd == rdabst) v = oincrement / dimensions;
7401 else if(rd == rdabsi) v = oincrement / dimensions;
7402 else v = 0;
7403
7404 if(v == rd->values[c]) fprintf(stderr, "passed.\n");
7405 else {
7355 - if(rd == rdabs2) {
7356 - // FIXME: the expected numbers are wrong
7357 - fprintf(stderr, "IGNORED (expected " STORAGE_NUMBER_FORMAT ")\n", v);
7358 - }
7359 - else {
7360 - fprintf(stderr, "ERROR! (expected " STORAGE_NUMBER_FORMAT ")\n", v);
7361 - ret = 1;
7362 - }
7406 + fprintf(stderr, "ERROR! (expected " STORAGE_NUMBER_FORMAT ")\n", v);
7407 + ret = 1;
7408 }
7409 }
7410 }
@@ -7394,6 +7439,8 @@ int main(int argc, char **argv)
7439 else if(strcmp(argv[i], "-l") == 0 && (i+1) < argc) { config_set("global", "history", argv[i+1]); i++; }
7440 else if(strcmp(argv[i], "-t") == 0 && (i+1) < argc) { config_set("global", "update every", argv[i+1]); i++; }
7441 else if(strcmp(argv[i], "--unittest") == 0) {
7442 + if(unit_test_storage()) exit(1);
7443 + exit(0);
7444 update_every = 1;
7445 if(unit_test(1000000, 0)) exit(1);
7446 if(unit_test(1000000, 500000)) exit(1);
web/netdata.js
+2 -6
@@ -57,7 +57,8 @@ function refreshChart(chart, doNext) {
57
58 // Create our data table out of JSON data loaded from server.
59 chart.datatable = new google.visualization.DataTable(chart.jsondata);
60 -
60 + //console.log(chart.datatable);
61 +
62 // cleanup once every 50 updates
63 // we don't cleanup on every single, to avoid firefox flashing effect
64 if(chart.chart && chart.refreshCount > 50) {
@@ -282,11 +283,6 @@ function loadCharts(base_url, doNext) {
283 json.charts[i].non_zero = 0;
284
285 json.charts[i].default_curveType = 'function';
285 - $.each(json.charts[i].dimensions, function(d, dim) {
286 - if(dim.algorithm == 'incremental-no-interpolation' || dim.algorithm == 'absolute-no-interpolation') {
287 - json.charts[i].default_curveType = 'none';
288 - }
289 - });
286 break;
287 }
288