@cryptotaxi247 / netdata-1 / commits / 12beb9c6a

visualized gauges, counters, meters and sets - missing histograms and timers

Costa Tsaousis (ktsaou) committed Apr 26, 2017 at 02:19 UTC 12beb9c6a04f34d3bd38e974f572dba435fa8cb1
2 files changed +322 -50
src/statsd.c
+321 -50
@@ -26,18 +26,22 @@
26 #define STATSD_DICTIONARY_OPTIONS DICTIONARY_FLAG_SINGLE_THREADED
27 #endif
28
29 +
30 +// --------------------------------------------------------------------------------------------------------------------
31 +// data specific to each metric type
32 +
33 typedef struct statsd_metric_gauge {
34 long double value;
35 } STATSD_METRIC_GAUGE;
36
33 -typedef struct statsd_metric_counter {
37 +typedef struct statsd_metric_counter { // counter and meter
38 long long value;
39 } STATSD_METRIC_COUNTER;
40
37 -typedef struct statsd_metric_histogram {
41 +typedef struct statsd_metric_histogram { // histogram and timer
42 size_t size;
43 size_t used;
40 - long double *values;
44 + long double *values; // dynamic array of values collected
45 } STATSD_METRIC_HISTOGRAM;
46
47 typedef struct statsd_metric_set {
@@ -45,42 +49,70 @@ typedef struct statsd_metric_set {
49 unsigned long long unique;
50 } STATSD_METRIC_SET;
51
48 -typedef struct statsd_metric_set_value {
49 - char *value;
50 - uint32_t hash;
51 -} STATSD_METRIC_SET_VALUE;
52 +
53 +// --------------------------------------------------------------------------------------------------------------------
54 +// this is a metric - for all types of metrics
55 +
56 +typedef enum statsd_metric_options {
57 + STATSD_METRIC_OPTION_NONE = 0x00000000,
58 + STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED = 0x00000001,
59 + STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED = 0x00000002,
60 + STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED = 0x00000004,
61 +} STATS_METRIC_OPTIONS;
62
63 typedef struct statsd_metric {
64 avl avl; // indexing
55 - struct statsd_metric *next;
65
57 - const char *name;
66 + const char *name; // the name of the metric
67 uint32_t hash; // hash of the name
68
60 - size_t count; // the number of times this metrics has been collected
61 - calculated_number sampling; // the sampling rate of this metric
62 -
63 - char reset; // set to 1 to reset this metric to zero
69 + // metadata about data collection
70 + size_t events; // the number of times this metric has been collected (never resets)
71 + size_t count; // the number of times this metric has been collected since the last flush
72
73 + // the actual collected data
74 union {
75 STATSD_METRIC_GAUGE gauge;
76 STATSD_METRIC_COUNTER counter;
77 STATSD_METRIC_HISTOGRAM histogram;
78 STATSD_METRIC_SET set;
79 };
80 +
81 + // chart related members
82 + STATS_METRIC_OPTIONS options; // STATSD_METRIC_OPTION_* (bitfield)
83 + char reset; // set to 1 to reset this metric to zero
84 + collected_number last; // the last value sent to netdata
85 + RRDSET *st; // the chart of this metric
86 + RRDDIM *rd_value; // the dimension of this metric value
87 + RRDDIM *rd_count; // the dimension for the number of events received
88 +
89 + // linking, used for walking through all metrics
90 + struct statsd_metric *next;
91 } STATSD_METRIC;
92
93 +
94 +// --------------------------------------------------------------------------------------------------------------------
95 +// each type of metric has its own index
96 +
97 typedef struct statsd_index {
74 - char *name;
75 - size_t events;
76 - size_t metrics;
77 - STATSD_METRIC *first;
78 - STATSD_AVL_TREE index;
79 - STATSD_FIRST_PTR_MUTEX;
98 + char *name; // the name of the index of metrics
99 + size_t events; // the number of events processed for this index
100 + size_t metrics; // the number of metrics in this index
101 +
102 + STATSD_AVL_TREE index; // the AVL tree
103 +
104 + STATSD_METRIC *first; // the linked list of metrics (new metrics are added in front)
105 + STATSD_FIRST_PTR_MUTEX; // when mutli-threading is enabled, a lock to protect the linked list
106 +
107 + STATS_METRIC_OPTIONS default_options; // default options for all metrics in this index
108 } STATSD_INDEX;
109
110 static int statsd_metric_compare(void* a, void* b);
111
112 +
113 +// --------------------------------------------------------------------------------------------------------------------
114 +// global statsd data
115 +
116 static struct statsd {
117 STATSD_INDEX gauges;
118 STATSD_INDEX counters;
@@ -89,56 +121,68 @@ static struct statsd {
121 STATSD_INDEX meters;
122 STATSD_INDEX sets;
123
124 + int enabled;
125 + int update_every;
126 + SIMPLE_PATTERN *charts_for;
127 +
128 size_t histogram_increase_step;
129 int threads;
130 LISTEN_SOCKETS sockets;
131 } statsd = {
132 + .enabled = 1,
133 +
134 .gauges = {
135 .name = "gauge",
136 .events = 0,
137 .metrics = 0,
100 - .first = NULL,
138 .index = STATSD_AVL_INDEX_INIT,
139 + .default_options = STATSD_METRIC_OPTION_NONE,
140 + .first = NULL,
141 STATSD_FIRST_PTR_MUTEX_INIT
142 },
143 .counters = {
144 .name = "counter",
145 .events = 0,
146 .metrics = 0,
108 - .first = NULL,
147 .index = STATSD_AVL_INDEX_INIT,
148 + .default_options = STATSD_METRIC_OPTION_NONE,
149 + .first = NULL,
150 STATSD_FIRST_PTR_MUTEX_INIT
151 },
152 .timers = {
153 .name = "timer",
154 .events = 0,
155 .metrics = 0,
116 - .first = NULL,
156 .index = STATSD_AVL_INDEX_INIT,
157 + .default_options = STATSD_METRIC_OPTION_NONE,
158 + .first = NULL,
159 STATSD_FIRST_PTR_MUTEX_INIT
160 },
161 .histograms = {
162 .name = "histogram",
163 .events = 0,
164 .metrics = 0,
124 - .first = NULL,
165 .index = STATSD_AVL_INDEX_INIT,
166 + .default_options = STATSD_METRIC_OPTION_NONE,
167 + .first = NULL,
168 STATSD_FIRST_PTR_MUTEX_INIT
169 },
170 .meters = {
171 .name = "meter",
172 .events = 0,
173 .metrics = 0,
132 - .first = NULL,
174 .index = STATSD_AVL_INDEX_INIT,
175 + .default_options = STATSD_METRIC_OPTION_NONE,
176 + .first = NULL,
177 STATSD_FIRST_PTR_MUTEX_INIT
178 },
179 .sets = {
180 .name = "set",
181 .events = 0,
182 .metrics = 0,
140 - .first = NULL,
183 .index = STATSD_AVL_INDEX_INIT,
184 + .default_options = STATSD_METRIC_OPTION_NONE,
185 + .first = NULL,
186 STATSD_FIRST_PTR_MUTEX_INIT
187 },
188
@@ -152,14 +196,9 @@ static struct statsd {
196 },
197 };
198
155 -// --------------------------------------------------------------------------------------
156 -
157 -int statsd_listen_sockets_setup(void) {
158 - return listen_sockets_setup(&statsd.sockets);
159 -}
199
200 // --------------------------------------------------------------------------------------------------------------------
162 -// statsd index
201 +// statsd index management - add/find metrics
202
203 static int statsd_metric_compare(void* a, void* b) {
204 if(((STATSD_METRIC *)a)->hash < ((STATSD_METRIC *)b)->hash) return -1;
@@ -187,6 +226,7 @@ static inline STATSD_METRIC *statsd_find_or_add_metric(STATSD_INDEX *index, char
226 m = (STATSD_METRIC *)callocz(sizeof(STATSD_METRIC), 1);
227 m->name = strdupz(metric);
228 m->hash = hash;
229 + m->options = index->default_options;
230 STATSD_METRIC *n = (STATSD_METRIC *)STATSD_AVL_INSERT(&index->index, (avl *)m);
231 if(unlikely(n != m)) {
232 freez((void *)m->name);
@@ -243,7 +283,6 @@ static inline long long statsd_parse_int(const char *v, long long def) {
283 static inline void statsd_reset_metric(STATSD_METRIC *m) {
284 m->reset = 0;
285 m->count = 0;
246 - m->sampling = 0.0;
286 }
287
288 static inline void statsd_process_gauge(STATSD_METRIC *m, char *v, char *r) {
@@ -252,24 +291,29 @@ static inline void statsd_process_gauge(STATSD_METRIC *m, char *v, char *r) {
291 return;
292 }
293
255 - if(unlikely(m->reset)) statsd_reset_metric(m);
256 - m->count++;
257 - m->sampling += statsd_parse_float(r, 1.0);
294 + if(unlikely(m->reset)) {
295 + // no need to reset anything specific for gauges
296 + statsd_reset_metric(m);
297 + }
298
299 if(*v == '+' || *v == '-')
260 - m->gauge.value += statsd_parse_float(v, 1.0);
300 + m->gauge.value += statsd_parse_float(v, 1.0) / statsd_parse_float(r, 1.0);
301 else
262 - m->gauge.value = statsd_parse_float(v, 1.0);
302 + m->gauge.value = statsd_parse_float(v, 1.0) / statsd_parse_float(r, 1.0);
303 +
304 + m->events++;
305 + m->count++;
306 }
307
308 static inline void statsd_process_counter(STATSD_METRIC *m, char *v, char *r) {
309 // we accept empty values for counters
310
311 if(unlikely(m->reset)) statsd_reset_metric(m);
269 - m->count++;
270 - m->sampling += statsd_parse_float(r, 1.0);
312
272 - m->counter.value += statsd_parse_int(v, 1);
313 + m->counter.value += roundl((long double)statsd_parse_int(v, 1) / statsd_parse_float(r, 1.0));
314 +
315 + m->events++;
316 + m->count++;
317 }
318
319 static inline void statsd_process_meter(STATSD_METRIC *m, char *v, char *r) {
@@ -288,15 +332,15 @@ static inline void statsd_process_histogram(STATSD_METRIC *m, char *v, char *r)
332 statsd_reset_metric(m);
333 }
334
291 - m->count++;
292 - m->sampling += statsd_parse_float(r, 1.0);
293 -
335 if(m->histogram.used == m->histogram.size) {
336 m->histogram.size += statsd.histogram_increase_step;
337 m->histogram.values = reallocz(m->histogram.values, sizeof(long double) * m->histogram.size);
338 }
339
299 - m->histogram.values[m->histogram.used++] = statsd_parse_float(v, 1.0);
340 + m->histogram.values[m->histogram.used++] = statsd_parse_float(v, 1.0) / statsd_parse_float(r, 1.0);
341 +
342 + m->events++;
343 + m->count++;
344 }
345
346 static inline void statsd_process_timer(STATSD_METRIC *m, char *v, char *r) {
@@ -335,6 +379,9 @@ static inline void statsd_process_set(STATSD_METRIC *m, char *v, char *r) {
379 dictionary_set(m->set.dict, v, v, 1);
380 m->set.unique++;
381 }
382 +
383 + m->events++;
384 + m->count++;
385 }
386
387
@@ -605,7 +652,7 @@ static int statsd_rcv_callback(int fd, int socktype, void *data, short int *even
652
653
654 // --------------------------------------------------------------------------------------------------------------------
608 -// statsd child thread to update netdata
655 +// statsd child thread to collect metrics from network
656
657 void *statsd_collector_thread(void *ptr) {
658 int id = *((int *)ptr);
@@ -633,8 +680,198 @@ void *statsd_collector_thread(void *ptr) {
680
681
682 // --------------------------------------------------------------------------------------------------------------------
683 +// send metrics to netdata - called from the main thread
684 +
685 +#define STATSD_CHART_PREFIX "statsd"
686 +#define STATSD_CHART_PRIORITY 90000
687 +
688 +// extract chart type and chart id from metric name
689 +static inline void statsd_get_metric_type_and_id(STATSD_METRIC *m, char *type, char *id, char *defid, size_t len) {
690 + char *s;
691 +
692 + snprintfz(type, len, "%s_%s_%s", STATSD_CHART_PREFIX, defid, m->name);
693 + for(s = type; *s ;s++)
694 + if(unlikely(*s == '.')) break;
695 +
696 + if(*s == '.') {
697 + *s++ = '\0';
698 + strncpyz(id, s, len);
699 + }
700 + else {
701 + strncpyz(id, defid, len);
702 + }
703 +
704 + netdata_fix_chart_id(type);
705 + netdata_fix_chart_id(id);
706 +}
707 +
708 +static inline void statsd_chart_from_gauge(STATSD_METRIC *m) {
709 + if(unlikely(!m->st)) {
710 + char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1];
711 + statsd_get_metric_type_and_id(m, type, id, "gauge", RRD_ID_LENGTH_MAX);
712 +
713 + m->st = rrdset_create_localhost(
714 + type
715 + , id
716 + , NULL // name
717 + , "gauges" // family (submenu)
718 + , m->name // context
719 + , m->name // title
720 + , "value" // units
721 + , STATSD_CHART_PRIORITY
722 + , statsd.update_every
723 + , RRDSET_TYPE_AREA
724 + );
725 +
726 + m->rd_value = rrddim_add(m->st, "gauge", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
727 + m->rd_count = rrddim_add(m->st, "events", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
728 + }
729 + else rrdset_next(m->st);
730 +
731 + if(m->count && !m->reset)
732 + m->last = (collected_number )(m->gauge.value * 1000.0);
733 +
734 + m->reset = 1;
735 + rrddim_set_by_pointer(m->st, m->rd_value, m->last);
736 + rrddim_set_by_pointer(m->st, m->rd_count, (collected_number)m->events);
737 + rrdset_done(m->st);
738 +}
739 +
740 +static inline void statsd_chart_from_counter(STATSD_METRIC *m) {
741 + if(unlikely(!m->st)) {
742 + char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1];
743 + statsd_get_metric_type_and_id(m, type, id, "counter", RRD_ID_LENGTH_MAX);
744 +
745 + m->st = rrdset_create_localhost(
746 + type
747 + , id
748 + , NULL // name
749 + , "counters" // family (submenu)
750 + , m->name // context
751 + , m->name // title
752 + , "events/s" // units
753 + , STATSD_CHART_PRIORITY
754 + , statsd.update_every
755 + , RRDSET_TYPE_LINE
756 + );
757 +
758 + m->rd_value = rrddim_add(m->st, "counter", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
759 + m->rd_count = rrddim_add(m->st, "events", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
760 + }
761 + else rrdset_next(m->st);
762 +
763 + if(m->count && !m->reset)
764 + m->last = m->counter.value;
765 +
766 + m->reset = 1;
767 + rrddim_set_by_pointer(m->st, m->rd_value, m->last);
768 + rrddim_set_by_pointer(m->st, m->rd_count, (collected_number)m->events);
769 + rrdset_done(m->st);
770 +}
771 +
772 +static inline void statsd_chart_from_meter(STATSD_METRIC *m) {
773 + if(unlikely(!m->st)) {
774 + char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1];
775 + statsd_get_metric_type_and_id(m, type, id, "meter", RRD_ID_LENGTH_MAX);
776 +
777 + m->st = rrdset_create_localhost(
778 + type
779 + , id
780 + , NULL // name
781 + , "meters" // family (submenu)
782 + , m->name // context
783 + , m->name // title
784 + , "events/s" // units
785 + , STATSD_CHART_PRIORITY
786 + , statsd.update_every
787 + , RRDSET_TYPE_LINE
788 + );
789 +
790 + m->rd_value = rrddim_add(m->st, "meter", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
791 + m->rd_count = rrddim_add(m->st, "events", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
792 + }
793 + else rrdset_next(m->st);
794 +
795 + if(m->count && !m->reset)
796 + m->last = m->counter.value;
797 +
798 + m->reset = 1;
799 + rrddim_set_by_pointer(m->st, m->rd_value, m->last);
800 + rrddim_set_by_pointer(m->st, m->rd_count, (collected_number)m->events);
801 + rrdset_done(m->st);
802 +}
803 +
804 +static inline void statsd_chart_from_set(STATSD_METRIC *m) {
805 + if(unlikely(!m->st)) {
806 + char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1];
807 + statsd_get_metric_type_and_id(m, type, id, "set", RRD_ID_LENGTH_MAX);
808 +
809 + m->st = rrdset_create_localhost(
810 + type
811 + , id
812 + , NULL // name
813 + , "sets" // family (submenu)
814 + , m->name // context
815 + , m->name // title
816 + , "entries" // units
817 + , STATSD_CHART_PRIORITY
818 + , statsd.update_every
819 + , RRDSET_TYPE_LINE
820 + );
821 +
822 + m->rd_value = rrddim_add(m->st, "set", "set size", 1, 1, RRD_ALGORITHM_ABSOLUTE);
823 + m->rd_count = rrddim_add(m->st, "events", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
824 + }
825 + else rrdset_next(m->st);
826 +
827 + if(m->count && !m->reset)
828 + m->last = m->set.unique;
829 +
830 + m->reset = 1;
831 + rrddim_set_by_pointer(m->st, m->rd_value, m->last);
832 + rrddim_set_by_pointer(m->st, m->rd_count, (collected_number)m->events);
833 + rrdset_done(m->st);
834 +}
835 +
836 +static inline void statsd_charts_from_index(STATSD_INDEX *index, void (*chart_from_metric)(STATSD_METRIC *m)) {
837 + STATSD_METRIC *m;
838 + for(m = index->first; m ; m = m->next) {
839 +
840 + // if this is the first time we see this metric
841 + // check it against our list
842 + if(unlikely(!(m->options & STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED|STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED))) {
843 + if(simple_pattern_matches(statsd.charts_for, m->name))
844 + m->options |= STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED;
845 + else
846 + m->options |= STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED;
847 + }
848 +
849 + // if it is not enabled, don't do anything
850 + if(unlikely(m->options & STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED)) {
851 + m->reset = 1; // reset it to allow housekeeping
852 + continue;
853 + }
854 +
855 + // if no values are collected, and we need to show gaps
856 + if(unlikely((m->reset || !m->count) && m->options & STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED)) {
857 + m->reset = 1; // reset it to allow housekeeping
858 + continue;
859 + }
860 +
861 + // send it to netdata
862 + if(likely(chart_from_metric))
863 + chart_from_metric(m);
864 + }
865 +}
866 +
867 +
868 +// --------------------------------------------------------------------------------------
869 // statsd main thread
870
871 +int statsd_listen_sockets_setup(void) {
872 + return listen_sockets_setup(&statsd.sockets);
873 +}
874 +
875 void *statsd_main(void *ptr) {
876 (void)ptr;
877
@@ -646,8 +883,35 @@ void *statsd_main(void *ptr) {
883 if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
884 error("Cannot set pthread cancel state to ENABLE.");
885
649 - int enabled = config_get_boolean(CONFIG_SECTION_STATSD, "enabled", 1);
650 - if(!enabled) return NULL;
886 + statsd.enabled = config_get_boolean(CONFIG_SECTION_STATSD, "enabled", statsd.enabled);
887 + if(!statsd.enabled) return NULL;
888 +
889 + statsd.update_every = default_rrd_update_every;
890 + statsd.update_every = config_get_boolean(CONFIG_SECTION_STATSD, "update every (statsd flushInterval)", statsd.update_every);
891 + if(statsd.update_every < default_rrd_update_every) {
892 + error("STATSD: minimum flush interval %d given, but the minimum is the update every of netdata. Using %d", statsd.update_every, default_rrd_update_every);
893 + statsd.update_every = default_rrd_update_every;
894 + }
895 +
896 + statsd.charts_for = simple_pattern_create(config_get(CONFIG_SECTION_STATSD, "create charts for metrics", "*"), SIMPLE_PATTERN_EXACT);
897 +
898 + if(config_get_boolean(CONFIG_SECTION_STATSD, "gaps on gauges (statsd deleteGauges)", 0))
899 + statsd.gauges.default_options |= STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED;
900 +
901 + if(config_get_boolean(CONFIG_SECTION_STATSD, "gaps on counters (statsd deleteCounters)", 0))
902 + statsd.counters.default_options |= STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED;
903 +
904 + if(config_get_boolean(CONFIG_SECTION_STATSD, "gaps on meters (statsd deleteMeters)", 0))
905 + statsd.meters.default_options |= STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED;
906 +
907 + if(config_get_boolean(CONFIG_SECTION_STATSD, "gaps on sets (statsd deleteSets)", 0))
908 + statsd.sets.default_options |= STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED;
909 +
910 + if(config_get_boolean(CONFIG_SECTION_STATSD, "gaps on histograms (statsd deleteHistograms)", 0))
911 + statsd.histograms.default_options |= STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED;
912 +
913 + if(config_get_boolean(CONFIG_SECTION_STATSD, "gaps on timers (statsd deleteTimers)", 0))
914 + statsd.timers.default_options |= STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED;
915
916 statsd_listen_sockets_setup();
917 if(!statsd.sockets.opened) {
@@ -686,7 +950,7 @@ void *statsd_main(void *ptr) {
950 , "Metrics in the netdata statsd database"
951 , "metrics"
952 , 132000
689 - , localhost->rrd_update_every
953 + , statsd.update_every
954 , RRDSET_TYPE_STACKED
955 );
956 RRDDIM *rd_metrics_gauge = rrddim_add(st_metrics, "gauges", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
@@ -705,7 +969,7 @@ void *statsd_main(void *ptr) {
969 , "Events processed by the netdata statsd server"
970 , "events/s"
971 , 132001
708 - , localhost->rrd_update_every
972 + , statsd.update_every
973 , RRDSET_TYPE_STACKED
974 );
975 RRDDIM *rd_events_gauge = rrddim_add(st_events, "gauges", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -715,7 +979,7 @@ void *statsd_main(void *ptr) {
979 RRDDIM *rd_events_histogram = rrddim_add(st_events, "histograms", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
980 RRDDIM *rd_events_set = rrddim_add(st_events, "sets", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
981
718 - usec_t step = localhost->rrd_update_every * USEC_PER_SEC;
982 + usec_t step = statsd.update_every * USEC_PER_SEC;
983 heartbeat_t hb;
984 heartbeat_init(&hb);
985 for(;;) {
@@ -752,6 +1016,13 @@ void *statsd_main(void *ptr) {
1016 if(unlikely(netdata_exit))
1017 break;
1018
1019 + statsd_charts_from_index(&statsd.gauges, statsd_chart_from_gauge);
1020 + statsd_charts_from_index(&statsd.counters, statsd_chart_from_counter);
1021 + statsd_charts_from_index(&statsd.meters, statsd_chart_from_meter);
1022 + statsd_charts_from_index(&statsd.timers, NULL);
1023 + statsd_charts_from_index(&statsd.histograms, NULL);
1024 + statsd_charts_from_index(&statsd.sets, statsd_chart_from_set);
1025 +
1026 }
1027
1028 for(i = 0; i < statsd.threads ;i++)
web/index.html
+1
@@ -1164,6 +1164,7 @@
1164 case 'ap':
1165 case 'net':
1166 case 'disk':
1167 + case 'statsd':
1168 chart.menu = tmp;
1169 break;
1170