126
int update_every;
127
SIMPLE_PATTERN *charts_for;
128
129
+ size_t private_charts;
130
+ size_t max_private_charts;
131
+ size_t max_private_charts_hard;
132
+ RRD_MEMORY_MODE private_charts_memory_mode;
133
+ int private_charts_history;
134
+
135
size_t histogram_increase_step;
136
int threads;
137
LISTEN_SOCKETS sockets;
138
} statsd = {
139
.enabled = 1,
140
+ .private_charts = 0,
141
+ .max_private_charts = 200,
142
+ .max_private_charts_hard = 1000,
143
144
.gauges = {
145
.name = "gauge",
715
netdata_fix_chart_id(id);
716
}
717
718
+static inline RRDSET *statsd_private_rrdset_create(
719
+ STATSD_METRIC *m
720
+ , const char *type
721
+ , const char *id
722
+ , const char *name
723
+ , const char *family
724
+ , const char *context
725
+ , const char *title
726
+ , const char *units
727
+ , long priority
728
+ , int update_every
729
+ , RRDSET_TYPE chart_type
730
+) {
731
+ RRD_MEMORY_MODE memory_mode = statsd.private_charts_memory_mode;
732
+ long history = statsd.private_charts_history;
733
+
734
+ if(unlikely(statsd.private_charts >= statsd.max_private_charts)) {
735
+ debug(D_STATSD, "STATSD: metric '%s' will be charted with memory mode = none, because the maximum number of charts has been reached.", m->name);
736
+ info("STATSD: metric '%s' will be charted with memory mode = none, because the maximum number of charts (%zu) has been reached. Increase the number of charts by editing netdata.conf, [statsd] section.", m->name, statsd.max_private_charts);
737
+ memory_mode = RRD_MEMORY_MODE_NONE;
738
+ history = 5;
739
+ }
740
+
741
+ statsd.private_charts++;
742
+ return rrdset_create_custom(
743
+ localhost
744
+ , type
745
+ , id
746
+ , name
747
+ , family
748
+ , context
749
+ , title
750
+ , units
751
+ , priority
752
+ , update_every
753
+ , chart_type
754
+ , memory_mode
755
+ , history
756
+ );
757
+}
758
+
759
+
760
static inline void statsd_chart_from_gauge(STATSD_METRIC *m) {
761
if(unlikely(!m->st)) {
762
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1];
763
statsd_get_metric_type_and_id(m, type, id, "gauge", RRD_ID_LENGTH_MAX);
764
714
- m->st = rrdset_create_localhost(
715
- type
716
- , id
717
- , NULL // name
718
- , "gauges" // family (submenu)
719
- , m->name // context
720
- , m->name // title
721
- , "value" // units
722
- , STATSD_CHART_PRIORITY
723
- , statsd.update_every
724
- , RRDSET_TYPE_LINE
765
+ m->st = statsd_private_rrdset_create(
766
+ m
767
+ , type
768
+ , id
769
+ , NULL // name
770
+ , "gauges" // family (submenu)
771
+ , m->name // context
772
+ , m->name // title
773
+ , "value" // units
774
+ , STATSD_CHART_PRIORITY
775
+ , statsd.update_every
776
+ , RRDSET_TYPE_LINE
777
);
778
779
m->rd_value = rrddim_add(m->st, "gauge", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
799
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1];
800
statsd_get_metric_type_and_id(m, type, id, dim, RRD_ID_LENGTH_MAX);
801
750
- m->st = rrdset_create_localhost(
751
- type
802
+ m->st = statsd_private_rrdset_create(
803
+ m
804
+ , type
805
, id
806
, NULL // name
807
, family // family (submenu)
844
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1];
845
statsd_get_metric_type_and_id(m, type, id, "set", RRD_ID_LENGTH_MAX);
846
794
- m->st = rrdset_create_localhost(
795
- type
847
+ m->st = statsd_private_rrdset_create(
848
+ m
849
+ , type
850
, id
851
, NULL // name
852
, "sets" // family (submenu)
858
, RRDSET_TYPE_LINE
859
);
860
807
- m->rd_value = rrddim_add(m->st, "set", "set size", 1, 1, RRD_ALGORITHM_ABSOLUTE);
861
+ m->rd_value = rrddim_add(m->st, "set", "set size", 1, 1, RRD_ALGORITHM_ABSOLUTE);
862
863
if(m->options & STATSD_METRIC_OPTION_CHART_DIMENSION_COUNT)
864
m->rd_count = rrddim_add(m->st, "events", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
877
rrdset_done(m->st);
878
}
879
826
-static inline void statsd_charts_from_index(STATSD_INDEX *index, void (*chart_from_metric)(STATSD_METRIC *m)) {
880
+static inline void statsd_private_charts_from_index(STATSD_INDEX *index, void (*chart_from_metric)(STATSD_METRIC *m)) {
881
STATSD_METRIC *m;
882
for(m = index->first; m ; m = m->next) {
829
-
830
- // if this is the first time we see this metric
831
- // check it against our list
832
- if(unlikely(!(m->options & STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED|STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED))) {
833
- if(simple_pattern_matches(statsd.charts_for, m->name))
834
- m->options |= STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED;
835
- else
883
+ if(unlikely(!(m->options & (STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED|STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED)))) {
884
+ if(statsd.private_charts >= statsd.max_private_charts_hard) {
885
+ debug(D_STATSD, "STATSD: metric '%s' will not be charted, because the hard limit of the maximum number of charts has been reached.", m->name);
886
+ info("STATSD: metric '%s' will not be charted, because the hard limit of the maximum number of charts (%zu) has been reached. Increase the number of charts by editing netdata.conf, [statsd] section.", m->name, statsd.max_private_charts);
887
m->options |= STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED;
837
- }
838
-
839
- // if it is not enabled, don't do anything
840
- if(unlikely(m->options & STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED)) {
841
- m->reset = 1; // reset it to allow housekeeping
842
- continue;
888
+ m->options &= ~STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED;
889
+ }
890
+ else {
891
+ if (simple_pattern_matches(statsd.charts_for, m->name)) {
892
+ debug(D_STATSD, "STATSD: metric '%s' will be charted.", m->name);
893
+ m->options |= STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED;
894
+ m->options &= ~STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED;
895
+ } else {
896
+ debug(D_STATSD, "STATSD: metric '%s' will not be charted.", m->name);
897
+ m->options |= STATSD_METRIC_OPTION_PRIVATE_CHART_DISABLED;
898
+ m->options &= ~STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED;
899
+ }
900
+ }
901
}
902
903
// if no values are collected, and we need to show gaps
906
continue;
907
}
908
851
- // send it to netdata
852
- if(likely(chart_from_metric))
909
+ if(likely(m->options & STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED && chart_from_metric))
910
+ // send it to netdata
911
chart_from_metric(m);
912
+ else
913
+ // since we not going to send it, reset it to allow housekeeping
914
+ m->reset = 1;
915
}
916
}
917
945
}
946
947
statsd.charts_for = simple_pattern_create(config_get(CONFIG_SECTION_STATSD, "create private charts for metrics matching", "*"), SIMPLE_PATTERN_EXACT);
948
+ statsd.max_private_charts = (size_t)config_get_number(CONFIG_SECTION_STATSD, "max private charts allowed", (long long)statsd.max_private_charts);
949
+ statsd.max_private_charts_hard = (size_t)config_get_number(CONFIG_SECTION_STATSD, "max private charts hard limit", (long long)statsd.max_private_charts * 5);
950
+ statsd.private_charts_memory_mode = rrd_memory_mode_id(config_get(CONFIG_SECTION_STATSD, "private charts memory mode", rrd_memory_mode_name(default_rrd_memory_mode)));
951
+ statsd.private_charts_history = (int)config_get_number(CONFIG_SECTION_STATSD, "private charts history", default_rrd_history_entries);
952
953
if(config_get_boolean(CONFIG_SECTION_STATSD, "add dimension for number of events received", 1)) {
954
statsd.gauges.default_options |= STATSD_METRIC_OPTION_CHART_DIMENSION_COUNT;
1043
RRDDIM *rd_events_histogram = rrddim_add(st_events, "histograms", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1044
RRDDIM *rd_events_set = rrddim_add(st_events, "sets", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1045
1046
+ RRDSET *st_pcharts = rrdset_create_localhost(
1047
+ "netdata"
1048
+ , "private_charts"
1049
+ , NULL
1050
+ , "statsd"
1051
+ , NULL
1052
+ , "Private metric charts created by the netdata statsd server"
1053
+ , "charts"
1054
+ , 132002
1055
+ , statsd.update_every
1056
+ , RRDSET_TYPE_AREA
1057
+ );
1058
+ RRDDIM *rd_pcharts = rrddim_add(st_pcharts, "charts", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1059
+
1060
usec_t step = statsd.update_every * USEC_PER_SEC;
1061
heartbeat_t hb;
1062
heartbeat_init(&hb);
1063
for(;;) {
1064
usec_t hb_dt = heartbeat_next(&hb, step);
1065
1066
+ if(unlikely(netdata_exit))
1067
+ break;
1068
+
1069
+ statsd_private_charts_from_index(&statsd.gauges, statsd_chart_from_gauge);
1070
+ statsd_private_charts_from_index(&statsd.counters, statsd_chart_from_counter);
1071
+ statsd_private_charts_from_index(&statsd.meters, statsd_chart_from_meter);
1072
+ statsd_private_charts_from_index(&statsd.timers, NULL);
1073
+ statsd_private_charts_from_index(&statsd.histograms, NULL);
1074
+ statsd_private_charts_from_index(&statsd.sets, statsd_chart_from_set);
1075
+
1076
if(unlikely(netdata_exit))
1077
break;
1078
1079
if(hb_dt) {
1080
rrdset_next(st_metrics);
1081
rrdset_next(st_events);
1082
+ rrdset_next(st_pcharts);
1083
}
1084
1085
rrddim_set_by_pointer(st_metrics, rd_metrics_gauge, (collected_number)statsd.gauges.metrics);
1096
rrddim_set_by_pointer(st_events, rd_events_histogram, (collected_number)statsd.histograms.events);
1097
rrddim_set_by_pointer(st_events, rd_events_set, (collected_number)statsd.sets.events);
1098
1099
+ rrddim_set_by_pointer(st_pcharts, rd_pcharts, (collected_number)statsd.private_charts);
1100
+
1101
if(unlikely(netdata_exit))
1102
break;
1103
1104
rrdset_done(st_metrics);
1105
rrdset_done(st_events);
1106
+ rrdset_done(st_pcharts);
1107
1108
if(unlikely(netdata_exit))
1109
break;
1017
-
1018
- statsd_charts_from_index(&statsd.gauges, statsd_chart_from_gauge);
1019
- statsd_charts_from_index(&statsd.counters, statsd_chart_from_counter);
1020
- statsd_charts_from_index(&statsd.meters, statsd_chart_from_meter);
1021
- statsd_charts_from_index(&statsd.timers, NULL);
1022
- statsd_charts_from_index(&statsd.histograms, NULL);
1023
- statsd_charts_from_index(&statsd.sets, statsd_chart_from_set);
1024
-
1110
}
1111
1112
for(i = 0; i < statsd.threads ;i++)