summaryrefslogtreecommitdiffstats
path: root/database/rrd.h
diff options
context:
space:
mode:
Diffstat (limited to 'database/rrd.h')
-rw-r--r--database/rrd.h173
1 files changed, 168 insertions, 5 deletions
diff --git a/database/rrd.h b/database/rrd.h
index 1572e62ab..3f57b9037 100644
--- a/database/rrd.h
+++ b/database/rrd.h
@@ -14,6 +14,14 @@ typedef struct rrdcalc RRDCALC;
typedef struct rrdcalctemplate RRDCALCTEMPLATE;
typedef struct alarm_entry ALARM_ENTRY;
+// forward declarations
+struct rrddim_volatile;
+#ifdef ENABLE_DBENGINE
+struct rrdeng_page_cache_descr;
+struct rrdengine_instance;
+struct pg_cache_page_index;
+#endif
+
#include "../daemon/common.h"
#include "web/api/queries/query.h"
#include "rrdvar.h"
@@ -66,7 +74,8 @@ typedef enum rrd_memory_mode {
RRD_MEMORY_MODE_RAM = 1,
RRD_MEMORY_MODE_MAP = 2,
RRD_MEMORY_MODE_SAVE = 3,
- RRD_MEMORY_MODE_ALLOC = 4
+ RRD_MEMORY_MODE_ALLOC = 4,
+ RRD_MEMORY_MODE_DBENGINE = 5
} RRD_MEMORY_MODE;
#define RRD_MEMORY_MODE_NONE_NAME "none"
@@ -74,6 +83,7 @@ typedef enum rrd_memory_mode {
#define RRD_MEMORY_MODE_MAP_NAME "map"
#define RRD_MEMORY_MODE_SAVE_NAME "save"
#define RRD_MEMORY_MODE_ALLOC_NAME "alloc"
+#define RRD_MEMORY_MODE_DBENGINE_NAME "dbengine"
extern RRD_MEMORY_MODE default_rrd_memory_mode;
@@ -178,7 +188,8 @@ struct rrddim {
char *cache_filename; // the filename we load/save from/to this set
size_t collections_counter; // the number of times we added values to this rrdim
- size_t unused[9];
+ struct rrddim_volatile *state; // volatile state that is not persistently stored
+ size_t unused[8];
collected_number collected_value_max; // the absolute maximum of the collected value
@@ -227,6 +238,90 @@ struct rrddim {
};
// ----------------------------------------------------------------------------
+// iterator state for RRD dimension data collection
+union rrddim_collect_handle {
+ struct {
+ long slot;
+ long entries;
+ } slotted; // state the legacy code uses
+#ifdef ENABLE_DBENGINE
+ struct rrdeng_collect_handle {
+ struct rrdeng_page_cache_descr *descr, *prev_descr;
+ unsigned long page_correlation_id;
+ struct rrdengine_instance *ctx;
+ struct pg_cache_page_index *page_index;
+ } rrdeng; // state the database engine uses
+#endif
+};
+
+// ----------------------------------------------------------------------------
+// iterator state for RRD dimension data queries
+struct rrddim_query_handle {
+ RRDDIM *rd;
+ time_t start_time;
+ time_t end_time;
+ union {
+ struct {
+ long slot;
+ long last_slot;
+ uint8_t finished;
+ } slotted; // state the legacy code uses
+#ifdef ENABLE_DBENGINE
+ struct rrdeng_query_handle {
+ struct rrdeng_page_cache_descr *descr;
+ struct rrdengine_instance *ctx;
+ struct pg_cache_page_index *page_index;
+ time_t now; //TODO: remove now to implement next point iteration
+ time_t dt; //TODO: remove dt to implement next point iteration
+ } rrdeng; // state the database engine uses
+#endif
+ };
+};
+
+
+// ----------------------------------------------------------------------------
+// volatile state per RRD dimension
+struct rrddim_volatile {
+#ifdef ENABLE_DBENGINE
+ uuid_t *rrdeng_uuid; // database engine metric UUID
+#endif
+ union rrddim_collect_handle handle;
+ // ------------------------------------------------------------------------
+ // function pointers that handle data collection
+ struct rrddim_collect_ops {
+ // an initialization function to run before starting collection
+ void (*init)(RRDDIM *rd);
+
+ // run this to store each metric into the database
+ void (*store_metric)(RRDDIM *rd, usec_t point_in_time, storage_number number);
+
+ // an finalization function to run after collection is over
+ void (*finalize)(RRDDIM *rd);
+ } collect_ops;
+
+ // function pointers that handle database queries
+ struct rrddim_query_ops {
+ // run this before starting a series of next_metric() database queries
+ void (*init)(RRDDIM *rd, struct rrddim_query_handle *handle, time_t start_time, time_t end_time);
+
+ // run this to load each metric number from the database
+ storage_number (*next_metric)(struct rrddim_query_handle *handle);
+
+ // run this to test if the series of next_metric() database queries is finished
+ int (*is_finished)(struct rrddim_query_handle *handle);
+
+ // run this after finishing a series of load_metric() database queries
+ void (*finalize)(struct rrddim_query_handle *handle);
+
+ // get the timestamp of the last entry of this metric
+ time_t (*latest_time)(RRDDIM *rd);
+
+ // get the timestamp of the first entry of this metric
+ time_t (*oldest_time)(RRDDIM *rd);
+ } query_ops;
+};
+
+// ----------------------------------------------------------------------------
// these loop macros make sure the linked list is accessed with the right lock
#define rrddim_foreach_read(rd, st) \
@@ -490,6 +585,22 @@ typedef struct alarm_log {
// ----------------------------------------------------------------------------
// RRD HOST
+struct rrdhost_system_info {
+ char *os_name;
+ char *os_id;
+ char *os_id_like;
+ char *os_version;
+ char *os_version_id;
+ char *os_detection;
+ char *kernel_name;
+ char *kernel_version;
+ char *architecture;
+ char *virtualization;
+ char *virt_detection;
+ char *container;
+ char *container_detection;
+};
+
struct rrdhost {
avl avl; // the index of hosts
@@ -512,6 +623,10 @@ struct rrdhost {
int rrd_update_every; // the update frequency of the host
long rrd_history_entries; // the number of history entries for the host's charts
+#ifdef ENABLE_DBENGINE
+ unsigned page_cache_mb; // Database Engine page cache size in MiB
+ unsigned disk_space_mb; // Database Engine disk space quota in MiB
+#endif
RRD_MEMORY_MODE rrd_memory_mode; // the memory more for the charts of this host
char *cache_dir; // the directory to save RRD cache files
@@ -520,6 +635,8 @@ struct rrdhost {
char *program_name; // the program name that collects metrics for this host
char *program_version; // the program version that collects metrics for this host
+ struct rrdhost_system_info *system_info; // information collected from the host environment
+
// ------------------------------------------------------------------------
// streaming of data to remote hosts - rrdpush
@@ -602,6 +719,10 @@ struct rrdhost {
avl_tree_lock rrdfamily_root_index; // the host's chart families index
avl_tree_lock rrdvar_root_index; // the host's chart variables index
+#ifdef ENABLE_DBENGINE
+ struct rrdengine_instance *rrdeng_ctx; // DB engine instance for this host
+#endif
+
struct rrdhost *next;
};
extern RRDHOST *localhost;
@@ -634,7 +755,7 @@ extern netdata_rwlock_t rrd_rwlock;
extern size_t rrd_hosts_available;
extern time_t rrdhost_free_orphan_time;
-extern void rrd_init(char *hostname);
+extern void rrd_init(char *hostname, struct rrdhost_system_info *system_info);
extern RRDHOST *rrdhost_find_by_hostname(const char *hostname, uint32_t hash);
extern RRDHOST *rrdhost_find_by_guid(const char *guid, uint32_t hash);
@@ -656,8 +777,12 @@ extern RRDHOST *rrdhost_find_or_create(
, char *rrdpush_destination
, char *rrdpush_api_key
, char *rrdpush_send_charts_matching
+ , struct rrdhost_system_info *system_info
);
+extern int rrdhost_set_system_info_variable(struct rrdhost_system_info *system_info, char *name, char *value);
+extern struct rrdhost_system_info *rrdhost_system_info_dup(struct rrdhost_system_info *system_info);
+
#if defined(NETDATA_INTERNAL_CHECKS) && defined(NETDATA_VERIFY_LOCKS)
extern void __rrdhost_check_wrlock(RRDHOST *host, const char *file, const char *function, const unsigned long line);
extern void __rrdhost_check_rdlock(RRDHOST *host, const char *file, const char *function, const unsigned long line);
@@ -714,6 +839,7 @@ extern void rrdhost_save_all(void);
extern void rrdhost_cleanup_all(void);
extern void rrdhost_cleanup_orphan_hosts_nolock(RRDHOST *protected);
+extern void rrdhost_system_info_free(struct rrdhost_system_info *system_info);
extern void rrdhost_free(RRDHOST *host);
extern void rrdhost_save_charts(RRDHOST *host);
extern void rrdhost_delete_charts(RRDHOST *host);
@@ -748,10 +874,41 @@ extern void rrdset_isnot_obsolete(RRDSET *st);
#define rrdset_duration(st) ((time_t)( (((st)->counter >= ((unsigned long)(st)->entries))?(unsigned long)(st)->entries:(st)->counter) * (st)->update_every ))
// get the timestamp of the last entry in the round robin database
-#define rrdset_last_entry_t(st) ((time_t)(((st)->last_updated.tv_sec)))
+static inline time_t rrdset_last_entry_t(RRDSET *st) {
+ if (st->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
+ RRDDIM *rd;
+ time_t last_entry_t = 0;
+
+ int ret = netdata_rwlock_tryrdlock(&st->rrdset_rwlock);
+ rrddim_foreach_read(rd, st) {
+ last_entry_t = MAX(last_entry_t, rd->state->query_ops.latest_time(rd));
+ }
+ if(0 == ret) netdata_rwlock_unlock(&st->rrdset_rwlock);
+
+ return last_entry_t;
+ } else {
+ return (time_t)st->last_updated.tv_sec;
+ }
+}
// get the timestamp of first entry in the round robin database
-#define rrdset_first_entry_t(st) ((time_t)(rrdset_last_entry_t(st) - rrdset_duration(st)))
+static inline time_t rrdset_first_entry_t(RRDSET *st) {
+ if (st->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
+ RRDDIM *rd;
+ time_t first_entry_t = LONG_MAX;
+
+ int ret = netdata_rwlock_tryrdlock(&st->rrdset_rwlock);
+ rrddim_foreach_read(rd, st) {
+ first_entry_t = MIN(first_entry_t, rd->state->query_ops.oldest_time(rd));
+ }
+ if(0 == ret) netdata_rwlock_unlock(&st->rrdset_rwlock);
+
+ if (unlikely(LONG_MAX == first_entry_t)) return 0;
+ return first_entry_t;
+ } else {
+ return (time_t)(rrdset_last_entry_t(st) - rrdset_duration(st));
+ }
+}
// get the last slot updated in the round robin database
#define rrdset_last_slot(st) ((size_t)(((st)->current_entry == 0) ? (st)->entries - 1 : (st)->current_entry - 1))
@@ -891,5 +1048,11 @@ extern void rrdhost_cleanup_obsolete_charts(RRDHOST *host);
#endif /* NETDATA_RRD_INTERNALS */
+// ----------------------------------------------------------------------------
+// RRD DB engine declarations
+
+#ifdef ENABLE_DBENGINE
+#include "database/engine/rrdengineapi.h"
+#endif
#endif /* NETDATA_RRD_H */