28
struct by_reason disconnects_by_reason;
29
30
// gauges
31
- ssize_t nodes_local;
32
- ssize_t nodes_virtual;
33
- ssize_t nodes_loading;
34
- ssize_t nodes_archived;
35
- ssize_t nodes_offline;
36
- ssize_t nodes_waiting;
37
- ssize_t nodes_replicating;
38
- ssize_t nodes_replication_waiting;
39
- ssize_t nodes_running;
31
+ struct {
32
+ RRDSET *st_nodes;
33
+ RRDDIM *rd_loading;
34
+ RRDDIM *rd_local;
35
+ RRDDIM *rd_virtual;
36
+ RRDDIM *rd_archived;
37
+ RRDDIM *rd_offline;
38
+ RRDDIM *rd_waiting;
39
+ RRDDIM *rd_replication_waiting;
40
+ RRDDIM *rd_replicating;
41
+ RRDDIM *rd_running;
42
+
43
+ ssize_t nodes_local;
44
+ ssize_t nodes_virtual;
45
+ ssize_t nodes_loading;
46
+ ssize_t nodes_archived;
47
+ ssize_t nodes_offline;
48
+ ssize_t nodes_waiting;
49
+ ssize_t nodes_replicating;
50
+ ssize_t nodes_replication_waiting;
51
+ ssize_t nodes_running;
52
+ } type[2];
53
} parent;
54
55
struct {
66
ssize_t nodes_replicating;
67
ssize_t nodes_running;
68
ssize_t nodes_no_dst;
69
+ ssize_t nodes_no_dst_failed;
70
} sender;
71
72
} p = { 0 };
115
}
116
117
static void pulse_host_add_sub_status(PULSE_HOST_STATUS status, ssize_t val, STREAM_HANDSHAKE reason) {
118
+ size_t idx = status & PULSE_HOST_STATUS_EPHEMERAL ? 1 : 0;
119
+ status &= ~(PULSE_HOST_STATUS_EPHEMERAL | PULSE_HOST_STATUS_PERMANENT);
120
+
121
while(status) {
122
PULSE_HOST_STATUS s = 1 << (__builtin_ffs(status) - 1);
123
status &= ~s;
129
break;
130
131
case PULSE_HOST_STATUS_LOCAL:
115
- __atomic_add_fetch(&p.parent.nodes_local, val, __ATOMIC_RELAXED);
132
+ __atomic_add_fetch(&p.parent.type[idx].nodes_local, val, __ATOMIC_RELAXED);
133
break;
134
135
case PULSE_HOST_STATUS_VIRTUAL:
119
- __atomic_add_fetch(&p.parent.nodes_virtual, val, __ATOMIC_RELAXED);
136
+ __atomic_add_fetch(&p.parent.type[idx].nodes_virtual, val, __ATOMIC_RELAXED);
137
break;
138
139
case PULSE_HOST_STATUS_LOADING:
123
- __atomic_add_fetch(&p.parent.nodes_loading, val, __ATOMIC_RELAXED);
140
+ __atomic_add_fetch(&p.parent.type[idx].nodes_loading, val, __ATOMIC_RELAXED);
141
break;
142
143
case PULSE_HOST_STATUS_ARCHIVED:
127
- __atomic_add_fetch(&p.parent.nodes_archived, val, __ATOMIC_RELAXED);
144
+ __atomic_add_fetch(&p.parent.type[idx].nodes_archived, val, __ATOMIC_RELAXED);
145
break;
146
147
case PULSE_HOST_STATUS_RCV_OFFLINE:
131
- __atomic_add_fetch(&p.parent.nodes_offline, val, __ATOMIC_RELAXED);
148
+ __atomic_add_fetch(&p.parent.type[idx].nodes_offline, val, __ATOMIC_RELAXED);
149
do_parent_reason = true;
150
break;
151
152
case PULSE_HOST_STATUS_RCV_WAITING:
136
- __atomic_add_fetch(&p.parent.nodes_waiting, val, __ATOMIC_RELAXED);
153
+ __atomic_add_fetch(&p.parent.type[idx].nodes_waiting, val, __ATOMIC_RELAXED);
154
do_parent_reason = true;
155
reason = 0;
156
break;
157
158
case PULSE_HOST_STATUS_RCV_REPLICATION_WAIT:
142
- __atomic_add_fetch(&p.parent.nodes_replication_waiting, val, __ATOMIC_RELAXED);
159
+ __atomic_add_fetch(&p.parent.type[idx].nodes_replication_waiting, val, __ATOMIC_RELAXED);
160
break;
161
162
case PULSE_HOST_STATUS_RCV_REPLICATING:
146
- __atomic_add_fetch(&p.parent.nodes_replicating, val, __ATOMIC_RELAXED);
163
+ __atomic_add_fetch(&p.parent.type[idx].nodes_replicating, val, __ATOMIC_RELAXED);
164
break;
165
166
case PULSE_HOST_STATUS_RCV_RUNNING:
150
- __atomic_add_fetch(&p.parent.nodes_running, val, __ATOMIC_RELAXED);
167
+ __atomic_add_fetch(&p.parent.type[idx].nodes_running, val, __ATOMIC_RELAXED);
168
break;
169
170
case PULSE_HOST_STATUS_SND_OFFLINE:
196
case PULSE_HOST_STATUS_SND_NO_DST:
197
__atomic_add_fetch(&p.sender.nodes_no_dst, val, __ATOMIC_RELAXED);
198
break;
199
+
200
+ case PULSE_HOST_STATUS_SND_NO_DST_FAILED:
201
+ __atomic_add_fetch(&p.sender.nodes_no_dst_failed, val, __ATOMIC_RELAXED);
202
+ break;
203
}
204
205
if(do_parent_reason && val > 0)
216
if(!status)
217
status = pulse_host_detect_receiver_status(host);
218
198
- PULSE_HOST_STATUS basic = PULSE_HOST_STATUS_LOCAL|PULSE_HOST_STATUS_VIRTUAL| PULSE_HOST_STATUS_LOADING |PULSE_HOST_STATUS_ARCHIVED|PULSE_HOST_STATUS_DELETED;
199
- PULSE_HOST_STATUS rcv = PULSE_HOST_STATUS_RCV_OFFLINE|PULSE_HOST_STATUS_RCV_WAITING|PULSE_HOST_STATUS_RCV_REPLICATING|PULSE_HOST_STATUS_RCV_REPLICATION_WAIT|PULSE_HOST_STATUS_RCV_RUNNING;
200
- PULSE_HOST_STATUS snd = PULSE_HOST_STATUS_SND_OFFLINE|PULSE_HOST_STATUS_SND_PENDING|PULSE_HOST_STATUS_SND_CONNECTING|PULSE_HOST_STATUS_SND_WAITING|PULSE_HOST_STATUS_SND_REPLICATING|PULSE_HOST_STATUS_SND_RUNNING|PULSE_HOST_STATUS_SND_NO_DST;
219
+ static const PULSE_HOST_STATUS ephemerality =
220
+ PULSE_HOST_STATUS_EPHEMERAL | PULSE_HOST_STATUS_PERMANENT;
221
+
222
+ static const PULSE_HOST_STATUS basic =
223
+ PULSE_HOST_STATUS_LOCAL | PULSE_HOST_STATUS_VIRTUAL | PULSE_HOST_STATUS_LOADING |
224
+ PULSE_HOST_STATUS_ARCHIVED | PULSE_HOST_STATUS_DELETED;
225
+
226
+ static const PULSE_HOST_STATUS receiver =
227
+ PULSE_HOST_STATUS_RCV_OFFLINE | PULSE_HOST_STATUS_RCV_WAITING | PULSE_HOST_STATUS_RCV_REPLICATING |
228
+ PULSE_HOST_STATUS_RCV_REPLICATION_WAIT | PULSE_HOST_STATUS_RCV_RUNNING;
229
+
230
+ static const PULSE_HOST_STATUS sender =
231
+ PULSE_HOST_STATUS_SND_OFFLINE | PULSE_HOST_STATUS_SND_PENDING | PULSE_HOST_STATUS_SND_CONNECTING |
232
+ PULSE_HOST_STATUS_SND_WAITING | PULSE_HOST_STATUS_SND_REPLICATING | PULSE_HOST_STATUS_SND_RUNNING |
233
+ PULSE_HOST_STATUS_SND_NO_DST | PULSE_HOST_STATUS_SND_NO_DST_FAILED;
234
+
235
+ if((status & (basic | receiver)) && !(status & ephemerality))
236
+ status |= rrdhost_option_check(host, RRDHOST_OPTION_EPHEMERAL_HOST) ?
237
+ PULSE_HOST_STATUS_EPHEMERAL : PULSE_HOST_STATUS_PERMANENT;
238
239
if(status & basic)
203
- remove = ~0;
204
- else if(status & rcv)
205
- remove = basic | rcv;
206
- else if(status & snd)
207
- remove = snd;
240
+ remove = basic | receiver | ephemerality | sender;
241
+ else if(status & receiver)
242
+ remove = basic | receiver | ephemerality;
243
+ else if(status & sender)
244
+ remove = sender;
245
246
spinlock_lock(&p.spinlock);
247
PULSE_HOST_STATUS old = PHOST_GET(&p.index, (uintptr_t)host);
211
- if(status == PULSE_HOST_STATUS_DELETED)
248
+ if(status == PULSE_HOST_STATUS_DELETED) {
249
PHOST_DEL(&p.index, (uintptr_t)host);
250
+ status = 0; // do not add anything, just remove the old flags
251
+ }
252
else
253
PHOST_SET(&p.index, (uintptr_t)host, (old & ~remove) | status);
254
spinlock_unlock(&p.spinlock);
255
256
remove &= old;
218
- pulse_host_add_sub_status(remove, -1, 0);
257
220
- if(status != PULSE_HOST_STATUS_DELETED)
221
- pulse_host_add_sub_status(status, 1, reason);
258
+ pulse_host_add_sub_status(remove, -1, 0);
259
+ pulse_host_add_sub_status(status, 1, reason);
260
}
261
262
void pulse_parent_stream_info_received_request(void) {
288
289
// --------------------------------------------------------------------------------------------------------------------
290
253
-static void chart_by_reason(struct by_reason *b, const char *id, const char *context, const char *title, int priority) {
291
+static void chart_by_reason(struct by_reason *b, const char *id, const char *context, const char *title, const char *label, int priority) {
292
if(!b->st) {
293
b->st = rrdset_create_localhost(
294
"netdata"
316
317
b->rd[i] = rrddim_add(b->st, buf, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
318
}
319
+
320
+ rrdlabels_add(b->st->rrdlabels, "type", label, RRDLABEL_SRC_AUTO);
321
+
322
b->rd[STREAM_HANDSHAKE_STREAM_INFO] = rrddim_add(b->st, "info", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
323
b->rd[STREAM_HANDSHAKE_CONNECT] = rrddim_add(b->st, "connect", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
324
b->rd[STREAM_HANDSHAKE_OTHER] = rrddim_add(b->st, "other", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
332
333
void pulse_parents_do(bool extended) {
334
if(netdata_conf_is_parent()) {
294
- {
295
- static RRDSET *st_nodes = NULL;
296
- static RRDDIM *rd_loading = NULL;
297
- static RRDDIM *rd_local = NULL;
298
- static RRDDIM *rd_virtual = NULL;
299
- static RRDDIM *rd_archived = NULL;
300
- static RRDDIM *rd_offline = NULL;
301
- static RRDDIM *rd_waiting = NULL;
302
- static RRDDIM *rd_replication_waiting = NULL;
303
- static RRDDIM *rd_replicating = NULL;
304
- static RRDDIM *rd_running = NULL;
305
-
306
- if (unlikely(!st_nodes)) {
307
- st_nodes = rrdset_create_localhost(
335
+ for(size_t idx = 0; idx < _countof(p.parent.type) ; idx++) {
336
+ if (unlikely(!p.parent.type[idx].st_nodes)) {
337
+ const char *type;
338
+ const char *id;
339
+ if(idx == 0) {
340
+ type = "permanent";
341
+ id = "netdata.streaming_inbound_permanent";
342
+ }
343
+ else {
344
+ type = "ephemeral";
345
+ id = "netdata.streaming_inbound_ephemeral";
346
+ }
347
+
348
+ p.parent.type[idx].st_nodes = rrdset_create_localhost(
349
"netdata"
309
- , "streaming_inbound"
350
+ , id
351
, NULL
352
, "Streaming"
353
, "netdata.streaming_inbound"
360
, RRDSET_TYPE_LINE
361
);
362
322
- rd_local = rrddim_add(st_nodes, "local", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
323
- rd_virtual = rrddim_add(st_nodes, "virtual", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
324
- rd_loading = rrddim_add(st_nodes, "loading", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
325
- rd_archived = rrddim_add(st_nodes, "stale archived", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
326
- rd_offline = rrddim_add(st_nodes, "stale disconnected", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
327
- rd_waiting = rrddim_add(st_nodes, "waiting", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
328
- rd_replication_waiting = rrddim_add(st_nodes, "waiting replication", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
329
- rd_replicating = rrddim_add(st_nodes, "replicating", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
330
- rd_running = rrddim_add(st_nodes, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
363
+ rrdlabels_add(p.parent.type[idx].st_nodes->rrdlabels, "type", type, RRDLABEL_SRC_AUTO);
364
+
365
+ p.parent.type[idx].rd_local = rrddim_add(p.parent.type[idx].st_nodes, "local", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
366
+ p.parent.type[idx].rd_virtual = rrddim_add(p.parent.type[idx].st_nodes, "virtual", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
367
+ p.parent.type[idx].rd_loading = rrddim_add(p.parent.type[idx].st_nodes, "loading", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
368
+ p.parent.type[idx].rd_archived = rrddim_add(p.parent.type[idx].st_nodes, "stale archived", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
369
+ p.parent.type[idx].rd_offline = rrddim_add(p.parent.type[idx].st_nodes, "stale disconnected", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
370
+ p.parent.type[idx].rd_waiting = rrddim_add(p.parent.type[idx].st_nodes, "waiting", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
371
+ p.parent.type[idx].rd_replication_waiting = rrddim_add(p.parent.type[idx].st_nodes, "waiting replication", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
372
+ p.parent.type[idx].rd_replicating = rrddim_add(p.parent.type[idx].st_nodes, "replicating", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
373
+ p.parent.type[idx].rd_running = rrddim_add(p.parent.type[idx].st_nodes, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
374
}
375
333
- rrddim_set_by_pointer(st_nodes, rd_local, (collected_number)__atomic_load_n(&p.parent.nodes_local, __ATOMIC_RELAXED));
334
- rrddim_set_by_pointer(st_nodes, rd_virtual, (collected_number)__atomic_load_n(&p.parent.nodes_virtual, __ATOMIC_RELAXED));
335
- rrddim_set_by_pointer(st_nodes,rd_loading, (collected_number)__atomic_load_n(&p.parent.nodes_loading, __ATOMIC_RELAXED));
336
- rrddim_set_by_pointer(st_nodes, rd_archived, (collected_number)__atomic_load_n(&p.parent.nodes_archived, __ATOMIC_RELAXED));
337
- rrddim_set_by_pointer(st_nodes, rd_offline, (collected_number)__atomic_load_n(&p.parent.nodes_offline, __ATOMIC_RELAXED));
338
- rrddim_set_by_pointer(st_nodes, rd_waiting, (collected_number)__atomic_load_n(&p.parent.nodes_waiting, __ATOMIC_RELAXED));
339
- rrddim_set_by_pointer(st_nodes, rd_replication_waiting, (collected_number)__atomic_load_n(&p.parent.nodes_replication_waiting, __ATOMIC_RELAXED));
340
- rrddim_set_by_pointer(st_nodes, rd_replicating, (collected_number)__atomic_load_n(&p.parent.nodes_replicating, __ATOMIC_RELAXED));
341
- rrddim_set_by_pointer(st_nodes, rd_running, (collected_number)__atomic_load_n(&p.parent.nodes_running, __ATOMIC_RELAXED));
342
-
343
- rrdset_done(st_nodes);
376
+ rrddim_set_by_pointer(p.parent.type[idx].st_nodes, p.parent.type[idx].rd_local, (collected_number)__atomic_load_n(&p.parent.type[idx].nodes_local, __ATOMIC_RELAXED));
377
+ rrddim_set_by_pointer(p.parent.type[idx].st_nodes, p.parent.type[idx].rd_virtual, (collected_number)__atomic_load_n(&p.parent.type[idx].nodes_virtual, __ATOMIC_RELAXED));
378
+ rrddim_set_by_pointer(p.parent.type[idx].st_nodes,p.parent.type[idx].rd_loading, (collected_number)__atomic_load_n(&p.parent.type[idx].nodes_loading, __ATOMIC_RELAXED));
379
+ rrddim_set_by_pointer(p.parent.type[idx].st_nodes, p.parent.type[idx].rd_archived, (collected_number)__atomic_load_n(&p.parent.type[idx].nodes_archived, __ATOMIC_RELAXED));
380
+ rrddim_set_by_pointer(p.parent.type[idx].st_nodes, p.parent.type[idx].rd_offline, (collected_number)__atomic_load_n(&p.parent.type[idx].nodes_offline, __ATOMIC_RELAXED));
381
+ rrddim_set_by_pointer(p.parent.type[idx].st_nodes, p.parent.type[idx].rd_waiting, (collected_number)__atomic_load_n(&p.parent.type[idx].nodes_waiting, __ATOMIC_RELAXED));
382
+ rrddim_set_by_pointer(p.parent.type[idx].st_nodes, p.parent.type[idx].rd_replication_waiting, (collected_number)__atomic_load_n(&p.parent.type[idx].nodes_replication_waiting, __ATOMIC_RELAXED));
383
+ rrddim_set_by_pointer(p.parent.type[idx].st_nodes, p.parent.type[idx].rd_replicating, (collected_number)__atomic_load_n(&p.parent.type[idx].nodes_replicating, __ATOMIC_RELAXED));
384
+ rrddim_set_by_pointer(p.parent.type[idx].st_nodes, p.parent.type[idx].rd_running, (collected_number)__atomic_load_n(&p.parent.type[idx].nodes_running, __ATOMIC_RELAXED));
385
+
386
+ rrdset_done(p.parent.type[idx].st_nodes);
387
}
388
389
if(extended) {
392
"streaming_rejections_inbound",
393
"netdata.streaming_events_inbound",
394
"Inbound Streaming Events",
395
+ "rejections",
396
130151);
397
chart_by_reason(
398
&p.parent.disconnects_by_reason,
399
"streaming_disconnects_inbound",
400
"netdata.streaming_events_inbound",
401
"Inbound Streaming Events",
402
+ "disconnects",
403
130151);
404
}
405
}
414
static RRDDIM *rd_replicating = NULL;
415
static RRDDIM *rd_running = NULL;
416
static RRDDIM *rd_no_dst = NULL;
417
+ static RRDDIM *rd_no_dst_failed = NULL;
418
419
if (unlikely(!st_nodes)) {
420
st_nodes = rrdset_create_localhost(
427
, "nodes"
428
, "netdata"
429
, "pulse"
384
- , 130151
430
+ , 130153
431
, localhost->rrd_update_every
432
, RRDSET_TYPE_LINE
433
);
439
rd_replicating = rrddim_add(st_nodes, "replicating", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
440
rd_running = rrddim_add(st_nodes, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
441
rd_no_dst = rrddim_add(st_nodes, "no dst", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
442
+ rd_no_dst_failed = rrddim_add(st_nodes, "failed", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
443
}
444
445
rrddim_set_by_pointer(st_nodes, rd_connecting, (collected_number)__atomic_load_n(&p.sender.nodes_connecting, __ATOMIC_RELAXED));
449
rrddim_set_by_pointer(st_nodes, rd_replicating, (collected_number)__atomic_load_n(&p.sender.nodes_replicating, __ATOMIC_RELAXED));
450
rrddim_set_by_pointer(st_nodes, rd_running, (collected_number)__atomic_load_n(&p.sender.nodes_running, __ATOMIC_RELAXED));
451
rrddim_set_by_pointer(st_nodes, rd_no_dst, (collected_number)__atomic_load_n(&p.sender.nodes_no_dst, __ATOMIC_RELAXED));
452
+ rrddim_set_by_pointer(st_nodes, rd_no_dst_failed, (collected_number)__atomic_load_n(&p.sender.nodes_no_dst_failed, __ATOMIC_RELAXED));
453
454
rrdset_done(st_nodes);
455
}
460
"streaming_info_failed_outbound",
461
"netdata.streaming_events_outbound",
462
"Outbound Streaming Events",
415
- 130152);
463
+ "stream-info",
464
+ 130154);
465
chart_by_reason(
466
&p.sender.events_by_reason,
467
"streaming_rejections_outbound",
468
"netdata.streaming_events_outbound",
469
"Outbound Streaming Events",
421
- 130152);
470
+ "rejections",
471
+ 130154);
472
chart_by_reason(
473
&p.sender.disconnects_by_reason,
474
"streaming_disconnects_outbound",
475
"netdata.streaming_events_outbound",
476
"Outbound Streaming Events",
427
- 130152);
477
+ "disconnects",
478
+ 130154);
479
}
480
}
481
}