summaryrefslogtreecommitdiffstats
path: root/database/rrd.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--database/rrd.h (renamed from src/rrd.h)227
1 files changed, 183 insertions, 44 deletions
diff --git a/src/rrd.h b/database/rrd.h
index d17daacd..19eb100c 100644
--- a/src/rrd.h
+++ b/database/rrd.h
@@ -1,6 +1,27 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
#ifndef NETDATA_RRD_H
#define NETDATA_RRD_H 1
+// forward typedefs
+typedef struct rrdhost RRDHOST;
+typedef struct rrddim RRDDIM;
+typedef struct rrdset RRDSET;
+typedef struct rrdvar RRDVAR;
+typedef struct rrdsetvar RRDSETVAR;
+typedef struct rrddimvar RRDDIMVAR;
+typedef struct rrdcalc RRDCALC;
+typedef struct rrdcalctemplate RRDCALCTEMPLATE;
+typedef struct alarm_entry ALARM_ENTRY;
+
+#include "../daemon/common.h"
+#include "web/api/queries/query.h"
+#include "rrdvar.h"
+#include "rrdsetvar.h"
+#include "rrddimvar.h"
+#include "rrdcalc.h"
+#include "rrdcalctemplate.h"
+
#define UPDATE_EVERY 1
#define UPDATE_EVERY_MAX 3600
@@ -19,8 +40,6 @@ extern int gap_when_lost_iterations_above;
typedef long long total_number;
#define TOTAL_NUMBER_FORMAT "%lld"
-typedef struct rrdhost RRDHOST;
-
// ----------------------------------------------------------------------------
// chart types
@@ -103,8 +122,8 @@ typedef struct rrdfamily RRDFAMILY;
typedef enum rrddim_flags {
RRDDIM_FLAG_NONE = 0,
- RRDDIM_FLAG_HIDDEN = 1 << 0, // this dimension will not be offered to callers
- RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS = 1 << 1 // do not offer RESET or OVERFLOW info to callers
+ RRDDIM_FLAG_HIDDEN = (1 << 0), // this dimension will not be offered to callers
+ RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS = (1 << 1) // do not offer RESET or OVERFLOW info to callers
} RRDDIM_FLAGS;
#ifdef HAVE_C___ATOMIC
@@ -159,8 +178,8 @@ struct rrddim {
size_t collections_counter; // the number of times we added values to this rrdim
size_t unused[10];
- int updated:1; // 1 when the dimension has been updated since the last processing
- int exposed:1; // 1 when set what have sent this dimension to the central netdata
+ unsigned int updated:1; // 1 when the dimension has been updated since the last processing
+ unsigned int exposed:1; // 1 when set what have sent this dimension to the central netdata
struct timeval last_collected_time; // when was this dimension last updated
// this is actual date time we updated the last_collected_value
@@ -202,7 +221,6 @@ struct rrddim {
storage_number values[]; // the array of values - THIS HAS TO BE THE LAST MEMBER
};
-typedef struct rrddim RRDDIM;
// ----------------------------------------------------------------------------
// these loop macros make sure the linked list is accessed with the right lock
@@ -222,18 +240,21 @@ typedef struct rrddim RRDDIM;
// and may lead to missing information.
typedef enum rrdset_flags {
- RRDSET_FLAG_ENABLED = 1 << 0, // enables or disables a chart
- RRDSET_FLAG_DETAIL = 1 << 1, // if set, the data set should be considered as a detail of another
+ RRDSET_FLAG_ENABLED = 1 << 0, // enables or disables a chart
+ RRDSET_FLAG_DETAIL = 1 << 1, // if set, the data set should be considered as a detail of another
// (the master data set should be the one that has the same family and is not detail)
- RRDSET_FLAG_DEBUG = 1 << 2, // enables or disables debugging for a chart
- RRDSET_FLAG_OBSOLETE = 1 << 3, // this is marked by the collector/module as obsolete
- RRDSET_FLAG_BACKEND_SEND = 1 << 4, // if set, this chart should be sent to backends
- RRDSET_FLAG_BACKEND_IGNORE = 1 << 5, // if set, this chart should not be sent to backends
- RRDSET_FLAG_EXPOSED_UPSTREAM = 1 << 6, // if set, we have sent this chart to netdata master (streaming)
- RRDSET_FLAG_STORE_FIRST = 1 << 7, // if set, do not eliminate the first collection during interpolation
- RRDSET_FLAG_HETEROGENEOUS = 1 << 8, // if set, the chart is not homogeneous (dimensions in it have multiple algorithms, multipliers or dividers)
- RRDSET_FLAG_HOMEGENEOUS_CHECK= 1 << 9, // if set, the chart should be checked to determine if the dimensions as homogeneous
- RRDSET_FLAG_HIDDEN = 1 << 10, // if set, do not show this chart on the dashboard, but use it for backends
+ RRDSET_FLAG_DEBUG = 1 << 2, // enables or disables debugging for a chart
+ RRDSET_FLAG_OBSOLETE = 1 << 3, // this is marked by the collector/module as obsolete
+ RRDSET_FLAG_BACKEND_SEND = 1 << 4, // if set, this chart should be sent to backends
+ RRDSET_FLAG_BACKEND_IGNORE = 1 << 5, // if set, this chart should not be sent to backends
+ RRDSET_FLAG_UPSTREAM_SEND = 1 << 6, // if set, this chart should be sent upstream (streaming)
+ RRDSET_FLAG_UPSTREAM_IGNORE = 1 << 7, // if set, this chart should not be sent upstream (streaming)
+ RRDSET_FLAG_UPSTREAM_EXPOSED = 1 << 8, // if set, we have sent this chart definition to netdata master (streaming)
+ RRDSET_FLAG_STORE_FIRST = 1 << 9, // if set, do not eliminate the first collection during interpolation
+ RRDSET_FLAG_HETEROGENEOUS = 1 << 10, // if set, the chart is not homogeneous (dimensions in it have multiple algorithms, multipliers or dividers)
+ RRDSET_FLAG_HOMEGENEOUS_CHECK = 1 << 11, // if set, the chart should be checked to determine if the dimensions as homogeneous
+ RRDSET_FLAG_HIDDEN = 1 << 12, // if set, do not show this chart on the dashboard, but use it for backends
+ RRDSET_FLAG_SYNC_CLOCK = 1 << 13, // if set, microseconds on next data collection will be ignored (the chart will be synced to now)
} RRDSET_FLAGS;
#ifdef HAVE_C___ATOMIC
@@ -245,6 +266,7 @@ typedef enum rrdset_flags {
#define rrdset_flag_set(st, flag) (st)->flags |= (flag)
#define rrdset_flag_clear(st, flag) (st)->flags &= ~(flag)
#endif
+#define rrdset_flag_check_noatomic(st, flag) ((st)->flags & (flag))
struct rrdset {
// ------------------------------------------------------------------------
@@ -282,7 +304,7 @@ struct rrdset {
long current_entry; // the entry that is currently being updated
// it goes around in a round-robin fashion
- uint32_t flags; // configuration flags
+ RRDSET_FLAGS flags; // configuration flags
int gap_when_lost_iterations_above; // after how many lost iterations a gap should be stored
// netdata will interpolate values for gaps lower than this
@@ -353,7 +375,6 @@ struct rrdset {
RRDDIM *dimensions; // the actual data for every dimension
};
-typedef struct rrdset RRDSET;
#define rrdset_rdlock(st) netdata_rwlock_rdlock(&((st)->rrdset_rwlock))
#define rrdset_wrlock(st) netdata_rwlock_wrlock(&((st)->rrdset_rwlock))
@@ -401,6 +422,65 @@ typedef enum rrdhost_flags {
#define rrdset_debug(st, fmt, args...) debug_dummy()
#endif
+// ----------------------------------------------------------------------------
+// Health data
+
+struct alarm_entry {
+ uint32_t unique_id;
+ uint32_t alarm_id;
+ uint32_t alarm_event_id;
+
+ time_t when;
+ time_t duration;
+ time_t non_clear_duration;
+
+ char *name;
+ uint32_t hash_name;
+
+ char *chart;
+ uint32_t hash_chart;
+
+ char *family;
+
+ char *exec;
+ char *recipient;
+ time_t exec_run_timestamp;
+ int exec_code;
+
+ char *source;
+ char *units;
+ char *info;
+
+ calculated_number old_value;
+ calculated_number new_value;
+
+ char *old_value_string;
+ char *new_value_string;
+
+ RRDCALC_STATUS old_status;
+ RRDCALC_STATUS new_status;
+
+ uint32_t flags;
+
+ int delay;
+ time_t delay_up_to_timestamp;
+
+ uint32_t updated_by_id;
+ uint32_t updates_id;
+
+ struct alarm_entry *next;
+};
+
+
+typedef struct alarm_log {
+ uint32_t next_log_id;
+ uint32_t next_alarm_id;
+ unsigned int count;
+ unsigned int max;
+ ALARM_ENTRY *alarms;
+ netdata_rwlock_t alarm_log_rwlock;
+} ALARM_LOG;
+
// ----------------------------------------------------------------------------
// RRD HOST
@@ -423,7 +503,7 @@ struct rrdhost {
const char *tags; // tags for this host
const char *timezone; // the timezone of the host
- uint32_t flags; // flags about this RRDHOST
+ RRDHOST_FLAGS flags; // flags about this 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
@@ -438,20 +518,22 @@ struct rrdhost {
// ------------------------------------------------------------------------
// streaming of data to remote hosts - rrdpush
- int rrdpush_send_enabled:1; // 1 when this host sends metrics to another netdata
+ unsigned int rrdpush_send_enabled:1; // 1 when this host sends metrics to another netdata
char *rrdpush_send_destination; // where to send metrics to
char *rrdpush_send_api_key; // the api key at the receiving netdata
// the following are state information for the threading
// streaming metrics from this netdata to an upstream netdata
- volatile int rrdpush_sender_spawn:1; // 1 when the sender thread has been spawn
+ volatile unsigned int rrdpush_sender_spawn:1; // 1 when the sender thread has been spawn
netdata_thread_t rrdpush_sender_thread; // the sender thread
- volatile int rrdpush_sender_connected:1; // 1 when the sender is ready to push metrics
+ volatile unsigned int rrdpush_sender_connected:1; // 1 when the sender is ready to push metrics
int rrdpush_sender_socket; // the fd of the socket to the remote host, or -1
- volatile int rrdpush_sender_error_shown:1; // 1 when we have logged a communication error
- volatile int rrdpush_sender_join:1; // 1 when we have to join the sending thread
+ volatile unsigned int rrdpush_sender_error_shown:1; // 1 when we have logged a communication error
+ volatile unsigned int rrdpush_sender_join:1; // 1 when we have to join the sending thread
+
+ SIMPLE_PATTERN *rrdpush_send_charts_matching; // pattern to match the charts to be sent
// metrics may be collected asynchronously
// these synchronize all the threads willing the write to our sending buffer
@@ -471,7 +553,7 @@ struct rrdhost {
// ------------------------------------------------------------------------
// health monitoring options
- int health_enabled:1; // 1 when this host has health enabled
+ unsigned int health_enabled:1; // 1 when this host has health enabled
time_t health_delay_up_to; // a timestamp to delay alarms processing up to
char *health_default_exec; // the full path of the alarms notifications program
char *health_default_recipient; // the default recipient for all alarms
@@ -564,10 +646,11 @@ extern RRDHOST *rrdhost_find_or_create(
, int update_every
, long history
, RRD_MEMORY_MODE mode
- , int health_enabled
- , int rrdpush_enabled
+ , unsigned int health_enabled
+ , unsigned int rrdpush_enabled
, char *rrdpush_destination
, char *rrdpush_api_key
+ , char *rrdpush_send_charts_matching
);
#if defined(NETDATA_INTERNAL_CHECKS) && defined(NETDATA_VERIFY_LOCKS)
@@ -666,28 +749,84 @@ extern void rrdset_isnot_obsolete(RRDSET *st);
#define rrdset_first_entry_t(st) ((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) ((unsigned long)(((st)->current_entry == 0) ? (st)->entries - 1 : (st)->current_entry - 1))
+#define rrdset_last_slot(st) ((size_t)(((st)->current_entry == 0) ? (st)->entries - 1 : (st)->current_entry - 1))
// get the first / oldest slot updated in the round robin database
-#define rrdset_first_slot(st) ((unsigned long)( (((st)->counter >= ((unsigned long)(st)->entries)) ? (unsigned long)( ((unsigned long)(st)->current_entry > 0) ? ((unsigned long)(st)->current_entry) : ((unsigned long)(st)->entries) ) - 1 : 0) ))
+// #define rrdset_first_slot(st) ((size_t)( (((st)->counter >= ((unsigned long)(st)->entries)) ? (unsigned long)( ((unsigned long)(st)->current_entry > 0) ? ((unsigned long)(st)->current_entry) : ((unsigned long)(st)->entries) ) - 1 : 0) ))
+
+// return the slot that has the oldest value
+
+static inline size_t rrdset_first_slot(RRDSET *st) {
+ if(st->counter >= (size_t)st->entries) {
+ // the database has been rotated at least once
+ // the oldest entry is the one that will be next
+ // overwritten by data collection
+ return (size_t)st->current_entry;
+ }
+
+ // we do not have rotated the db yet
+ // so 0 is the first entry
+ return 0;
+}
// get the slot of the round robin database, for the given timestamp (t)
// it always returns a valid slot, although may not be for the time requested if the time is outside the round robin database
-#define rrdset_time2slot(st, t) ( \
- ( (time_t)(t) >= rrdset_last_entry_t(st)) ? ( rrdset_last_slot(st) ) : \
- ( ((time_t)(t) <= rrdset_first_entry_t(st)) ? rrdset_first_slot(st) : \
- ( (rrdset_last_slot(st) >= (unsigned long)((rrdset_last_entry_t(st) - (time_t)(t)) / (unsigned long)((st)->update_every)) ) ? \
- (rrdset_last_slot(st) - (unsigned long)((rrdset_last_entry_t(st) - (time_t)(t)) / (unsigned long)((st)->update_every)) ) : \
- (rrdset_last_slot(st) - (unsigned long)((rrdset_last_entry_t(st) - (time_t)(t)) / (unsigned long)((st)->update_every)) + (unsigned long)(st)->entries ) \
- )))
+static inline size_t rrdset_time2slot(RRDSET *st, time_t t) {
+ size_t ret = 0;
+
+ if(t >= rrdset_last_entry_t(st)) {
+ // the requested time is after the last entry we have
+ ret = rrdset_last_slot(st);
+ }
+ else {
+ if(t <= rrdset_first_entry_t(st)) {
+ // the requested time is before the first entry we have
+ ret = rrdset_first_slot(st);
+ }
+ else {
+ if(rrdset_last_slot(st) >= ((rrdset_last_entry_t(st) - t) / (size_t)(st->update_every)))
+ ret = rrdset_last_slot(st) - ((rrdset_last_entry_t(st) - t) / (size_t)(st->update_every));
+ else
+ ret = rrdset_last_slot(st) - ((rrdset_last_entry_t(st) - t) / (size_t)(st->update_every)) + (unsigned long)st->entries;
+ }
+ }
+
+ if(unlikely(ret >= (size_t)st->entries)) {
+ error("INTERNAL ERROR: rrdset_time2slot() on %s returns values outside entries", st->name);
+ ret = (size_t)(st->entries - 1);
+ }
+
+ return ret;
+}
// get the timestamp of a specific slot in the round robin database
-#define rrdset_slot2time(st, slot) ( rrdset_last_entry_t(st) - \
- ((unsigned long)(st)->update_every * ( \
- ( (unsigned long)(slot) > rrdset_last_slot(st)) ? \
- ( (rrdset_last_slot(st) - (unsigned long)(slot) + (unsigned long)(st)->entries) ) : \
- ( (rrdset_last_slot(st) - (unsigned long)(slot)) )) \
- ))
+static inline time_t rrdset_slot2time(RRDSET *st, size_t slot) {
+ time_t ret;
+
+ if(slot >= (size_t)st->entries) {
+ error("INTERNAL ERROR: caller of rrdset_slot2time() gives invalid slot %zu", slot);
+ slot = (size_t)st->entries - 1;
+ }
+
+ if(slot > rrdset_last_slot(st)) {
+ ret = rrdset_last_entry_t(st) - (size_t)st->update_every * (rrdset_last_slot(st) - slot + (size_t)st->entries);
+ }
+ else {
+ ret = rrdset_last_entry_t(st) - (size_t)st->update_every;
+ }
+
+ if(unlikely(ret < rrdset_first_entry_t(st))) {
+ error("INTERNAL ERROR: rrdset_slot2time() on %s returns time too far in the past", st->name);
+ ret = rrdset_first_entry_t(st);
+ }
+
+ if(unlikely(ret > rrdset_last_entry_t(st))) {
+ error("INTERNAL ERROR: rrdset_slot2time() on %s returns time into the future", st->name);
+ ret = rrdset_last_entry_t(st);
+ }
+
+ return ret;
+}
// ----------------------------------------------------------------------------
// RRD DIMENSION functions