master
h 528 lines 23.7 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef NETDATA_RRDHOST_H
4 #define NETDATA_RRDHOST_H
5
6 #include "libnetdata/libnetdata.h"
7
8 #define HOST_LABEL_IS_EPHEMERAL "_is_ephemeral"
9 #define NETDATA_VIRTUAL_HOST "Netdata Virtual Host 1.0"
10
11 #define IS_VIRTUAL_HOST_OS(host) (strcmp(string2str(host->os), NETDATA_VIRTUAL_HOST) == 0)
12
13 struct stream_thread;
14 struct rrdset;
15
16 typedef struct rrdhost RRDHOST;
17 typedef struct ml_host rrd_ml_host_t;
18 typedef struct rrdhost_acquired RRDHOST_ACQUIRED;
19
20 //#include "streaming/stream-traffic-types.h"
21 #include "streaming/stream-sender-commit.h"
22 #include "rrd-database-mode.h"
23 //#include "streaming/stream-replication-tracking.h"
24 #include "streaming/stream-parents.h"
25 #include "streaming/stream-path.h"
26 #include "storage-engine.h"
27 //#include "streaming/stream-traffic-types.h"
28 #include "rrdlabels.h"
29 #include "health/health-alert-log.h"
30
31 struct rrdcontext;
32 DEFINE_JUDYL_TYPED_ADVANCED(RRDCONTEXT_QUEUE, struct rrdcontext *, JUDYL_TYPED_NO_CONVERSION, JUDYL_TYPED_NO_CONVERSION, \
33 SPINLOCK spinlock; \
34 Word_t id; \
35 uint32_t version; \
36 int32_t entries; \
37 );
38
39 // ----------------------------------------------------------------------------
40 // RRDHOST flags
41 // use this for configuration flags, not for state control
42 // flags are set/unset in a manner that is not thread safe
43 // and may lead to missing information.
44
45 typedef enum __attribute__ ((__packed__)) rrdhost_flags {
46
47 // Careful not to overlap with rrdhost_options to avoid bugs if
48 // rrdhost_flags_xxx is used instead of rrdhost_option_xxx or vice-versa
49 // Orphan, Archived and Obsolete flags
50
51 /*
52 * 3 BASE FLAGS FOR HOSTS:
53 *
54 * - COLLECTOR_ONLINE = the collector is currently collecting data for this node
55 * this is true FOR ALL KINDS OF NODES (including localhost, virtual hosts, children)
56 *
57 * - ORPHAN = the node had a collector online recently, but does not have it now
58 *
59 * - ARCHIVED = the node does not have data collection structures attached to it
60 *
61 */
62
63 RRDHOST_FLAG_COLLECTOR_ONLINE = (1 << 7), // the collector of this host is online
64 RRDHOST_FLAG_ORPHAN = (1 << 8), // this host is orphan (not receiving data)
65 RRDHOST_FLAG_ARCHIVED = (1 << 9), // The host is archived, no collected charts yet
66
67 RRDHOST_FLAG_PENDING_OBSOLETE_CHARTS = (1 << 10), // the host has pending chart obsoletions
68 RRDHOST_FLAG_PENDING_OBSOLETE_DIMENSIONS = (1 << 11), // the host has pending dimension obsoletions
69
70 // Streaming sender
71 RRDHOST_FLAG_STREAM_SENDER_INITIALIZED = (1 << 12), // the host has initialized streaming sender structures
72 RRDHOST_FLAG_STREAM_SENDER_ADDED = (1 << 13), // When set, the sender thread is running
73 RRDHOST_FLAG_STREAM_SENDER_CONNECTED = (1 << 14), // When set, the host is connected to a parent
74 RRDHOST_FLAG_STREAM_SENDER_READY_4_METRICS = (1 << 15), // when set, rrdset_done() should push metrics to parent
75 RRDHOST_FLAG_STREAM_SENDER_LOGGED_STATUS = (1 << 16), // when set, we have logged the status of metrics streaming
76
77 // Health
78 RRDHOST_FLAG_PENDING_HEALTH_INITIALIZATION = (1 << 17), // contains charts and dims with uninitialized variables
79 RRDHOST_FLAG_INITIALIZED_HEALTH = (1 << 18), // the host has initialized health structures
80
81 // Exporting
82 RRDHOST_FLAG_EXPORTING_SEND = (1 << 19), // send it to external databases
83 RRDHOST_FLAG_EXPORTING_DONT_SEND = (1 << 20), // don't send it to external databases
84
85 // ACLK
86 RRDHOST_FLAG_ACLK_STREAM_CONTEXTS = (1 << 21), // when set, we should send ACLK stream context updates
87 RRDHOST_FLAG_ACLK_STREAM_ALERTS = (1 << 22), // Host should stream alerts
88
89 // Metadata
90 RRDHOST_FLAG_METADATA_UPDATE = (1 << 23), // metadata needs to be stored in the database
91 RRDHOST_FLAG_METADATA_LABELS = (1 << 24), // metadata needs to be stored in the database
92 RRDHOST_FLAG_METADATA_INFO = (1 << 25), // metadata needs to be stored in the database
93 RRDHOST_FLAG_PENDING_CONTEXT_LOAD = (1 << 26), // Context needs to be loaded
94
95 RRDHOST_FLAG_METADATA_CLAIMID = (1 << 27), // metadata needs to be stored in the database
96
97 RRDHOST_FLAG_GLOBAL_FUNCTIONS_UPDATED = (1 << 28), // set when the host has updated global functions
98 RRDHOST_FLAG_RRDCONTEXT_GET_RETENTION = (1 << 29), // set when rrdcontext needs to update the retention of the host
99
100 RRDHOST_FLAG_OBSOLETE_ALL_IN_PROGRESS = (1 << 30), // svc_rrdhost_obsolete_all_charts() is running on this host;
101 // gates rrdhost_set_receiver() so a reconnect cannot attach
102 // mid-pass. Set under receiver_lock; the heavy work runs
103 // without holding receiver_lock so readers stay unblocked.
104
105 RRDHOST_FLAG_PENDING_LABEL_RECHECK = (1U << 31), // host labels changed since the last health prototype
106 // evaluation; on its next pass the health thread treats
107 // every chart of this host as needing a recheck, in
108 // addition to charts that have RRDSET_FLAG_PENDING_LABEL_RECHECK
109 // set individually (no per-chart flag fan-out).
110 } RRDHOST_FLAGS;
111
112 #define rrdhost_flag_get(host) atomic_flags_get(&((host)->flags))
113 #define rrdhost_flag_check(host, flag) atomic_flags_check(&((host)->flags), flag)
114 #define rrdhost_flag_set(host, flag) atomic_flags_set(&((host)->flags), flag)
115 #define rrdhost_flag_clear(host, flag) atomic_flags_clear(&((host)->flags), flag)
116 #define rrdhost_flag_set_and_clear(host, set, clear) atomic_flags_set_and_clear(&((host)->flags), set, clear)
117
118 typedef enum __attribute__ ((__packed__)) {
119 // Streaming configuration
120 RRDHOST_OPTION_SENDER_ENABLED = (1 << 0), // set when the host is configured to send metrics to a parent
121 RRDHOST_OPTION_REPLICATION = (1 << 1), // when set, we support replication for this host
122
123 // Other options
124 RRDHOST_OPTION_VIRTUAL_HOST = (1 << 2), // when set, this host is a virtual one
125 RRDHOST_OPTION_EPHEMERAL_HOST = (1 << 3), // when set, this host is an ephemeral one
126 } RRDHOST_OPTIONS;
127
128 #define rrdhost_option_check(host, flag) ((host)->options & (flag))
129 #define rrdhost_option_set(host, flag) (host)->options |= flag
130 #define rrdhost_option_clear(host, flag) (host)->options &= ~(flag)
131
132 #define rrdhost_has_stream_sender_enabled(host) (rrdhost_option_check(host, RRDHOST_OPTION_SENDER_ENABLED) && (host)->sender)
133
134 #define rrdhost_can_stream_metadata_to_parent(host) \
135 (rrdhost_has_stream_sender_enabled(host) && \
136 rrdhost_flag_check(host, RRDHOST_FLAG_STREAM_SENDER_READY_4_METRICS) && \
137 rrdhost_flag_check(host, RRDHOST_FLAG_COLLECTOR_ONLINE) \
138 )
139
140
141 struct rrdhost {
142 char machine_guid[GUID_LEN + 1]; // the unique ID of this host
143
144 // ------------------------------------------------------------------------
145 // host information
146
147 STRING *hostname; // the hostname of this host
148 STRING *registry_hostname; // the registry hostname for this host
149 STRING *os; // the O/S type of the host
150 STRING *timezone; // the timezone of the host
151 STRING *abbrev_timezone; // the abbriviated timezone of the host
152 STRING *program_name; // the program name that collects metrics for this host
153 STRING *program_version; // the program version that collects metrics for this host
154
155 uint32_t node_stale_after_seconds; // vnode stale timeout
156
157 OBJECT_STATE state_id; // every time data collection (stream receiver) (dis)connects,
158 // this gets incremented - it is used to detect stale functions,
159 // stale backfilling requests, etc.
160
161 int32_t utc_offset; // the offset in seconds from utc
162
163 RRDHOST_OPTIONS options; // configuration option for this RRDHOST (no atomics on this)
164 RRDHOST_FLAGS flags; // runtime flags about this RRDHOST (atomics on this)
165 RRDHOST_FLAGS *exporting_flags; // array of flags for exporting connector instances
166
167 int32_t rrd_update_every; // the update frequency of the host
168 int32_t rrd_history_entries; // the number of history entries for the host's charts
169
170 RRD_DB_MODE rrd_memory_mode; // the configured memory more for the charts of this host
171 // the actual per tier is at .db[tier].mode
172
173 char *cache_dir; // the directory to save RRD cache files
174
175 struct {
176 RRD_DB_MODE mode; // the db mode for this tier
177 STORAGE_ENGINE *eng; // the storage engine API for this tier
178 STORAGE_INSTANCE *si; // the db instance for this tier
179 uint32_t tier_grouping; // tier 0 iterations aggregated on this tier
180 } db[RRD_STORAGE_TIERS];
181
182 struct rrdhost_system_info *system_info; // information collected from the host environment
183
184 // ------------------------------------------------------------------------
185 // streaming and replication, configuration and status
186
187 struct {
188 struct stream_thread *thread;
189 uint8_t refcount;
190
191 // --- sender ---
192
193 struct {
194 struct {
195 struct {
196 SPINLOCK spinlock;
197
198 bool ignore; // when set, freeing slots will not put them in the available
199 uint32_t used;
200 uint32_t size;
201 uint32_t *array;
202 } available; // keep track of the available chart slots per host
203
204 uint32_t last_used; // the last slot we used for a chart (increments only)
205 } pluginsd_chart_slots;
206
207 struct {
208 pid_t tid;
209
210 time_t last_connected; // last time child connected (stored in db)
211 uint32_t connections; // the number of times this sender has connected
212 STREAM_HANDSHAKE reason; // the last receiver exit reason
213
214 struct {
215 uint32_t counter_in; // counts the number of replication statements we have received
216 uint32_t counter_out; // counts the number of replication statements we have sent
217 uint32_t charts; // the number of charts currently being replicated to a parent
218 } replication;
219 } status;
220
221 // reserved for the receiver/sender thread - do not use for other purposes
222 struct sender_buffer commit;
223
224 STRING *destination; // where to send metrics to
225 STRING *api_key; // the api key at the receiving netdata
226 SIMPLE_PATTERN *charts_matching; // pattern to match the charts to be sent
227 RRDHOST_STREAM_PARENTS parents; // the list of parents (extracted from destination)
228 } snd;
229
230 // --- receiver ---
231
232 struct {
233 struct {
234 SPINLOCK spinlock; // lock for the management of the allocation
235 uint32_t size;
236 struct rrdset **array;
237 } pluginsd_chart_slots;
238
239 struct {
240 pid_t tid;
241
242 time_t last_connected; // the time the last sender was connected
243 time_t last_disconnected; // the time the last sender was disconnected
244
245 uint32_t connections; // the number of times this receiver has connected
246 STREAM_HANDSHAKE reason; // the last receiver exit reason
247
248 struct {
249 uint32_t counter_in; // counts the number of replication statements we have received
250 uint32_t counter_out; // counts the number of replication statements we have sent
251 uint32_t backfill_pending; // the number of replication requests pending on us
252 uint32_t charts; // the number of charts currently being replicated from a child
253 NETDATA_DOUBLE percent; // the % of replication completion
254 } replication;
255 } status;
256 } rcv;
257
258 // --- configuration ---
259
260 struct {
261 time_t period; // max time we want to replicate from the child
262 time_t step; // seconds per replication step
263 } replication;
264
265 RRDHOST_STREAM_PATH path;
266 } stream;
267
268 // the following are state information for the threading
269 // streaming metrics from this netdata to an upstream netdata
270 struct sender_state *sender;
271
272 struct receiver_state *receiver;
273 SPINLOCK receiver_lock;
274
275 // ------------------------------------------------------------------------
276
277 struct aclk_sync_cfg_t *aclk_host_config;
278
279 // ------------------------------------------------------------------------
280 // health monitoring options
281
282 // health variables
283 HEALTH health;
284
285 // all RRDCALCs are primarily allocated and linked here
286 DICTIONARY *rrdcalc_root_index;
287
288 ALARM_LOG health_log; // alarms historical events (event log)
289 uint32_t health_last_processed_id; // the last processed health id from the log
290 uint32_t health_max_unique_id; // the max alarm log unique id given for the host
291 uint32_t health_max_alarm_id; // the max alarm id given for the host
292 size_t health_transitions; // the number of times an alert changed state
293
294 // ------------------------------------------------------------------------
295 // locks
296
297 SPINLOCK rrdhost_update_lock;
298
299 // ------------------------------------------------------------------------
300 // ML handle
301 rrd_ml_host_t *ml_host;
302
303 // ------------------------------------------------------------------------
304 // Support for host-level labels
305 RRDLABELS *rrdlabels;
306
307 // ------------------------------------------------------------------------
308 // Support for functions
309 DICTIONARY *functions; // collector functions this rrdset supports, can be NULL
310
311 // ------------------------------------------------------------------------
312 // indexes
313
314 DICTIONARY *rrdset_root_index; // the host's charts index (by id)
315 DICTIONARY *rrdset_root_index_name; // the host's charts index (by name)
316
317 DICTIONARY *rrdvars; // the host's chart variables index
318 // this includes custom host variables
319
320 struct {
321 uint32_t metrics_count; // atomic
322 uint32_t instances_count; // atomic
323 uint32_t contexts_count; // atomic
324 } collected;
325
326 struct {
327 DICTIONARY *contexts;
328 RRDCONTEXT_QUEUE_JudyLSet pp_queue;
329 RRDCONTEXT_QUEUE_JudyLSet hub_queue;
330 uint32_t metrics_count; // atomic
331 uint32_t instances_count; // atomic
332 uint32_t contexts_count; // atomic
333 } rrdctx;
334
335 struct {
336 SPINLOCK spinlock;
337 time_t first_time_s;
338 time_t last_time_s;
339 } retention;
340
341 ND_UUID host_id; // Global GUID for this host
342 ND_UUID node_id; // Cloud node_id
343
344 struct {
345 ND_UUID claim_id_of_origin;
346 ND_UUID claim_id_of_parent;
347 } aclk;
348
349 struct rrdhost *next;
350 struct rrdhost *prev;
351 };
352
353 extern RRDHOST *localhost;
354
355 // receiver_lock protects host->receiver and the host->stream.rcv.status fields.
356 //
357 // Hold time must stay short-bounded: no caller may hold receiver_lock across
358 // O(charts), I/O, sends, ML stop/start, or any wait on other subsystems. The
359 // obsolete-all cleanup pass (service.c) used to violate this; it now sets
360 // RRDHOST_FLAG_OBSOLETE_ALL_IN_PROGRESS under the lock and runs the heavy
361 // work without holding it. rrdhost_set_receiver() checks that flag under
362 // the lock and returns RRDHOST_SET_RECEIVER_CLEANUP_BUSY when the cleanup
363 // pass is in progress; the caller answers the child with BUSY_TRY_LATER and
364 // the child reconnects via normal backoff. With cleanup off the lock, all
365 // other readers (status, ACLK, capabilities, paths, event-driven sends)
366 // keep blocking-lock semantics and stay truthful.
367 #define rrdhost_receiver_lock(host) spinlock_lock(&(host)->receiver_lock)
368 #define rrdhost_receiver_unlock(host) spinlock_unlock(&(host)->receiver_lock)
369
370 #define rrdhost_hostname(host) string2str((host)->hostname)
371 #define rrdhost_registry_hostname(host) string2str((host)->registry_hostname)
372 #define rrdhost_os(host) string2str((host)->os)
373 // Timezone fields are mutable at runtime (DST refresh); use rrdhost_tz_get() for thread-safe access.
374 // Do NOT access host->timezone or host->abbrev_timezone directly outside of rrdhost_update_lock.
375 #define rrdhost_program_name(host) string2str((host)->program_name)
376 #define rrdhost_program_version(host) string2str((host)->program_version)
377
378 #define rrdhost_receiver_replicating_charts(host) (__atomic_load_n(&((host)->stream.rcv.status.replication.charts), __ATOMIC_RELAXED))
379 #define rrdhost_receiver_replicating_charts_plus_one(host) (__atomic_add_fetch(&((host)->stream.rcv.status.replication.charts), 1, __ATOMIC_RELAXED))
380 #define rrdhost_receiver_replicating_charts_minus_one(host) (__atomic_sub_fetch(&((host)->stream.rcv.status.replication.charts), 1, __ATOMIC_RELAXED))
381 #define rrdhost_receiver_replicating_charts_zero(host) (__atomic_store_n(&((host)->stream.rcv.status.replication.charts), 0, __ATOMIC_RELAXED))
382
383 #define rrdhost_sender_replicating_charts(host) (__atomic_load_n(&((host)->stream.snd.status.replication.charts), __ATOMIC_RELAXED))
384 #define rrdhost_sender_replicating_charts_plus_one(host) (__atomic_add_fetch(&((host)->stream.snd.status.replication.charts), 1, __ATOMIC_RELAXED))
385 #define rrdhost_sender_replicating_charts_minus_one(host) (__atomic_sub_fetch(&((host)->stream.snd.status.replication.charts), 1, __ATOMIC_RELAXED))
386 #define rrdhost_sender_replicating_charts_zero(host) (__atomic_store_n(&((host)->stream.snd.status.replication.charts), 0, __ATOMIC_RELAXED))
387
388 #define rrdhost_is_virtual(host) \
389 rrdhost_option_check(host, RRDHOST_OPTION_VIRTUAL_HOST)
390
391 #define rrdhost_is_local(host) ( \
392 (host) == localhost || \
393 rrdhost_is_virtual(host) \
394 )
395
396 #define rrdhost_is_online_flags(flags) ((flags & RRDHOST_FLAG_COLLECTOR_ONLINE) && !(flags & RRDHOST_FLAG_ORPHAN))
397
398 static inline bool rrdhost_is_online(RRDHOST *host) {
399 if(rrdhost_is_local(host))
400 return true;
401
402 RRDHOST_FLAGS flags = rrdhost_flag_get(host);
403 return rrdhost_is_online_flags(flags);
404 }
405
406 bool rrdhost_matches_window(RRDHOST *host, time_t after, time_t before, time_t now);
407
408 extern DICTIONARY *rrdhost_root_index;
409 size_t rrdhost_hosts_available(void);
410
411 RRDHOST_ACQUIRED *rrdhost_find_and_acquire(const char *machine_guid);
412 RRDHOST *rrdhost_acquired_to_rrdhost(RRDHOST_ACQUIRED *rha);
413 void rrdhost_acquired_release(RRDHOST_ACQUIRED *rha);
414
415 #define rrdhost_foreach_read(var) \
416 for((var) = localhost; var ; (var) = (var)->next)
417
418 #define rrdhost_foreach_write(var) \
419 for((var) = localhost; var ; (var) = (var)->next)
420
421 RRDHOST *rrdhost_find_by_hostname(const char *hostname);
422 RRDHOST *rrdhost_find_by_guid(const char *guid);
423 RRDHOST *rrdhost_find_by_node_id(const char *node_id);
424
425 #ifdef RRDHOST_INTERNALS
426 RRDHOST *rrdhost_create(
427 const char *hostname,
428 const char *registry_hostname,
429 const char *guid,
430 const char *os,
431 const char *timezone,
432 const char *abbrev_timezone,
433 int32_t utc_offset,
434 const char *prog_name,
435 const char *prog_version,
436 int update_every,
437 long entries,
438 RRD_DB_MODE memory_mode,
439 bool health,
440 bool stream,
441 STRING *parents,
442 STRING *api_key,
443 STRING *send_charts_matching,
444 bool replication,
445 time_t replication_period,
446 time_t replication_step,
447 struct rrdhost_system_info *system_info,
448 int is_localhost,
449 bool archived
450 );
451
452 void rrdhost_init(void);
453 #endif
454
455 RRDHOST *rrdhost_find_or_create(
456 const char *hostname,
457 const char *registry_hostname,
458 const char *guid,
459 const char *os,
460 const char *timezone,
461 const char *abbrev_timezone,
462 int32_t utc_offset,
463 const char *prog_name,
464 const char *prog_version,
465 int update_every,
466 long history,
467 RRD_DB_MODE mode,
468 bool health,
469 bool stream,
470 STRING *parents,
471 STRING *api_key,
472 STRING *send_charts_matching,
473 bool replication,
474 time_t replication_period,
475 time_t replication_step,
476 struct rrdhost_system_info *system_info,
477 bool is_archived);
478
479 void rrdhost_free_all(void);
480
481 void rrdhost_free___while_having_rrd_wrlock(RRDHOST *host);
482 void rrdhost_free___without_having_rrd_wrlock(RRDHOST *host);
483 void rrdhost_cleanup_data_collection_and_health(RRDHOST *host);
484
485 bool rrdhost_should_be_cleaned_up(RRDHOST *host, RRDHOST *protected_host, time_t now_s);
486 bool rrdhost_should_run_health(RRDHOST *host);
487
488 void set_host_properties(
489 RRDHOST *host, int update_every,
490 RRD_DB_MODE memory_mode, const char *registry_hostname,
491 const char *os, const char *tzone, const char *abbrev_tzone, int32_t utc_offset,
492 const char *prog_name, const char *prog_version);
493
494 bool rrdhost_update_timezone(RRDHOST *host, const char *timezone, const char *abbrev_timezone, int32_t utc_offset);
495
496 // Thread-safe timezone snapshot from an RRDHOST.
497 // The returned struct owns strdup'd copies; release with rrdhost_tz_free().
498 typedef struct {
499 char *timezone; // IANA timezone name (owned, strdup'd)
500 char *abbrev_timezone; // abbreviated timezone (owned, strdup'd)
501 int32_t utc_offset; // offset from UTC in seconds
502 } RRDHOST_TZ;
503
504 RRDHOST_TZ rrdhost_tz_get(RRDHOST *host);
505 void rrdhost_tz_free(RRDHOST_TZ *tz);
506
507 static inline void rrdhost_retention(RRDHOST *host, time_t now, bool online, time_t *from, time_t *to) {
508 time_t first_time_s = 0, last_time_s = 0;
509 spinlock_lock(&host->retention.spinlock);
510 first_time_s = host->retention.first_time_s;
511 last_time_s = host->retention.last_time_s;
512 spinlock_unlock(&host->retention.spinlock);
513
514 if(from)
515 *from = first_time_s;
516
517 if(to)
518 *to = online ? now : last_time_s;
519 }
520
521 extern time_t rrdhost_cleanup_orphan_to_archive_time_s;
522 extern time_t rrdhost_free_ephemeral_time_s;
523
524 #include "rrdhost-collection.h"
525 #include "rrdhost-slots.h"
526 #include "rrdhost-labels.h"
527
528 #endif //NETDATA_RRDHOST_H