added the ability to define the value type on synthetic charts of statsd; fixes #1281
Costa Tsaousis (ktsaou) committed
May 12, 2017 at 23:03 UTC
c10d8c78089ff702a0187a4fc39835446c1dd4c9
3 files changed
+218
-61
conf.d/Makefile.am
+5
@@ -126,3 +126,8 @@ dist_chartsconfig_DATA = \
126
charts.d/postfix.conf \
127
charts.d/squid.conf \
128
$(NULL)
129
+
130
+statsdconfigdir=$(configdir)/statsd.d
131
+dist_statsdconfig_DATA = \
132
+ statsd.d/example.conf \
133
+ $(NULL)
conf.d/statsd.d/example.conf
new
+63
@@ -0,0 +1,63 @@
1
+# statsd synthetic charts configuration
2
+
3
+# You can add many .conf files, one for each of your apps
4
+
5
+# start a new app - you can add many apps in the same file
6
+[app]
7
+ # give a name for this app
8
+ # this controls the main menu on the dashboard
9
+ # and will be the prefix for all charts of the app
10
+ name = myapp
11
+
12
+ # match all the metrics of the app
13
+ metrics = myapp.*
14
+
15
+ # shall private charts of these metrics be created?
16
+ private charts = no
17
+
18
+ # shall gaps be shown when metrics are not collected?
19
+ gaps when not collected = no
20
+
21
+ # the memory mode for the charts of this app: none|map|save
22
+ memory mode = ram
23
+
24
+ # the history size for the charts of this app, in seconds
25
+ history = 60
26
+
27
+
28
+
29
+# create a chart
30
+# this is its id - the chart will be named myapp.mychart
31
+[mychart]
32
+ # a name for the chart, similar to the id (2 names for each chart)
33
+ name = mychart
34
+
35
+ # the chart title
36
+ title = my chart title
37
+
38
+ # the submenu of the dashboard
39
+ family = my family
40
+
41
+ # the context for alarm templates
42
+ context = chart.context
43
+
44
+ # the units of the chart
45
+ units = tests/s
46
+
47
+ # the sorting priority of the chart on the dashboard
48
+ priority = 91000
49
+
50
+ # the type of chart to create: line | area | stacked
51
+ type = area
52
+
53
+ # one or more dimensions for the chart
54
+ # type = events | last | min | max | sum | average | percentile | median | stddev
55
+ # events = the number of events for this metric
56
+ # last = the last value collected
57
+ # all the others are only valid for histograms and timers
58
+ dimension = myapp.metric1 avg average 1 1
59
+ dimension = myapp.metric1 lower min 1 1
60
+ dimension = myapp.metric1 upper max 1 1
61
+ dimension = myapp.metric2 other last 1 1
62
+
63
+# You can add as many charts as needed
src/statsd.c
+150
-61
@@ -30,6 +30,7 @@
30
#define STATSD_DICTIONARY_OPTIONS DICTIONARY_FLAG_SINGLE_THREADED
31
#endif
32
33
+#define STATSD_DECIMAL_DETAIL 1000 // floating point values get multiplied by this, with the same divider
34
35
// --------------------------------------------------------------------------------------------------------------------
36
// data specific to each metric type
@@ -43,31 +44,35 @@ typedef struct statsd_metric_counter { // counter and meter
44
} STATSD_METRIC_COUNTER;
45
46
typedef struct statsd_histogram_extensions {
46
- size_t size;
47
- size_t used;
47
+ netdata_mutex_t mutex;
48
+
49
+ // average is stored in metric->last
50
collected_number last_min;
51
collected_number last_max;
52
collected_number last_percentile;
53
collected_number last_median;
54
collected_number last_stddev;
55
collected_number last_sum;
56
+
57
RRDDIM *rd_min;
58
RRDDIM *rd_max;
59
RRDDIM *rd_percentile;
60
RRDDIM *rd_median;
61
RRDDIM *rd_stddev;
62
RRDDIM *rd_sum;
60
- long double values[]; // dynamic array of values collected
63
+
64
+ size_t size;
65
+ size_t used;
66
+ long double *values; // dynamic array of values collected
67
} STATSD_METRIC_HISTOGRAM_EXTENSIONS;
68
69
typedef struct statsd_metric_histogram { // histogram and timer
64
- netdata_mutex_t mutex;
70
STATSD_METRIC_HISTOGRAM_EXTENSIONS *ext;
71
} STATSD_METRIC_HISTOGRAM;
72
73
typedef struct statsd_metric_set {
74
DICTIONARY *dict;
70
- unsigned long long unique;
75
+ size_t unique;
76
} STATSD_METRIC_SET;
77
78
@@ -92,6 +97,7 @@ typedef enum statsd_metric_type {
97
STATSD_METRIC_TYPE_SET
98
} STATSD_METRIC_TYPE;
99
100
+
101
typedef struct statsd_metric {
102
avl avl; // indexing
103
@@ -101,7 +107,7 @@ typedef struct statsd_metric {
107
STATSD_METRIC_TYPE type;
108
109
// metadata about data collection
104
- size_t events; // the number of times this metric has been collected (never resets)
110
+ collected_number events; // the number of times this metric has been collected (never resets)
111
size_t count; // the number of times this metric has been collected since the last flush
112
113
// the actual collected data
@@ -146,16 +152,30 @@ static int statsd_metric_compare(void* a, void* b);
152
// --------------------------------------------------------------------------------------------------------------------
153
// synthetic charts
154
155
+typedef enum statsd_app_chart_dimension_value_type {
156
+ STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS,
157
+ STATSD_APP_CHART_DIM_VALUE_TYPE_LAST,
158
+ STATSD_APP_CHART_DIM_VALUE_TYPE_AVERAGE,
159
+ STATSD_APP_CHART_DIM_VALUE_TYPE_SUM,
160
+ STATSD_APP_CHART_DIM_VALUE_TYPE_MIN,
161
+ STATSD_APP_CHART_DIM_VALUE_TYPE_MAX,
162
+ STATSD_APP_CHART_DIM_VALUE_TYPE_PERCENTILE,
163
+ STATSD_APP_CHART_DIM_VALUE_TYPE_MEDIAN,
164
+ STATSD_APP_CHART_DIM_VALUE_TYPE_STDDEV
165
+} STATSD_APP_CHART_DIM_VALUE_TYPE;
166
+
167
typedef struct statsd_app_chart_dimension {
168
const char *name;
169
const char *metric;
170
uint32_t metric_hash;
171
collected_number multiplier;
172
collected_number divider;
155
- STATSD_INDEX *index;
173
+ STATSD_APP_CHART_DIM_VALUE_TYPE value_type;
174
157
- STATSD_METRIC *m;
175
RRDDIM *rd;
176
+ collected_number *value_ptr;
177
+ RRD_ALGORITHM algorithm;
178
+
179
struct statsd_app_chart_dimension *next;
180
} STATSD_APP_CHART_DIM;
181
@@ -186,7 +206,6 @@ typedef struct statsd_app {
206
207
const char *source;
208
STATSD_APP_CHART *charts;
189
- size_t charts_count;
209
struct statsd_app *next;
210
} STATSD_APP;
211
@@ -334,7 +353,7 @@ static inline STATSD_METRIC *statsd_find_or_add_metric(STATSD_INDEX *index, cons
353
354
if(type == STATSD_METRIC_TYPE_HISTOGRAM || type == STATSD_METRIC_TYPE_TIMER) {
355
m->histogram.ext = callocz(sizeof(STATSD_METRIC_HISTOGRAM_EXTENSIONS), 1);
337
- netdata_mutex_init(&m->histogram.mutex);
356
+ netdata_mutex_init(&m->histogram.ext->mutex);
357
}
358
STATSD_METRIC *n = (STATSD_METRIC *)STATSD_AVL_INSERT(&index->index, (avl *)m);
359
if(unlikely(n != m)) {
@@ -443,10 +462,10 @@ static inline void statsd_process_histogram(STATSD_METRIC *m, const char *value,
462
}
463
464
if(unlikely(m->histogram.ext->used == m->histogram.ext->size)) {
446
- netdata_mutex_lock(&m->histogram.mutex);
465
+ netdata_mutex_lock(&m->histogram.ext->mutex);
466
m->histogram.ext->size += statsd.histogram_increase_step;
448
- m->histogram.ext = reallocz(m->histogram.ext, sizeof(STATSD_METRIC_HISTOGRAM_EXTENSIONS) + (sizeof(long double) * m->histogram.ext->size));
449
- netdata_mutex_unlock(&m->histogram.mutex);
467
+ m->histogram.ext->values = reallocz(m->histogram.ext->values, sizeof(long double) * m->histogram.ext->size);
468
+ netdata_mutex_unlock(&m->histogram.ext->mutex);
469
}
470
471
m->histogram.ext->values[m->histogram.ext->used++] = statsd_parse_float(value, 1.0) / statsd_parse_float(sampling, 1.0);
@@ -1082,14 +1101,15 @@ int statsd_readfile(const char *path, const char *filename) {
1101
chart->chart_type = rrdset_type_id(value);
1102
}
1103
else if (!strcmp(name, "dimension")) {
1085
- // metric [name [multiplier [divider]]]
1086
- char *words[4];
1087
- pluginsd_split_words(value, words, 4);
1104
+ // metric [name [type [multiplier [divider]]]]
1105
+ char *words[5];
1106
+ pluginsd_split_words(value, words, 5);
1107
1108
char *metric_name = words[0];
1109
char *dim_name = words[1];
1091
- char *multipler = words[2];
1092
- char *divider = words[3];
1110
+ char *type = words[2];
1111
+ char *multipler = words[3];
1112
+ char *divider = words[4];
1113
1114
STATSD_APP_CHART_DIM *dim = callocz(sizeof(STATSD_APP_CHART_DIM), 1);
1115
dim->next = chart->dimensions;
@@ -1103,6 +1123,21 @@ int statsd_readfile(const char *path, const char *filename) {
1123
dim->multiplier = (multipler && *multipler)?str2l(multipler):1;
1124
dim->divider = (divider && *divider)?str2l(divider):1;
1125
1126
+ if(!type || !*type) type = "last";
1127
+ if(!strcmp(type, "events")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS;
1128
+ else if(!strcmp(type, "last")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_LAST;
1129
+ else if(!strcmp(type, "min")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_MIN;
1130
+ else if(!strcmp(type, "max")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_MAX;
1131
+ else if(!strcmp(type, "sum")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_SUM;
1132
+ else if(!strcmp(type, "average")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_AVERAGE;
1133
+ else if(!strcmp(type, "median")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_MEDIAN;
1134
+ else if(!strcmp(type, "stddev")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_STDDEV;
1135
+ else if(!strcmp(type, "percentile")) dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_PERCENTILE;
1136
+ else {
1137
+ error("STATSD: invalid type '%s' at line %zu of file '%s/%s'. Using 'last'.", type, line, path, filename);
1138
+ dim->value_type = STATSD_APP_CHART_DIM_VALUE_TYPE_LAST;
1139
+ }
1140
+
1141
if(!dim->multiplier) {
1142
error("STATSD: invalid multiplier value '%s' at line %zu of file '%s/%s'. Using 1.", multipler, line, path, filename);
1143
dim->multiplier = 1;
@@ -1253,7 +1288,7 @@ static inline void statsd_private_chart_gauge(STATSD_METRIC *m) {
1288
, RRDSET_TYPE_LINE
1289
);
1290
1256
- m->rd_value = rrddim_add(m->st, "gauge", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
1291
+ m->rd_value = rrddim_add(m->st, "gauge", NULL, 1, STATSD_DECIMAL_DETAIL, RRD_ALGORITHM_ABSOLUTE);
1292
1293
if(m->options & STATSD_METRIC_OPTION_CHART_DIMENSION_COUNT)
1294
m->rd_count = rrddim_add(m->st, "events", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1263,7 +1298,7 @@ static inline void statsd_private_chart_gauge(STATSD_METRIC *m) {
1298
rrddim_set_by_pointer(m->st, m->rd_value, m->last);
1299
1300
if(m->rd_count)
1266
- rrddim_set_by_pointer(m->st, m->rd_count, (collected_number)m->events);
1301
+ rrddim_set_by_pointer(m->st, m->rd_count, m->events);
1302
1303
rrdset_done(m->st);
1304
}
@@ -1299,7 +1334,7 @@ static inline void statsd_private_chart_counter_or_meter(STATSD_METRIC *m, const
1334
rrddim_set_by_pointer(m->st, m->rd_value, m->last);
1335
1336
if(m->rd_count)
1302
- rrddim_set_by_pointer(m->st, m->rd_count, (collected_number)m->events);
1337
+ rrddim_set_by_pointer(m->st, m->rd_count, m->events);
1338
1339
rrdset_done(m->st);
1340
}
@@ -1335,7 +1370,7 @@ static inline void statsd_private_chart_set(STATSD_METRIC *m) {
1370
rrddim_set_by_pointer(m->st, m->rd_value, m->last);
1371
1372
if(m->rd_count)
1338
- rrddim_set_by_pointer(m->st, m->rd_count, (collected_number)m->events);
1373
+ rrddim_set_by_pointer(m->st, m->rd_count, m->events);
1374
1375
rrdset_done(m->st);
1376
}
@@ -1361,13 +1396,13 @@ static inline void statsd_private_chart_timer_or_histogram(STATSD_METRIC *m, con
1396
, RRDSET_TYPE_AREA
1397
);
1398
1364
- m->histogram.ext->rd_min = rrddim_add(m->st, "min", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
1365
- m->histogram.ext->rd_max = rrddim_add(m->st, "max", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
1366
- m->rd_value = rrddim_add(m->st, "average", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
1367
- m->histogram.ext->rd_percentile = rrddim_add(m->st, statsd.histogram_percentile_str, NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
1368
- m->histogram.ext->rd_median = rrddim_add(m->st, "median", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
1369
- m->histogram.ext->rd_stddev = rrddim_add(m->st, "stddev", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
1370
- m->histogram.ext->rd_sum = rrddim_add(m->st, "sum", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
1399
+ m->histogram.ext->rd_min = rrddim_add(m->st, "min", NULL, 1, STATSD_DECIMAL_DETAIL, RRD_ALGORITHM_ABSOLUTE);
1400
+ m->histogram.ext->rd_max = rrddim_add(m->st, "max", NULL, 1, STATSD_DECIMAL_DETAIL, RRD_ALGORITHM_ABSOLUTE);
1401
+ m->rd_value = rrddim_add(m->st, "average", NULL, 1, STATSD_DECIMAL_DETAIL, RRD_ALGORITHM_ABSOLUTE);
1402
+ m->histogram.ext->rd_percentile = rrddim_add(m->st, statsd.histogram_percentile_str, NULL, 1, STATSD_DECIMAL_DETAIL, RRD_ALGORITHM_ABSOLUTE);
1403
+ m->histogram.ext->rd_median = rrddim_add(m->st, "median", NULL, 1, STATSD_DECIMAL_DETAIL, RRD_ALGORITHM_ABSOLUTE);
1404
+ m->histogram.ext->rd_stddev = rrddim_add(m->st, "stddev", NULL, 1, STATSD_DECIMAL_DETAIL, RRD_ALGORITHM_ABSOLUTE);
1405
+ m->histogram.ext->rd_sum = rrddim_add(m->st, "sum", NULL, 1, STATSD_DECIMAL_DETAIL, RRD_ALGORITHM_ABSOLUTE);
1406
1407
if(m->options & STATSD_METRIC_OPTION_CHART_DIMENSION_COUNT)
1408
m->rd_count = rrddim_add(m->st, "events", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -1383,7 +1418,7 @@ static inline void statsd_private_chart_timer_or_histogram(STATSD_METRIC *m, con
1418
rrddim_set_by_pointer(m->st, m->rd_value, m->last);
1419
1420
if(m->rd_count)
1386
- rrddim_set_by_pointer(m->st, m->rd_count, (collected_number)m->events);
1421
+ rrddim_set_by_pointer(m->st, m->rd_count, m->events);
1422
1423
rrdset_done(m->st);
1424
}
@@ -1396,7 +1431,7 @@ static inline void statsd_flush_gauge(STATSD_METRIC *m) {
1431
1432
int updated = 0;
1433
if(m->count && !m->reset) {
1399
- m->last = (collected_number) (m->gauge.value * 1000.0);
1434
+ m->last = (collected_number) (m->gauge.value * STATSD_DECIMAL_DETAIL);
1435
1436
m->reset = 1;
1437
updated = 1;
@@ -1434,7 +1469,7 @@ static inline void statsd_flush_set(STATSD_METRIC *m) {
1469
1470
int updated = 0;
1471
if(m->count && !m->reset) {
1437
- m->last = m->set.unique;
1472
+ m->last = (collected_number)m->set.unique;
1473
1474
m->reset = 1;
1475
updated = 1;
@@ -1447,7 +1482,7 @@ static inline void statsd_flush_set(STATSD_METRIC *m) {
1482
static inline void statsd_flush_timer_or_histogram(STATSD_METRIC *m, const char *dim, const char *family, const char *units) {
1483
debug(D_STATSD, "flushing %s metric '%s'", dim, m->name);
1484
1450
- netdata_mutex_lock(&m->histogram.mutex);
1485
+ netdata_mutex_lock(&m->histogram.ext->mutex);
1486
1487
int updated = 0;
1488
if(m->count && !m->reset) {
@@ -1455,13 +1490,13 @@ static inline void statsd_flush_timer_or_histogram(STATSD_METRIC *m, const char
1490
long double *series = m->histogram.ext->values;
1491
sort_series(series, len);
1492
1458
- m->histogram.ext->last_min = (collected_number)roundl(series[0] * 1000);
1459
- m->histogram.ext->last_max = (collected_number)roundl(series[len - 1] * 1000);
1460
- m->last = (collected_number)roundl(average(series, len) * 1000);
1461
- m->histogram.ext->last_percentile = (collected_number)roundl(average(series, (size_t)floor((double)len * statsd.histogram_percentile / 100.0)) * 1000);
1462
- m->histogram.ext->last_median = (collected_number)roundl(median_on_sorted_series(series, len) * 1000);
1463
- m->histogram.ext->last_stddev = (collected_number)roundl(standard_deviation(series, len) * 1000);
1464
- m->histogram.ext->last_sum = (collected_number)roundl(sum(series, len) * 1000);
1493
+ m->histogram.ext->last_min = (collected_number)roundl(series[0] * STATSD_DECIMAL_DETAIL);
1494
+ m->histogram.ext->last_max = (collected_number)roundl(series[len - 1] * STATSD_DECIMAL_DETAIL);
1495
+ m->last = (collected_number)roundl(average(series, len) * STATSD_DECIMAL_DETAIL);
1496
+ m->histogram.ext->last_percentile = (collected_number)roundl(average(series, (size_t)floor((double)len * statsd.histogram_percentile / 100.0)) * STATSD_DECIMAL_DETAIL);
1497
+ m->histogram.ext->last_median = (collected_number)roundl(median_on_sorted_series(series, len) * STATSD_DECIMAL_DETAIL);
1498
+ m->histogram.ext->last_stddev = (collected_number)roundl(standard_deviation(series, len) * STATSD_DECIMAL_DETAIL);
1499
+ m->histogram.ext->last_sum = (collected_number)roundl(sum(series, len) * STATSD_DECIMAL_DETAIL);
1500
1501
m->reset = 1;
1502
updated = 1;
@@ -1471,7 +1506,7 @@ static inline void statsd_flush_timer_or_histogram(STATSD_METRIC *m, const char
1506
if(m->options & STATSD_METRIC_OPTION_PRIVATE_CHART_ENABLED && (updated || !(m->options & STATSD_METRIC_OPTION_SHOW_GAPS_WHEN_NOT_COLLECTED)))
1507
statsd_private_chart_timer_or_histogram(m, dim, family, units);
1508
1474
- netdata_mutex_unlock(&m->histogram.mutex);
1509
+ netdata_mutex_unlock(&m->histogram.ext->mutex);
1510
}
1511
1512
static inline void statsd_flush_timer(STATSD_METRIC *m) {
@@ -1482,6 +1517,21 @@ static inline void statsd_flush_histogram(STATSD_METRIC *m) {
1517
statsd_flush_timer_or_histogram(m, "histogram", "histograms", "value");
1518
}
1519
1520
+static inline RRD_ALGORITHM statsd_algorithm_for_metric(STATSD_METRIC *m) {
1521
+ switch(m->type) {
1522
+ default:
1523
+ case STATSD_METRIC_TYPE_GAUGE:
1524
+ case STATSD_METRIC_TYPE_SET:
1525
+ case STATSD_METRIC_TYPE_TIMER:
1526
+ case STATSD_METRIC_TYPE_HISTOGRAM:
1527
+ return RRD_ALGORITHM_ABSOLUTE;
1528
+
1529
+ case STATSD_METRIC_TYPE_METER:
1530
+ case STATSD_METRIC_TYPE_COUNTER:
1531
+ return RRD_ALGORITHM_INCREMENTAL;
1532
+ }
1533
+}
1534
+
1535
static inline void check_if_metric_is_for_app(STATSD_INDEX *index, STATSD_METRIC *m) {
1536
(void)index;
1537
@@ -1509,10 +1559,64 @@ static inline void check_if_metric_is_for_app(STATSD_INDEX *index, STATSD_METRIC
1559
for(chart = app->charts; chart; chart = chart->next) {
1560
STATSD_APP_CHART_DIM *dim;
1561
for(dim = chart->dimensions; dim ; dim = dim->next) {
1512
- if(!dim->m && dim->metric_hash == m->hash && !strcmp(dim->metric, m->name)) {
1562
+ if(!dim->value_ptr && dim->metric_hash == m->hash && !strcmp(dim->metric, m->name)) {
1563
// we have a match - this metric should be linked to this dimension
1564
debug(D_STATSD, "metric '%s' linked with app '%s', chart '%s', dimension '%s'", m->name, app->name, chart->id, dim->name);
1515
- dim->m = m;
1565
+
1566
+ if(dim->value_type == STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS) {
1567
+ dim->value_ptr = &m->events;
1568
+ dim->algorithm = RRD_ALGORITHM_INCREMENTAL;
1569
+ }
1570
+ else if(m->type == STATSD_METRIC_TYPE_HISTOGRAM || m->type == STATSD_METRIC_TYPE_TIMER) {
1571
+ dim->algorithm = RRD_ALGORITHM_ABSOLUTE;
1572
+ dim->divider *= STATSD_DECIMAL_DETAIL;
1573
+
1574
+ switch(dim->value_type) {
1575
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_EVENTS:
1576
+ // will never match - added to avoid warning
1577
+ break;
1578
+
1579
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_LAST:
1580
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_AVERAGE:
1581
+ dim->value_ptr = &m->last;
1582
+ break;
1583
+
1584
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_SUM:
1585
+ dim->value_ptr = &m->histogram.ext->last_sum;
1586
+ break;
1587
+
1588
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_MIN:
1589
+ dim->value_ptr = &m->histogram.ext->last_min;
1590
+ break;
1591
+
1592
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_MAX:
1593
+ dim->value_ptr = &m->histogram.ext->last_max;
1594
+ break;
1595
+
1596
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_MEDIAN:
1597
+ dim->value_ptr = &m->histogram.ext->last_median;
1598
+ break;
1599
+
1600
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_PERCENTILE:
1601
+ dim->value_ptr = &m->histogram.ext->last_percentile;
1602
+ break;
1603
+
1604
+ case STATSD_APP_CHART_DIM_VALUE_TYPE_STDDEV:
1605
+ dim->value_ptr = &m->histogram.ext->last_stddev;
1606
+ break;
1607
+ }
1608
+ }
1609
+ else {
1610
+ if (dim->value_type != STATSD_APP_CHART_DIM_VALUE_TYPE_LAST)
1611
+ error("STATSD: unsupported value type for dimension '%s' of chart '%s' of app '%s' on metric '%s'", dim->name, chart->name, app->name, m->name);
1612
+
1613
+ dim->value_ptr = &m->last;
1614
+ dim->algorithm = statsd_algorithm_for_metric(m);
1615
+
1616
+ if(m->type == STATSD_METRIC_TYPE_GAUGE)
1617
+ dim->divider *= STATSD_DECIMAL_DETAIL;
1618
+ }
1619
+
1620
chart->dimensions_linked_count++;
1621
}
1622
}
@@ -1521,21 +1625,6 @@ static inline void check_if_metric_is_for_app(STATSD_INDEX *index, STATSD_METRIC
1625
}
1626
}
1627
1524
-static inline RRD_ALGORITHM statsd_algorithm_for_metric(STATSD_METRIC *m) {
1525
- switch(m->type) {
1526
- default:
1527
- case STATSD_METRIC_TYPE_GAUGE:
1528
- case STATSD_METRIC_TYPE_SET:
1529
- case STATSD_METRIC_TYPE_TIMER:
1530
- case STATSD_METRIC_TYPE_HISTOGRAM:
1531
- return RRD_ALGORITHM_ABSOLUTE;
1532
-
1533
- case STATSD_METRIC_TYPE_METER:
1534
- case STATSD_METRIC_TYPE_COUNTER:
1535
- return RRD_ALGORITHM_INCREMENTAL;
1536
- }
1537
-}
1538
-
1628
static inline void statsd_update_app_chart(STATSD_APP *app, STATSD_APP_CHART *chart) {
1629
debug(D_STATSD, "updating chart '%s' for app '%s'", chart->id, app->name);
1630
@@ -1560,11 +1649,11 @@ static inline void statsd_update_app_chart(STATSD_APP *app, STATSD_APP_CHART *ch
1649
1650
STATSD_APP_CHART_DIM *dim;
1651
for(dim = chart->dimensions; dim ;dim = dim->next) {
1563
- if(dim->m) {
1652
+ if(dim->value_ptr) {
1653
if(unlikely(!dim->rd))
1565
- dim->rd = rrddim_add(chart->st, dim->metric, dim->name, dim->multiplier, dim->divider,statsd_algorithm_for_metric(dim->m));
1654
+ dim->rd = rrddim_add(chart->st, dim->metric, dim->name, dim->multiplier, dim->divider, dim->algorithm);
1655
1567
- rrddim_set_by_pointer(chart->st, dim->rd, dim->m->last);
1656
+ rrddim_set_by_pointer(chart->st, dim->rd, *dim->value_ptr);
1657
}
1658
}
1659