@cryptotaxi247 / netdata-1 / commits / 231d19351

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);