Show internal stats for the exporting engine (#8635)
* Add a print function for internal exporting statistics * Send statistics for simple connectors * Flush sending buffers on failures * Send statistics for the Kinesis connector * Send statistics for the MongoDB connector * Add unit tests
Vladimir Kobal committed
Apr 10, 2020 at 12:26 UTC
231d19351d0ea20aa66fd204215cbb24f34d7575
18 files changed
+765
-79
CMakeLists.txt
+2
@@ -1112,6 +1112,8 @@ endif()
1112
-Wl,--wrap=recv
1113
-Wl,--wrap=send
1114
-Wl,--wrap=connect_to_one_of
1115
+ -Wl,--wrap=create_main_rusage_chart
1116
+ -Wl,--wrap=send_main_rusage
1117
${PROMETHEUS_REMOTE_WRITE_LINK_OPTIONS}
1118
${KINESIS_LINK_OPTIONS}
1119
${MONGODB_LINK_OPTIONS}
Makefile.am
+2
@@ -873,6 +873,8 @@ if ENABLE_UNITTESTS
873
-Wl,--wrap=recv \
874
-Wl,--wrap=send \
875
-Wl,--wrap=connect_to_one_of \
876
+ -Wl,--wrap=create_main_rusage_chart \
877
+ -Wl,--wrap=send_main_rusage \
878
$(TEST_LDFLAGS) \
879
$(NULL)
880
exporting_tests_exporting_engine_testdriver_LDADD = $(NETDATA_COMMON_LIBS) $(TEST_LIBS)
exporting/aws_kinesis/aws_kinesis.c
+27
-9
@@ -75,9 +75,23 @@ void aws_kinesis_connector_worker(void *instance_p)
75
uv_mutex_lock(&instance->mutex);
76
uv_cond_wait(&instance->cond_var, &instance->mutex);
77
78
+ // reset the monitoring chart counters
79
+ stats->received_bytes =
80
+ stats->sent_bytes =
81
+ stats->sent_metrics =
82
+ stats->lost_metrics =
83
+ stats->receptions =
84
+ stats->transmission_successes =
85
+ stats->transmission_failures =
86
+ stats->data_lost_events =
87
+ stats->lost_bytes =
88
+ stats->reconnects = 0;
89
+
90
BUFFER *buffer = (BUFFER *)instance->buffer;
91
size_t buffer_len = buffer_strlen(buffer);
92
93
+ stats->buffered_bytes = buffer_len;
94
+
95
size_t sent = 0;
96
97
while (sent < buffer_len) {
@@ -115,7 +129,7 @@ void aws_kinesis_connector_worker(void *instance_p)
129
connector_specific_data, connector_specific_config->stream_name, partition_key, first_char, record_len);
130
131
sent += record_len;
118
- stats->chart_transmission_successes++;
132
+ stats->transmission_successes++;
133
134
size_t sent_bytes = 0, lost_bytes = 0;
135
@@ -127,30 +141,34 @@ void aws_kinesis_connector_worker(void *instance_p)
141
"EXPORTING: failed to write data to database backend '%s'. Willing to write %zu bytes, wrote %zu bytes.",
142
instance->config.destination, sent_bytes, sent_bytes - lost_bytes);
143
130
- stats->chart_transmission_failures++;
131
- stats->chart_data_lost_events++;
132
- stats->chart_lost_bytes += lost_bytes;
144
+ stats->transmission_failures++;
145
+ stats->data_lost_events++;
146
+ stats->lost_bytes += lost_bytes;
147
148
// estimate the number of lost metrics
135
- stats->chart_lost_metrics += (collected_number)(
136
- stats->chart_buffered_metrics *
149
+ stats->lost_metrics += (collected_number)(
150
+ stats->buffered_metrics *
151
(buffer_len && (lost_bytes > buffer_len) ? (double)lost_bytes / buffer_len : 1));
152
153
break;
154
} else {
141
- stats->chart_receptions++;
155
+ stats->receptions++;
156
}
157
158
if (unlikely(netdata_exit))
159
break;
160
}
161
148
- stats->chart_sent_bytes += sent;
162
+ stats->sent_bytes += sent;
163
if (likely(sent == buffer_len))
150
- stats->chart_sent_metrics = stats->chart_buffered_metrics;
164
+ stats->sent_metrics = stats->buffered_metrics;
165
166
buffer_flush(buffer);
167
168
+ send_internal_metrics(instance);
169
+
170
+ stats->buffered_metrics = 0;
171
+
172
uv_mutex_unlock(&instance->mutex);
173
174
#ifdef UNIT_TESTING
exporting/exporting_engine.c
+6
-4
@@ -35,6 +35,11 @@ void *exporting_main(void *ptr)
35
goto cleanup;
36
}
37
38
+ RRDSET *st_main_rusage = NULL;
39
+ RRDDIM *rd_main_user = NULL;
40
+ RRDDIM *rd_main_system = NULL;
41
+ create_main_rusage_chart(&st_main_rusage, &rd_main_user, &rd_main_system);
42
+
43
usec_t step_ut = localhost->rrd_update_every * USEC_PER_SEC;
44
heartbeat_t hb;
45
heartbeat_init(&hb);
@@ -55,10 +60,7 @@ void *exporting_main(void *ptr)
60
break;
61
}
62
58
- if (send_internal_metrics(engine) != 0) {
59
- error("EXPORTING: cannot send metrics for the operation of exporting engine");
60
- break;
61
- }
63
+ send_main_rusage(st_main_rusage, rd_main_user, rd_main_system);
64
65
#ifdef UNIT_TESTING
66
break;
exporting/exporting_engine.h
+40
-13
@@ -99,18 +99,42 @@ struct engine_config {
99
};
100
101
struct stats {
102
- collected_number chart_buffered_metrics;
103
- collected_number chart_lost_metrics;
104
- collected_number chart_sent_metrics;
105
- collected_number chart_buffered_bytes;
106
- collected_number chart_received_bytes;
107
- collected_number chart_sent_bytes;
108
- collected_number chart_receptions;
109
- collected_number chart_transmission_successes;
110
- collected_number chart_transmission_failures;
111
- collected_number chart_data_lost_events;
112
- collected_number chart_lost_bytes;
113
- collected_number chart_reconnects;
102
+ collected_number buffered_metrics;
103
+ collected_number lost_metrics;
104
+ collected_number sent_metrics;
105
+ collected_number buffered_bytes;
106
+ collected_number lost_bytes;
107
+ collected_number sent_bytes;
108
+ collected_number received_bytes;
109
+ collected_number transmission_successes;
110
+ collected_number data_lost_events;
111
+ collected_number reconnects;
112
+ collected_number transmission_failures;
113
+ collected_number receptions;
114
+
115
+ int initialized;
116
+
117
+ RRDSET *st_metrics;
118
+ RRDDIM *rd_buffered_metrics;
119
+ RRDDIM *rd_lost_metrics;
120
+ RRDDIM *rd_sent_metrics;
121
+
122
+ RRDSET *st_bytes;
123
+ RRDDIM *rd_buffered_bytes;
124
+ RRDDIM *rd_lost_bytes;
125
+ RRDDIM *rd_sent_bytes;
126
+ RRDDIM *rd_received_bytes;
127
+
128
+ RRDSET *st_ops;
129
+ RRDDIM *rd_transmission_successes;
130
+ RRDDIM *rd_data_lost_events;
131
+ RRDDIM *rd_reconnects;
132
+ RRDDIM *rd_transmission_failures;
133
+ RRDDIM *rd_receptions;
134
+
135
+ RRDSET *st_rusage;
136
+ RRDDIM *rd_user;
137
+ RRDDIM *rd_system;
138
};
139
140
struct instance {
@@ -193,13 +217,16 @@ int end_chart_formatting(struct engine *engine, RRDSET *st);
217
int end_host_formatting(struct engine *engine, RRDHOST *host);
218
int end_batch_formatting(struct engine *engine);
219
int flush_host_labels(struct instance *instance, RRDHOST *host);
220
+int simple_connector_update_buffered_bytes(struct instance *instance);
221
222
int exporting_discard_response(BUFFER *buffer, struct instance *instance);
223
void simple_connector_receive_response(int *sock, struct instance *instance);
224
void simple_connector_send_buffer(int *sock, int *failures, struct instance *instance);
225
void simple_connector_worker(void *instance_p);
226
202
-int send_internal_metrics(struct engine *engine);
227
+void create_main_rusage_chart(RRDSET **st_rusage, RRDDIM **rd_user, RRDDIM **rd_system);
228
+void send_main_rusage(RRDSET *st_rusage, RRDDIM *rd_user, RRDDIM *rd_system);
229
+void send_internal_metrics(struct instance *instance);
230
231
#include "exporting/prometheus/prometheus.h"
232
exporting/graphite/graphite.c
+1
-1
@@ -27,7 +27,7 @@ int init_graphite_instance(struct instance *instance)
27
28
instance->end_chart_formatting = NULL;
29
instance->end_host_formatting = flush_host_labels;
30
- instance->end_batch_formatting = NULL;
30
+ instance->end_batch_formatting = simple_connector_update_buffered_bytes;
31
32
instance->send_header = NULL;
33
instance->check_response = exporting_discard_response;
exporting/json/json.c
+1
-1
@@ -27,7 +27,7 @@ int init_json_instance(struct instance *instance)
27
28
instance->end_chart_formatting = NULL;
29
instance->end_host_formatting = flush_host_labels;
30
- instance->end_batch_formatting = NULL;
30
+ instance->end_batch_formatting = simple_connector_update_buffered_bytes;
31
32
instance->send_header = NULL;
33
instance->check_response = exporting_discard_response;
exporting/mongodb/mongodb.c
+48
-12
@@ -183,8 +183,10 @@ int format_batch_mongodb(struct instance *instance)
183
// ring buffer is full, reuse the oldest element
184
connector_specific_data->first_buffer = connector_specific_data->first_buffer->next;
185
free_bson(insert, connector_specific_data->last_buffer->documents_inserted);
186
+ connector_specific_data->total_documents_inserted -= connector_specific_data->last_buffer->documents_inserted;
187
+ stats->buffered_bytes -= connector_specific_data->last_buffer->buffered_bytes;
188
}
187
- insert = callocz((size_t)stats->chart_buffered_metrics, sizeof(bson_t *));
189
+ insert = callocz((size_t)stats->buffered_metrics, sizeof(bson_t *));
190
connector_specific_data->last_buffer->insert = insert;
191
192
BUFFER *buffer = (BUFFER *)instance->buffer;
@@ -193,7 +195,7 @@ int format_batch_mongodb(struct instance *instance)
195
196
size_t documents_inserted = 0;
197
196
- while (*end && documents_inserted <= (size_t)stats->chart_buffered_metrics) {
198
+ while (*end && documents_inserted <= (size_t)stats->buffered_metrics) {
199
while (*end && *end != '\n')
200
end++;
201
@@ -208,7 +210,8 @@ int format_batch_mongodb(struct instance *instance)
210
insert[documents_inserted] = bson_new_from_json((const uint8_t *)start, -1, &bson_error);
211
212
if (unlikely(!insert[documents_inserted])) {
211
- error("EXPORTING: Failed creating a BSON document from a JSON string \"%s\" : %s", start, bson_error.message);
213
+ error(
214
+ "EXPORTING: Failed creating a BSON document from a JSON string \"%s\" : %s", start, bson_error.message);
215
free_bson(insert, documents_inserted);
216
return 1;
217
}
@@ -218,8 +221,16 @@ int format_batch_mongodb(struct instance *instance)
221
documents_inserted++;
222
}
223
224
+ stats->buffered_bytes += connector_specific_data->last_buffer->buffered_bytes = buffer_strlen(buffer);
225
+
226
buffer_flush(buffer);
227
228
+ // The stats->buffered_metrics is used in the MongoDB batch formatting as a variable for the number
229
+ // of metrics, added in the current iteration, so we are clearing it here. We will use the
230
+ // connector_specific_data->total_documents_inserted in the worker to show the statistics.
231
+ stats->buffered_metrics = 0;
232
+ connector_specific_data->total_documents_inserted += documents_inserted;
233
+
234
connector_specific_data->last_buffer->documents_inserted = documents_inserted;
235
connector_specific_data->last_buffer = connector_specific_data->last_buffer->next;
236
@@ -246,11 +257,25 @@ void mongodb_connector_worker(void *instance_p)
257
uv_mutex_lock(&instance->mutex);
258
uv_cond_wait(&instance->cond_var, &instance->mutex);
259
260
+ // reset the monitoring chart counters
261
+ stats->received_bytes =
262
+ stats->sent_bytes =
263
+ stats->sent_metrics =
264
+ stats->lost_metrics =
265
+ stats->receptions =
266
+ stats->transmission_successes =
267
+ stats->transmission_failures =
268
+ stats->data_lost_events =
269
+ stats->lost_bytes =
270
+ stats->reconnects = 0;
271
+
272
bson_t **insert = connector_specific_data->first_buffer->insert;
273
size_t documents_inserted = connector_specific_data->first_buffer->documents_inserted;
274
+ size_t buffered_bytes = connector_specific_data->first_buffer->buffered_bytes;
275
276
connector_specific_data->first_buffer->insert = NULL;
277
connector_specific_data->first_buffer->documents_inserted = 0;
278
+ connector_specific_data->first_buffer->buffered_bytes = 0;
279
connector_specific_data->first_buffer = connector_specific_data->first_buffer->next;
280
281
uv_mutex_unlock(&instance->mutex);
@@ -279,9 +304,10 @@ void mongodb_connector_worker(void *instance_p)
304
NULL,
305
NULL,
306
&bson_error))) {
282
- stats->chart_sent_bytes += data_size;
283
- stats->chart_transmission_successes++;
284
- stats->chart_receptions++;
307
+ stats->sent_metrics = documents_inserted;
308
+ stats->sent_bytes += data_size;
309
+ stats->transmission_successes++;
310
+ stats->receptions++;
311
} else {
312
// oops! we couldn't send (all or some of the) data
313
error("EXPORTING: %s", bson_error.message);
@@ -290,10 +316,10 @@ void mongodb_connector_worker(void *instance_p)
316
"Willing to write %zu bytes, wrote %zu bytes.",
317
instance->config.destination, data_size, 0UL);
318
293
- stats->chart_transmission_failures++;
294
- stats->chart_data_lost_events++;
295
- stats->chart_lost_bytes += data_size;
296
- stats->chart_lost_metrics += stats->chart_buffered_metrics;
319
+ stats->transmission_failures++;
320
+ stats->data_lost_events++;
321
+ stats->lost_bytes += buffered_bytes;
322
+ stats->lost_metrics += documents_inserted;
323
}
324
325
free_bson(insert, documents_inserted);
@@ -301,8 +327,18 @@ void mongodb_connector_worker(void *instance_p)
327
if (unlikely(netdata_exit))
328
break;
329
304
- stats->chart_sent_bytes += data_size;
305
- stats->chart_sent_metrics = stats->chart_buffered_metrics;
330
+ uv_mutex_lock(&instance->mutex);
331
+
332
+ stats->buffered_metrics = connector_specific_data->total_documents_inserted;
333
+
334
+ send_internal_metrics(instance);
335
+
336
+ connector_specific_data->total_documents_inserted -= documents_inserted;
337
+
338
+ stats->buffered_metrics = 0;
339
+ stats->buffered_bytes -= buffered_bytes;
340
+
341
+ uv_mutex_unlock(&instance->mutex);
342
343
#ifdef UNIT_TESTING
344
break;
exporting/mongodb/mongodb.h
+3
@@ -10,6 +10,7 @@
10
struct bson_buffer {
11
bson_t **insert;
12
size_t documents_inserted;
13
+ size_t buffered_bytes;
14
15
struct bson_buffer *next;
16
};
@@ -18,6 +19,8 @@ struct mongodb_specific_data {
19
mongoc_client_t *client;
20
mongoc_collection_t *collection;
21
22
+ size_t total_documents_inserted;
23
+
24
bson_t **current_insert;
25
struct bson_buffer *first_buffer;
26
struct bson_buffer *last_buffer;
exporting/opentsdb/opentsdb.c
+2
-2
@@ -27,7 +27,7 @@ int init_opentsdb_telnet_instance(struct instance *instance)
27
28
instance->end_chart_formatting = NULL;
29
instance->end_host_formatting = flush_host_labels;
30
- instance->end_batch_formatting = NULL;
30
+ instance->end_batch_formatting = simple_connector_update_buffered_bytes;
31
32
instance->send_header = NULL;
33
instance->check_response = exporting_discard_response;
@@ -68,7 +68,7 @@ int init_opentsdb_http_instance(struct instance *instance)
68
69
instance->end_chart_formatting = NULL;
70
instance->end_host_formatting = flush_host_labels;
71
- instance->end_batch_formatting = NULL;
71
+ instance->end_batch_formatting = simple_connector_update_buffered_bytes;
72
73
instance->send_header = NULL;
74
instance->check_response = exporting_discard_response;
exporting/process_data.c
+14
-1
@@ -242,7 +242,7 @@ int metric_formatting(struct engine *engine, RRDDIM *rd)
242
error("EXPORTING: cannot format metric for %s", instance->config.name);
243
return 1;
244
}
245
- instance->stats.chart_buffered_metrics++;
245
+ instance->stats.buffered_metrics++;
246
}
247
}
248
@@ -389,6 +389,19 @@ int flush_host_labels(struct instance *instance, RRDHOST *host)
389
return 0;
390
}
391
392
+/**
393
+ * Update stats for buffered bytes
394
+ *
395
+ * @param instance an instance data structure.
396
+ * @return Always returns 0.
397
+ */
398
+int simple_connector_update_buffered_bytes(struct instance *instance)
399
+{
400
+ instance->stats.buffered_bytes = (collected_number)buffer_strlen((BUFFER *)(instance->buffer));
401
+
402
+ return 0;
403
+}
404
+
405
/**
406
* Notify workers
407
*
exporting/prometheus/remote_write/remote_write.c
+1
-1
@@ -314,7 +314,7 @@ int format_batch_prometheus_remote_write(struct instance *instance)
314
return 1;
315
}
316
buffer->len = data_size;
317
- instance->stats.chart_buffered_bytes = (collected_number)buffer_strlen(buffer);
317
+ instance->stats.buffered_bytes = (collected_number)buffer_strlen(buffer);
318
319
return 0;
320
}
exporting/send_data.c
+41
-9
@@ -57,8 +57,8 @@ void simple_connector_receive_response(int *sock, struct instance *instance)
57
if (likely(r > 0)) {
58
// we received some data
59
response->len += r;
60
- stats->chart_received_bytes += r;
61
- stats->chart_receptions++;
60
+ stats->received_bytes += r;
61
+ stats->receptions++;
62
} else if (r == 0) {
63
error("EXPORTING: '%s' closed the socket", instance->config.destination);
64
close(*sock);
@@ -109,9 +109,9 @@ void simple_connector_send_buffer(int *sock, int *failures, struct instance *ins
109
110
if(written != -1 && (size_t)written == len) {
111
// we sent the data successfully
112
- stats->chart_transmission_successes++;
113
- stats->chart_sent_bytes += written;
114
- stats->chart_sent_metrics = stats->chart_buffered_metrics;
112
+ stats->transmission_successes++;
113
+ stats->sent_bytes += written;
114
+ stats->sent_metrics = stats->buffered_metrics;
115
116
// reset the failures count
117
*failures = 0;
@@ -126,10 +126,10 @@ void simple_connector_send_buffer(int *sock, int *failures, struct instance *ins
126
instance->config.destination,
127
len,
128
written);
129
- stats->chart_transmission_failures++;
129
+ stats->transmission_failures++;
130
131
if(written != -1)
132
- stats->chart_sent_bytes += written;
132
+ stats->sent_bytes += written;
133
134
// increment the counter we check for data loss
135
(*failures)++;
@@ -160,6 +160,19 @@ void simple_connector_worker(void *instance_p)
160
int failures = 0;
161
162
while(!netdata_exit) {
163
+
164
+ // reset the monitoring chart counters
165
+ stats->received_bytes =
166
+ stats->sent_bytes =
167
+ stats->sent_metrics =
168
+ stats->lost_metrics =
169
+ stats->receptions =
170
+ stats->transmission_successes =
171
+ stats->transmission_failures =
172
+ stats->data_lost_events =
173
+ stats->lost_bytes =
174
+ stats->reconnects = 0;
175
+
176
// ------------------------------------------------------------------------
177
// if we are connected, receive a response, without blocking
178
@@ -179,7 +192,7 @@ void simple_connector_worker(void *instance_p)
192
&reconnects,
193
NULL,
194
0);
182
- stats->chart_reconnects += reconnects;
195
+ stats->reconnects += reconnects;
196
}
197
198
if(unlikely(netdata_exit)) break;
@@ -194,12 +207,31 @@ void simple_connector_worker(void *instance_p)
207
simple_connector_send_buffer(&sock, &failures, instance);
208
} else {
209
error("EXPORTING: failed to update '%s'", instance->config.destination);
197
- stats->chart_transmission_failures++;
210
+ stats->transmission_failures++;
211
212
// increment the counter we check for data loss
213
failures++;
214
}
215
216
+ BUFFER *buffer = instance->buffer;
217
+
218
+ if (failures > instance->config.buffer_on_failures) {
219
+ stats->lost_bytes += buffer_strlen(buffer);
220
+ error(
221
+ "EXPORTING: connector instance %s reached %d exporting failures. "
222
+ "Flushing buffers to protect this host - this results in data loss on server '%s'",
223
+ instance->config.name, failures, instance->config.destination);
224
+ buffer_flush(buffer);
225
+ failures = 0;
226
+ stats->data_lost_events++;
227
+ stats->lost_metrics = stats->buffered_metrics;
228
+ }
229
+
230
+ send_internal_metrics(instance);
231
+
232
+ if(likely(buffer_strlen(buffer) == 0))
233
+ stats->buffered_metrics = 0;
234
+
235
uv_mutex_unlock(&instance->mutex);
236
237
#ifdef UNIT_TESTING
exporting/send_internal_metrics.c
+160
-6
@@ -3,16 +3,170 @@
3
#include "exporting_engine.h"
4
5
/**
6
- * Send internal metrics
6
+ * Create a chart for the main exporting thread CPU usage
7
+ *
8
+ * @param st_rusage the thead CPU usage chart
9
+ * @param rd_user a dimension for user CPU usage
10
+ * @param rd_system a dimension for system CPU usage
11
+ */
12
+void create_main_rusage_chart(RRDSET **st_rusage, RRDDIM **rd_user, RRDDIM **rd_system)
13
+{
14
+ if (*st_rusage && *rd_user && *rd_system)
15
+ return;
16
+
17
+ *st_rusage = rrdset_create_localhost(
18
+ "netdata", "exporting_main_thread_cpu", NULL, "exporting", NULL, "Netdata Main Exporting Thread CPU Usage",
19
+ "milliseconds/s", "exporting", NULL, 130600, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
20
+
21
+ *rd_user = rrddim_add(*st_rusage, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
22
+ *rd_system = rrddim_add(*st_rusage, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
23
+}
24
+
25
+/**
26
+ * Send the main exporting thread CPU usage
27
+ *
28
+ * @param st_rusage a thead CPU usage chart
29
+ * @param rd_user a dimension for user CPU usage
30
+ * @param rd_system a dimension for system CPU usage
31
+ */
32
+void send_main_rusage(RRDSET *st_rusage, RRDDIM *rd_user, RRDDIM *rd_system)
33
+{
34
+ struct rusage thread;
35
+ getrusage(RUSAGE_THREAD, &thread);
36
+
37
+ if (likely(st_rusage->counter_done))
38
+ rrdset_next(st_rusage);
39
+
40
+ rrddim_set_by_pointer(st_rusage, rd_user, thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec);
41
+ rrddim_set_by_pointer(st_rusage, rd_system, thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec);
42
+
43
+ rrdset_done(st_rusage);
44
+}
45
+
46
+/**
47
+ * Send internal metrics for an instance
48
*
49
* Send performance metrics for the operation of exporting engine itself to the Netdata database.
50
*
10
- * @param engine an engine data structure.
11
- * @return Returns 0 on success, 1 on failure.
51
+ * @param instance an instance data structure.
52
*/
13
-int send_internal_metrics(struct engine *engine)
53
+void send_internal_metrics(struct instance *instance)
54
{
15
- (void)engine;
55
+ struct stats *stats = &instance->stats;
56
+
57
+ // ------------------------------------------------------------------------
58
+ // create charts for monitoring the exporting operations
59
+
60
+ if (!stats->initialized) {
61
+ char id[RRD_ID_LENGTH_MAX + 1];
62
+ BUFFER *family = buffer_create(0);
63
+
64
+ buffer_sprintf(family, "exporting_%s", instance->config.name);
65
+
66
+ snprintf(id, RRD_ID_LENGTH_MAX, "exporting_%s_metrics", instance->config.name);
67
+ netdata_fix_chart_id(id);
68
+
69
+ stats->st_metrics = rrdset_create_localhost(
70
+ "netdata", id, NULL, buffer_tostring(family), NULL, "Netdata Buffered Metrics", "metrics", "exporting", NULL,
71
+ 130610, instance->config.update_every, RRDSET_TYPE_LINE);
72
+
73
+ stats->rd_buffered_metrics = rrddim_add(stats->st_metrics, "buffered", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
74
+ stats->rd_lost_metrics = rrddim_add(stats->st_metrics, "lost", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
75
+ stats->rd_sent_metrics = rrddim_add(stats->st_metrics, "sent", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
76
+
77
+ // ------------------------------------------------------------------------
78
+
79
+ snprintf(id, RRD_ID_LENGTH_MAX, "exporting_%s_bytes", instance->config.name);
80
+ netdata_fix_chart_id(id);
81
+
82
+ stats->st_bytes = rrdset_create_localhost(
83
+ "netdata", id, NULL, buffer_tostring(family), NULL, "Netdata Exporting Data Size", "KiB", "exporting", NULL,
84
+ 130620, instance->config.update_every, RRDSET_TYPE_AREA);
85
+
86
+ stats->rd_buffered_bytes = rrddim_add(stats->st_bytes, "buffered", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
87
+ stats->rd_lost_bytes = rrddim_add(stats->st_bytes, "lost", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
88
+ stats->rd_sent_bytes = rrddim_add(stats->st_bytes, "sent", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
89
+ stats->rd_received_bytes = rrddim_add(stats->st_bytes, "received", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
90
+
91
+ // ------------------------------------------------------------------------
92
+
93
+ snprintf(id, RRD_ID_LENGTH_MAX, "exporting_%s_ops", instance->config.name);
94
+ netdata_fix_chart_id(id);
95
+
96
+ stats->st_ops = rrdset_create_localhost(
97
+ "netdata", id, NULL, buffer_tostring(family), NULL, "Netdata Exporting Operations", "operations", "exporting",
98
+ NULL, 130630, instance->config.update_every, RRDSET_TYPE_LINE);
99
+
100
+ stats->rd_transmission_successes = rrddim_add(stats->st_ops, "write", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
101
+ stats->rd_data_lost_events = rrddim_add(stats->st_ops, "discard", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
102
+ stats->rd_reconnects = rrddim_add(stats->st_ops, "reconnect", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
103
+ stats->rd_transmission_failures = rrddim_add(stats->st_ops, "failure", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
104
+ stats->rd_receptions = rrddim_add(stats->st_ops, "read", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
105
+
106
+ // ------------------------------------------------------------------------
107
+
108
+ snprintf(id, RRD_ID_LENGTH_MAX, "exporting_%s_thread_cpu", instance->config.name);
109
+ netdata_fix_chart_id(id);
110
+
111
+ stats->st_rusage = rrdset_create_localhost(
112
+ "netdata", id, NULL, buffer_tostring(family), NULL, "Netdata Exporting Instance Thread CPU Usage",
113
+ "milliseconds/s", "exporting", NULL, 130640, instance->config.update_every, RRDSET_TYPE_STACKED);
114
+
115
+ stats->rd_user = rrddim_add(stats->st_rusage, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
116
+ stats->rd_system = rrddim_add(stats->st_rusage, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
117
+
118
+ buffer_free(family);
119
+
120
+ stats->initialized = 1;
121
+ }
122
+
123
+ // ------------------------------------------------------------------------
124
+ // update the monitoring charts
125
+
126
+ if (likely(stats->st_metrics->counter_done))
127
+ rrdset_next(stats->st_metrics);
128
+
129
+ rrddim_set_by_pointer(stats->st_metrics, stats->rd_buffered_metrics, stats->buffered_metrics);
130
+ rrddim_set_by_pointer(stats->st_metrics, stats->rd_lost_metrics, stats->lost_metrics);
131
+ rrddim_set_by_pointer(stats->st_metrics, stats->rd_sent_metrics, stats->sent_metrics);
132
+
133
+ rrdset_done(stats->st_metrics);
134
+
135
+ // ------------------------------------------------------------------------
136
+
137
+ if (likely(stats->st_bytes->counter_done))
138
+ rrdset_next(stats->st_bytes);
139
+
140
+ rrddim_set_by_pointer(stats->st_bytes, stats->rd_buffered_bytes, stats->buffered_bytes);
141
+ rrddim_set_by_pointer(stats->st_bytes, stats->rd_lost_bytes, stats->lost_bytes);
142
+ rrddim_set_by_pointer(stats->st_bytes, stats->rd_sent_bytes, stats->sent_bytes);
143
+ rrddim_set_by_pointer(stats->st_bytes, stats->rd_received_bytes, stats->received_bytes);
144
+
145
+ rrdset_done(stats->st_bytes);
146
+
147
+ // ------------------------------------------------------------------------
148
+
149
+ if (likely(stats->st_ops->counter_done))
150
+ rrdset_next(stats->st_ops);
151
+
152
+ rrddim_set_by_pointer(stats->st_ops, stats->rd_transmission_successes, stats->transmission_successes);
153
+ rrddim_set_by_pointer(stats->st_ops, stats->rd_data_lost_events, stats->data_lost_events);
154
+ rrddim_set_by_pointer(stats->st_ops, stats->rd_reconnects, stats->reconnects);
155
+ rrddim_set_by_pointer(stats->st_ops, stats->rd_transmission_failures, stats->transmission_failures);
156
+ rrddim_set_by_pointer(stats->st_ops, stats->rd_receptions, stats->receptions);
157
+
158
+ rrdset_done(stats->st_ops);
159
+
160
+ // ------------------------------------------------------------------------
161
+
162
+ struct rusage thread;
163
+ getrusage(RUSAGE_THREAD, &thread);
164
+
165
+ if (likely(stats->st_rusage->counter_done))
166
+ rrdset_next(stats->st_rusage);
167
+
168
+ rrddim_set_by_pointer(stats->st_rusage, stats->rd_user, thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec);
169
+ rrddim_set_by_pointer(stats->st_rusage, stats->rd_system, thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec);
170
17
- return 0;
171
+ rrdset_done(stats->st_rusage);
172
}
exporting/tests/exporting_doubles.c
+18
-2
@@ -82,10 +82,26 @@ int __wrap_notify_workers(struct engine *engine)
82
return mock_type(int);
83
}
84
85
-int __wrap_send_internal_metrics(struct engine *engine)
85
+void __wrap_create_main_rusage_chart(RRDSET **st_rusage, RRDDIM **rd_user, RRDDIM **rd_system)
86
{
87
function_called();
88
- check_expected_ptr(engine);
88
+ check_expected_ptr(st_rusage);
89
+ check_expected_ptr(rd_user);
90
+ check_expected_ptr(rd_system);
91
+}
92
+
93
+void __wrap_send_main_rusage(RRDSET *st_rusage, RRDDIM *rd_user, RRDDIM *rd_system)
94
+{
95
+ function_called();
96
+ check_expected_ptr(st_rusage);
97
+ check_expected_ptr(rd_user);
98
+ check_expected_ptr(rd_system);
99
+}
100
+
101
+int __wrap_send_internal_metrics(struct instance *instance)
102
+{
103
+ function_called();
104
+ check_expected_ptr(instance);
105
return mock_type(int);
106
}
107
exporting/tests/netdata_doubles.c
+86
@@ -85,6 +85,92 @@ void __rrd_check_rdlock(const char *file, const char *function, const unsigned l
85
(void)line;
86
}
87
88
+RRDSET *rrdset_create_custom(
89
+ RRDHOST *host,
90
+ const char *type,
91
+ const char *id,
92
+ const char *name,
93
+ const char *family,
94
+ const char *context,
95
+ const char *title,
96
+ const char *units,
97
+ const char *plugin,
98
+ const char *module,
99
+ long priority,
100
+ int update_every,
101
+ RRDSET_TYPE chart_type,
102
+ RRD_MEMORY_MODE memory_mode,
103
+ long history_entries)
104
+{
105
+ check_expected_ptr(host);
106
+ check_expected_ptr(type);
107
+ check_expected_ptr(id);
108
+ check_expected_ptr(name);
109
+ check_expected_ptr(family);
110
+ check_expected_ptr(context);
111
+ UNUSED(title);
112
+ check_expected_ptr(units);
113
+ check_expected_ptr(plugin);
114
+ check_expected_ptr(module);
115
+ check_expected(priority);
116
+ check_expected(update_every);
117
+ check_expected(chart_type);
118
+ UNUSED(memory_mode);
119
+ UNUSED(history_entries);
120
+
121
+ function_called();
122
+
123
+ return mock_ptr_type(RRDSET *);
124
+}
125
+
126
+void rrdset_next_usec(RRDSET *st, usec_t microseconds)
127
+{
128
+ check_expected_ptr(st);
129
+ UNUSED(microseconds);
130
+
131
+ function_called();
132
+}
133
+
134
+void rrdset_done(RRDSET *st)
135
+{
136
+ check_expected_ptr(st);
137
+
138
+ function_called();
139
+}
140
+
141
+RRDDIM *rrddim_add_custom(
142
+ RRDSET *st,
143
+ const char *id,
144
+ const char *name,
145
+ collected_number multiplier,
146
+ collected_number divisor,
147
+ RRD_ALGORITHM algorithm,
148
+ RRD_MEMORY_MODE memory_mode)
149
+{
150
+ check_expected_ptr(st);
151
+ UNUSED(id);
152
+ check_expected_ptr(name);
153
+ check_expected(multiplier);
154
+ check_expected(divisor);
155
+ check_expected(algorithm);
156
+ UNUSED(memory_mode);
157
+
158
+ function_called();
159
+
160
+ return NULL;
161
+}
162
+
163
+collected_number rrddim_set_by_pointer(RRDSET *st, RRDDIM *rd, collected_number value)
164
+{
165
+ check_expected_ptr(st);
166
+ UNUSED(rd);
167
+ UNUSED(value);
168
+
169
+ function_called();
170
+
171
+ return 0;
172
+}
173
+
174
const char *rrd_memory_mode_name(RRD_MEMORY_MODE id)
175
{
176
(void)id;
exporting/tests/test_exporting_engine.c
+305
-17
@@ -44,6 +44,11 @@ static void test_exporting_engine(void **state)
44
expect_memory(__wrap_init_connectors, engine, engine, sizeof(struct engine));
45
will_return(__wrap_init_connectors, 0);
46
47
+ expect_function_call(__wrap_create_main_rusage_chart);
48
+ expect_not_value(__wrap_create_main_rusage_chart, st_rusage, NULL);
49
+ expect_not_value(__wrap_create_main_rusage_chart, rd_user, NULL);
50
+ expect_not_value(__wrap_create_main_rusage_chart, rd_system, NULL);
51
+
52
expect_function_call(__wrap_now_realtime_sec);
53
will_return(__wrap_now_realtime_sec, 2);
54
@@ -59,9 +64,10 @@ static void test_exporting_engine(void **state)
64
expect_memory(__wrap_notify_workers, engine, engine, sizeof(struct engine));
65
will_return(__wrap_notify_workers, 0);
66
62
- expect_function_call(__wrap_send_internal_metrics);
63
- expect_memory(__wrap_send_internal_metrics, engine, engine, sizeof(struct engine));
64
- will_return(__wrap_send_internal_metrics, 0);
67
+ expect_function_call(__wrap_send_main_rusage);
68
+ expect_value(__wrap_send_main_rusage, st_rusage, NULL);
69
+ expect_value(__wrap_send_main_rusage, rd_user, NULL);
70
+ expect_value(__wrap_send_main_rusage, rd_system, NULL);
71
72
expect_function_call(__wrap_info_int);
73
@@ -122,7 +128,7 @@ static void test_init_connectors(void **state)
128
assert_ptr_equal(instance->metric_formatting, format_dimension_collected_graphite_plaintext);
129
assert_ptr_equal(instance->end_chart_formatting, NULL);
130
assert_ptr_equal(instance->end_host_formatting, flush_host_labels);
125
- assert_ptr_equal(instance->end_batch_formatting, NULL);
131
+ assert_ptr_equal(instance->end_batch_formatting, simple_connector_update_buffered_bytes);
132
133
BUFFER *buffer = instance->buffer;
134
assert_ptr_not_equal(buffer, NULL);
@@ -384,7 +390,7 @@ static void test_prepare_buffers(void **state)
390
391
assert_int_equal(__real_prepare_buffers(engine), 0);
392
387
- assert_int_equal(instance->stats.chart_buffered_metrics, 1);
393
+ assert_int_equal(instance->stats.buffered_metrics, 1);
394
395
// check with NULL functions
396
instance->start_batch_formatting = NULL;
@@ -573,8 +579,8 @@ static void test_simple_connector_receive_response(void **state)
579
log_line,
580
"EXPORTING: received 9 bytes from instance_name connector instance. Ignoring them. Sample: 'Test recv'");
581
576
- assert_int_equal(stats->chart_received_bytes, 9);
577
- assert_int_equal(stats->chart_receptions, 1);
582
+ assert_int_equal(stats->received_bytes, 9);
583
+ assert_int_equal(stats->receptions, 1);
584
assert_int_equal(sock, 1);
585
}
586
@@ -614,10 +620,10 @@ static void test_simple_connector_send_buffer(void **state)
620
simple_connector_send_buffer(&sock, &failures, instance);
621
622
assert_int_equal(failures, 0);
617
- assert_int_equal(stats->chart_transmission_successes, 1);
618
- assert_int_equal(stats->chart_sent_bytes, 84);
619
- assert_int_equal(stats->chart_sent_metrics, 1);
620
- assert_int_equal(stats->chart_transmission_failures, 0);
623
+ assert_int_equal(stats->transmission_successes, 1);
624
+ assert_int_equal(stats->sent_bytes, 84);
625
+ assert_int_equal(stats->sent_metrics, 1);
626
+ assert_int_equal(stats->transmission_failures, 0);
627
628
assert_int_equal(buffer_strlen(buffer), 0);
629
@@ -628,6 +634,7 @@ static void test_simple_connector_worker(void **state)
634
{
635
struct engine *engine = *state;
636
struct instance *instance = engine->instance_root;
637
+ struct stats *stats = &instance->stats;
638
BUFFER *buffer = instance->buffer;
639
640
__real_mark_scheduled_instances(engine);
@@ -661,7 +668,24 @@ static void test_simple_connector_worker(void **state)
668
expect_value(__wrap_send, len, 84);
669
expect_value(__wrap_send, flags, MSG_NOSIGNAL);
670
671
+ expect_function_call(__wrap_send_internal_metrics);
672
+ expect_value(__wrap_send_internal_metrics, instance, instance);
673
+ will_return(__wrap_send_internal_metrics, 0);
674
+
675
simple_connector_worker(instance);
676
+
677
+ assert_int_equal(stats->buffered_metrics, 0);
678
+ assert_int_equal(stats->buffered_bytes, 84);
679
+ assert_int_equal(stats->received_bytes, 0);
680
+ assert_int_equal(stats->sent_bytes, 84);
681
+ assert_int_equal(stats->sent_metrics, 1);
682
+ assert_int_equal(stats->lost_metrics, 0);
683
+ assert_int_equal(stats->receptions, 0);
684
+ assert_int_equal(stats->transmission_successes, 1);
685
+ assert_int_equal(stats->transmission_failures, 0);
686
+ assert_int_equal(stats->data_lost_events, 0);
687
+ assert_int_equal(stats->lost_bytes, 0);
688
+ assert_int_equal(stats->reconnects, 0);
689
}
690
691
static void test_sanitize_json_string(void **state)
@@ -761,6 +785,233 @@ static void test_flush_host_labels(void **state)
785
assert_int_equal(buffer_strlen(instance->labels), 0);
786
}
787
788
+static void test_create_main_rusage_chart(void **state)
789
+{
790
+ UNUSED(state);
791
+
792
+ RRDSET *st_rusage = calloc(1, sizeof(RRDSET));
793
+ RRDDIM *rd_user = NULL;
794
+ RRDDIM *rd_system = NULL;
795
+
796
+ expect_function_call(rrdset_create_custom);
797
+ expect_value(rrdset_create_custom, host, localhost);
798
+ expect_string(rrdset_create_custom, type, "netdata");
799
+ expect_string(rrdset_create_custom, id, "exporting_main_thread_cpu");
800
+ expect_value(rrdset_create_custom, name, NULL);
801
+ expect_string(rrdset_create_custom, family, "exporting");
802
+ expect_value(rrdset_create_custom, context, NULL);
803
+ expect_string(rrdset_create_custom, units, "milliseconds/s");
804
+ expect_string(rrdset_create_custom, plugin, "exporting");
805
+ expect_value(rrdset_create_custom, module, NULL);
806
+ expect_value(rrdset_create_custom, priority, 130600);
807
+ expect_value(rrdset_create_custom, update_every, localhost->rrd_update_every);
808
+ expect_value(rrdset_create_custom, chart_type, RRDSET_TYPE_STACKED);
809
+ will_return(rrdset_create_custom, st_rusage);
810
+
811
+ expect_function_calls(rrddim_add_custom, 2);
812
+ expect_value_count(rrddim_add_custom, st, st_rusage, 2);
813
+ expect_value_count(rrddim_add_custom, name, NULL, 2);
814
+ expect_value_count(rrddim_add_custom, multiplier, 1, 2);
815
+ expect_value_count(rrddim_add_custom, divisor, 1000, 2);
816
+ expect_value_count(rrddim_add_custom, algorithm, RRD_ALGORITHM_INCREMENTAL, 2);
817
+
818
+ __real_create_main_rusage_chart(&st_rusage, &rd_user, &rd_system);
819
+
820
+ free(st_rusage);
821
+}
822
+
823
+static void test_send_main_rusage(void **state)
824
+{
825
+ UNUSED(state);
826
+
827
+ RRDSET *st_rusage = calloc(1, sizeof(RRDSET));
828
+ st_rusage->counter_done = 1;
829
+
830
+ expect_function_call(rrdset_next_usec);
831
+ expect_value(rrdset_next_usec, st, st_rusage);
832
+
833
+ expect_function_calls(rrddim_set_by_pointer, 2);
834
+ expect_value_count(rrddim_set_by_pointer, st, st_rusage, 2);
835
+
836
+ expect_function_call(rrdset_done);
837
+ expect_value(rrdset_done, st, st_rusage);
838
+
839
+ __real_send_main_rusage(st_rusage, NULL, NULL);
840
+
841
+ free(st_rusage);
842
+}
843
+
844
+static void test_send_internal_metrics(void **state)
845
+{
846
+ UNUSED(state);
847
+
848
+ struct instance *instance = calloc(1, sizeof(struct instance));
849
+ instance->config.name = (const char *)strdupz("test_instance");
850
+ instance->config.update_every = 2;
851
+
852
+ struct stats *stats = &instance->stats;
853
+
854
+ stats->st_metrics = calloc(1, sizeof(RRDSET));
855
+ stats->st_metrics->counter_done = 1;
856
+ stats->st_bytes = calloc(1, sizeof(RRDSET));
857
+ stats->st_bytes->counter_done = 1;
858
+ stats->st_ops = calloc(1, sizeof(RRDSET));
859
+ stats->st_ops->counter_done = 1;
860
+ stats->st_rusage = calloc(1, sizeof(RRDSET));
861
+ stats->st_rusage->counter_done = 1;
862
+
863
+ // ------------------------------------------------------------------------
864
+
865
+ expect_function_call(rrdset_create_custom);
866
+ expect_value(rrdset_create_custom, host, localhost);
867
+ expect_string(rrdset_create_custom, type, "netdata");
868
+ expect_string(rrdset_create_custom, id, "exporting_test_instance_metrics");
869
+ expect_value(rrdset_create_custom, name, NULL);
870
+ expect_string(rrdset_create_custom, family, "exporting_test_instance");
871
+ expect_value(rrdset_create_custom, context, NULL);
872
+ expect_string(rrdset_create_custom, units, "metrics");
873
+ expect_string(rrdset_create_custom, plugin, "exporting");
874
+ expect_value(rrdset_create_custom, module, NULL);
875
+ expect_value(rrdset_create_custom, priority, 130610);
876
+ expect_value(rrdset_create_custom, update_every, 2);
877
+ expect_value(rrdset_create_custom, chart_type, RRDSET_TYPE_LINE);
878
+ will_return(rrdset_create_custom, stats->st_metrics);
879
+
880
+ expect_function_calls(rrddim_add_custom, 3);
881
+ expect_value_count(rrddim_add_custom, st, stats->st_metrics, 3);
882
+ expect_value_count(rrddim_add_custom, name, NULL, 3);
883
+ expect_value_count(rrddim_add_custom, multiplier, 1, 3);
884
+ expect_value_count(rrddim_add_custom, divisor, 1, 3);
885
+ expect_value_count(rrddim_add_custom, algorithm, RRD_ALGORITHM_ABSOLUTE, 3);
886
+
887
+ // ------------------------------------------------------------------------
888
+
889
+ expect_function_call(rrdset_create_custom);
890
+ expect_value(rrdset_create_custom, host, localhost);
891
+ expect_string(rrdset_create_custom, type, "netdata");
892
+ expect_string(rrdset_create_custom, id, "exporting_test_instance_bytes");
893
+ expect_value(rrdset_create_custom, name, NULL);
894
+ expect_string(rrdset_create_custom, family, "exporting_test_instance");
895
+ expect_value(rrdset_create_custom, context, NULL);
896
+ expect_string(rrdset_create_custom, units, "KiB");
897
+ expect_string(rrdset_create_custom, plugin, "exporting");
898
+ expect_value(rrdset_create_custom, module, NULL);
899
+ expect_value(rrdset_create_custom, priority, 130620);
900
+ expect_value(rrdset_create_custom, update_every, 2);
901
+ expect_value(rrdset_create_custom, chart_type, RRDSET_TYPE_AREA);
902
+ will_return(rrdset_create_custom, stats->st_bytes);
903
+
904
+ expect_function_calls(rrddim_add_custom, 4);
905
+ expect_value_count(rrddim_add_custom, st, stats->st_bytes, 4);
906
+ expect_value_count(rrddim_add_custom, name, NULL, 4);
907
+ expect_value_count(rrddim_add_custom, multiplier, 1, 4);
908
+ expect_value_count(rrddim_add_custom, divisor, 1024, 4);
909
+ expect_value_count(rrddim_add_custom, algorithm, RRD_ALGORITHM_ABSOLUTE, 4);
910
+
911
+ // ------------------------------------------------------------------------
912
+
913
+ expect_function_call(rrdset_create_custom);
914
+ expect_value(rrdset_create_custom, host, localhost);
915
+ expect_string(rrdset_create_custom, type, "netdata");
916
+ expect_string(rrdset_create_custom, id, "exporting_test_instance_ops");
917
+ expect_value(rrdset_create_custom, name, NULL);
918
+ expect_string(rrdset_create_custom, family, "exporting_test_instance");
919
+ expect_value(rrdset_create_custom, context, NULL);
920
+ expect_string(rrdset_create_custom, units, "operations");
921
+ expect_string(rrdset_create_custom, plugin, "exporting");
922
+ expect_value(rrdset_create_custom, module, NULL);
923
+ expect_value(rrdset_create_custom, priority, 130630);
924
+ expect_value(rrdset_create_custom, update_every, 2);
925
+ expect_value(rrdset_create_custom, chart_type, RRDSET_TYPE_LINE);
926
+ will_return(rrdset_create_custom, stats->st_ops);
927
+
928
+ expect_function_calls(rrddim_add_custom, 5);
929
+ expect_value_count(rrddim_add_custom, st, stats->st_ops, 5);
930
+ expect_value_count(rrddim_add_custom, name, NULL, 5);
931
+ expect_value_count(rrddim_add_custom, multiplier, 1, 5);
932
+ expect_value_count(rrddim_add_custom, divisor, 1, 5);
933
+ expect_value_count(rrddim_add_custom, algorithm, RRD_ALGORITHM_ABSOLUTE, 5);
934
+
935
+ // ------------------------------------------------------------------------
936
+
937
+ expect_function_call(rrdset_create_custom);
938
+ expect_value(rrdset_create_custom, host, localhost);
939
+ expect_string(rrdset_create_custom, type, "netdata");
940
+ expect_string(rrdset_create_custom, id, "exporting_test_instance_thread_cpu");
941
+ expect_value(rrdset_create_custom, name, NULL);
942
+ expect_string(rrdset_create_custom, family, "exporting_test_instance");
943
+ expect_value(rrdset_create_custom, context, NULL);
944
+ expect_string(rrdset_create_custom, units, "milliseconds/s");
945
+ expect_string(rrdset_create_custom, plugin, "exporting");
946
+ expect_value(rrdset_create_custom, module, NULL);
947
+ expect_value(rrdset_create_custom, priority, 130640);
948
+ expect_value(rrdset_create_custom, update_every, 2);
949
+ expect_value(rrdset_create_custom, chart_type, RRDSET_TYPE_STACKED);
950
+ will_return(rrdset_create_custom, stats->st_rusage);
951
+
952
+ expect_function_calls(rrddim_add_custom, 2);
953
+ expect_value_count(rrddim_add_custom, st, stats->st_rusage, 2);
954
+ expect_value_count(rrddim_add_custom, name, NULL, 2);
955
+ expect_value_count(rrddim_add_custom, multiplier, 1, 2);
956
+ expect_value_count(rrddim_add_custom, divisor, 1000, 2);
957
+ expect_value_count(rrddim_add_custom, algorithm, RRD_ALGORITHM_INCREMENTAL, 2);
958
+
959
+ // ------------------------------------------------------------------------
960
+
961
+ expect_function_call(rrdset_next_usec);
962
+ expect_value(rrdset_next_usec, st, stats->st_metrics);
963
+
964
+ expect_function_calls(rrddim_set_by_pointer, 3);
965
+ expect_value_count(rrddim_set_by_pointer, st, stats->st_metrics, 3);
966
+
967
+ expect_function_call(rrdset_done);
968
+ expect_value(rrdset_done, st, stats->st_metrics);
969
+
970
+ // ------------------------------------------------------------------------
971
+
972
+ expect_function_call(rrdset_next_usec);
973
+ expect_value(rrdset_next_usec, st, stats->st_bytes);
974
+
975
+ expect_function_calls(rrddim_set_by_pointer, 4);
976
+ expect_value_count(rrddim_set_by_pointer, st, stats->st_bytes, 4);
977
+
978
+ expect_function_call(rrdset_done);
979
+ expect_value(rrdset_done, st, stats->st_bytes);
980
+
981
+ // ------------------------------------------------------------------------
982
+
983
+ expect_function_call(rrdset_next_usec);
984
+ expect_value(rrdset_next_usec, st, stats->st_ops);
985
+
986
+ expect_function_calls(rrddim_set_by_pointer, 5);
987
+ expect_value_count(rrddim_set_by_pointer, st, stats->st_ops, 5);
988
+
989
+ expect_function_call(rrdset_done);
990
+ expect_value(rrdset_done, st, stats->st_ops);
991
+
992
+ // ------------------------------------------------------------------------
993
+
994
+ expect_function_call(rrdset_next_usec);
995
+ expect_value(rrdset_next_usec, st, stats->st_rusage);
996
+
997
+ expect_function_calls(rrddim_set_by_pointer, 2);
998
+ expect_value_count(rrddim_set_by_pointer, st, stats->st_rusage, 2);
999
+
1000
+ expect_function_call(rrdset_done);
1001
+ expect_value(rrdset_done, st, stats->st_rusage);
1002
+
1003
+ // ------------------------------------------------------------------------
1004
+
1005
+ __real_send_internal_metrics(instance);
1006
+
1007
+ free(stats->st_metrics);
1008
+ free(stats->st_bytes);
1009
+ free(stats->st_ops);
1010
+ free(stats->st_rusage);
1011
+ free((void *)instance->config.name);
1012
+ free(instance);
1013
+}
1014
+
1015
static void test_can_send_rrdset(void **state)
1016
{
1017
(void)*state;
@@ -1148,6 +1399,7 @@ static void test_aws_kinesis_connector_worker(void **state)
1399
{
1400
struct engine *engine = *state;
1401
struct instance *instance = engine->instance_root;
1402
+ struct stats *stats = &instance->stats;
1403
BUFFER *buffer = instance->buffer;
1404
1405
__real_mark_scheduled_instances(engine);
@@ -1193,8 +1445,25 @@ static void test_aws_kinesis_connector_worker(void **state)
1445
expect_not_value(__wrap_kinesis_get_result, lost_bytes, NULL);
1446
will_return(__wrap_kinesis_get_result, 0);
1447
1448
+ expect_function_call(__wrap_send_internal_metrics);
1449
+ expect_value(__wrap_send_internal_metrics, instance, instance);
1450
+ will_return(__wrap_send_internal_metrics, 0);
1451
+
1452
aws_kinesis_connector_worker(instance);
1453
1454
+ assert_int_equal(stats->buffered_metrics, 0);
1455
+ assert_int_equal(stats->buffered_bytes, 84);
1456
+ assert_int_equal(stats->received_bytes, 0);
1457
+ assert_int_equal(stats->sent_bytes, 84);
1458
+ assert_int_equal(stats->sent_metrics, 1);
1459
+ assert_int_equal(stats->lost_metrics, 0);
1460
+ assert_int_equal(stats->receptions, 1);
1461
+ assert_int_equal(stats->transmission_successes, 1);
1462
+ assert_int_equal(stats->transmission_failures, 0);
1463
+ assert_int_equal(stats->data_lost_events, 0);
1464
+ assert_int_equal(stats->lost_bytes, 0);
1465
+ assert_int_equal(stats->reconnects, 0);
1466
+
1467
free(connector_specific_config->stream_name);
1468
free(connector_specific_config->auth_key_id);
1469
free(connector_specific_config->secure_key);
@@ -1304,7 +1573,7 @@ static void test_format_batch_mongodb(void **state)
1573
BUFFER *buffer = buffer_create(0);
1574
buffer_sprintf(buffer, "{ \"metric\": \"test_metric\" }\n");
1575
instance->buffer = buffer;
1307
- stats->chart_buffered_metrics = 1;
1576
+ stats->buffered_metrics = 1;
1577
1578
assert_int_equal(format_batch_mongodb(instance), 0);
1579
@@ -1355,6 +1624,10 @@ static void test_mongodb_connector_worker(void **state)
1624
expect_not_value(__wrap_mongoc_collection_insert_many, error, NULL);
1625
will_return(__wrap_mongoc_collection_insert_many, true);
1626
1627
+ expect_function_call(__wrap_send_internal_metrics);
1628
+ expect_value(__wrap_send_internal_metrics, instance, instance);
1629
+ will_return(__wrap_send_internal_metrics, 0);
1630
+
1631
mongodb_connector_worker(instance);
1632
1633
assert_ptr_equal(connector_specific_data->first_buffer->insert, NULL);
@@ -1362,11 +1635,18 @@ static void test_mongodb_connector_worker(void **state)
1635
assert_ptr_equal(connector_specific_data->first_buffer, connector_specific_data->first_buffer->next);
1636
1637
struct stats *stats = &instance->stats;
1365
- assert_int_equal(stats->chart_sent_bytes, 60);
1366
- assert_int_equal(stats->chart_transmission_successes, 1);
1367
- assert_int_equal(stats->chart_receptions, 1);
1368
- assert_int_equal(stats->chart_sent_bytes, 60);
1369
- assert_int_equal(stats->chart_sent_metrics, 0);
1638
+ assert_int_equal(stats->buffered_metrics, 0);
1639
+ assert_int_equal(stats->buffered_bytes, 0);
1640
+ assert_int_equal(stats->received_bytes, 0);
1641
+ assert_int_equal(stats->sent_bytes, 30);
1642
+ assert_int_equal(stats->sent_metrics, 1);
1643
+ assert_int_equal(stats->lost_metrics, 0);
1644
+ assert_int_equal(stats->receptions, 1);
1645
+ assert_int_equal(stats->transmission_successes, 1);
1646
+ assert_int_equal(stats->transmission_failures, 0);
1647
+ assert_int_equal(stats->data_lost_events, 0);
1648
+ assert_int_equal(stats->lost_bytes, 0);
1649
+ assert_int_equal(stats->reconnects, 0);
1650
1651
free(connector_specific_config->database);
1652
free(connector_specific_config->collection);
@@ -1445,6 +1725,14 @@ int main(void)
1725
int test_res = cmocka_run_group_tests_name("exporting_engine", tests, NULL, NULL) +
1726
cmocka_run_group_tests_name("labels_in_exporting_engine", label_tests, NULL, NULL);
1727
1728
+ const struct CMUnitTest internal_metrics_tests[] = {
1729
+ cmocka_unit_test(test_create_main_rusage_chart),
1730
+ cmocka_unit_test(test_send_main_rusage),
1731
+ cmocka_unit_test(test_send_internal_metrics),
1732
+ };
1733
+
1734
+ test_res += cmocka_run_group_tests_name("internal_metrics", internal_metrics_tests, NULL, NULL);
1735
+
1736
const struct CMUnitTest prometheus_web_api_tests[] = {
1737
cmocka_unit_test_setup_teardown(test_can_send_rrdset, setup_prometheus, teardown_prometheus),
1738
cmocka_unit_test_setup_teardown(test_prometheus_name_copy, setup_prometheus, teardown_prometheus),
exporting/tests/test_exporting_engine.h
+8
-1
@@ -91,7 +91,14 @@ int __wrap_prepare_buffers(struct engine *engine);
91
92
int __wrap_notify_workers(struct engine *engine);
93
94
-int __wrap_send_internal_metrics(struct engine *engine);
94
+void __real_create_main_rusage_chart(RRDSET **st_rusage, RRDDIM **rd_user, RRDDIM **rd_system);
95
+void __wrap_create_main_rusage_chart(RRDSET **st_rusage, RRDDIM **rd_user, RRDDIM **rd_system);
96
+
97
+void __real_send_main_rusage(RRDSET *st_rusage, RRDDIM *rd_user, RRDDIM *rd_system);
98
+void __wrap_send_main_rusage(RRDSET *st_rusage, RRDDIM *rd_user, RRDDIM *rd_system);
99
+
100
+int __real_send_internal_metrics(struct instance *instance);
101
+int __wrap_send_internal_metrics(struct instance *instance);
102
103
int __real_rrdhost_is_exportable(struct instance *instance, RRDHOST *host);
104
int __wrap_rrdhost_is_exportable(struct instance *instance, RRDHOST *host);