mirror of
https://github.com/netdata/netdata.git
synced 2025-04-17 03:02:41 +00:00
Provide more agent analytics to posthog (#11020)
* Move statistics related functions to analytics.c * error message change, space added after if * start an analytics thread * use heartbeat instead of sleep * add late enviroment (after rrdinit) pick of some attributes * change loop * re-enable info messages * remove possible new line * log and report hits on allmetrics pages. detect if exporting engines are enabled/in use, and report them * use lowercase for analytics variables * add collectors * add buildinfo * more attributes from late environment * add new attributes to v1/info * re-gather meta data before exit. update allmetrics counters to be available in v1/info * log hits to dashboard * add mirrored hosts * added notification methods * fix spaces, proper JSON naming * add alerts, charts and metrics count * more attributes * keep the thread up, and report a meta event every 2 hours * small formating changes. Disable analytics_log_prometheus when for unit testing. Add the new attributes to the anonymous-statistics.sh.in script * applied clang-format * dont gather data again on exit * safe buffer length in snprintfz * add rrdset lock * remove show_archived * remove setenv * calculate lengths during sets
This commit is contained in:
parent
dc567d5076
commit
e9ccc75a45
13 changed files with 1220 additions and 197 deletions
|
@ -828,6 +828,8 @@ set(DAEMON_FILES
|
|||
daemon/daemon.h
|
||||
daemon/global_statistics.c
|
||||
daemon/global_statistics.h
|
||||
daemon/analytics.c
|
||||
daemon/analytics.h
|
||||
daemon/main.c
|
||||
daemon/main.h
|
||||
daemon/signals.c
|
||||
|
|
|
@ -668,6 +668,8 @@ DAEMON_FILES = \
|
|||
daemon/daemon.h \
|
||||
daemon/global_statistics.c \
|
||||
daemon/global_statistics.h \
|
||||
daemon/analytics.c \
|
||||
daemon/analytics.h \
|
||||
daemon/main.c \
|
||||
daemon/main.h \
|
||||
daemon/signals.c \
|
||||
|
|
856
daemon/analytics.c
Normal file
856
daemon/analytics.c
Normal file
|
@ -0,0 +1,856 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct analytics_data analytics_data;
|
||||
extern void analytics_exporting_connectors (BUFFER *b);
|
||||
extern void analytics_build_info (BUFFER *b);
|
||||
extern int aclk_connected;
|
||||
|
||||
struct collector {
|
||||
char *plugin;
|
||||
char *module;
|
||||
};
|
||||
|
||||
struct array_printer {
|
||||
int c;
|
||||
BUFFER *both;
|
||||
};
|
||||
|
||||
/*
|
||||
* Debug logging
|
||||
*/
|
||||
void analytics_log_data(void)
|
||||
{
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_STREAM_ENABLED : [%s]", analytics_data.netdata_config_stream_enabled);
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_MEMORY_MODE : [%s]", analytics_data.netdata_config_memory_mode);
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_EXPORTING_ENABLED : [%s]", analytics_data.netdata_config_exporting_enabled);
|
||||
debug(D_ANALYTICS, "NETDATA_EXPORTING_CONNECTORS : [%s]", analytics_data.netdata_exporting_connectors);
|
||||
debug(D_ANALYTICS, "NETDATA_ALLMETRICS_PROMETHEUS_USED : [%s]", analytics_data.netdata_allmetrics_prometheus_used);
|
||||
debug(D_ANALYTICS, "NETDATA_ALLMETRICS_SHELL_USED : [%s]", analytics_data.netdata_allmetrics_shell_used);
|
||||
debug(D_ANALYTICS, "NETDATA_ALLMETRICS_JSON_USED : [%s]", analytics_data.netdata_allmetrics_json_used);
|
||||
debug(D_ANALYTICS, "NETDATA_DASHBOARD_USED : [%s]", analytics_data.netdata_dashboard_used);
|
||||
debug(D_ANALYTICS, "NETDATA_COLLECTORS : [%s]", analytics_data.netdata_collectors);
|
||||
debug(D_ANALYTICS, "NETDATA_COLLECTORS_COUNT : [%s]", analytics_data.netdata_collectors_count);
|
||||
debug(D_ANALYTICS, "NETDATA_BUILDINFO : [%s]", analytics_data.netdata_buildinfo);
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_PAGE_CACHE_SIZE : [%s]", analytics_data.netdata_config_page_cache_size);
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_MULTIDB_DISK_QUOTA : [%s]", analytics_data.netdata_config_multidb_disk_quota);
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_HTTPS_ENABLED : [%s]", analytics_data.netdata_config_https_enabled);
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_WEB_ENABLED : [%s]", analytics_data.netdata_config_web_enabled);
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_RELEASE_CHANNEL : [%s]", analytics_data.netdata_config_release_channel);
|
||||
debug(D_ANALYTICS, "NETDATA_MIRRORED_HOST_COUNT : [%s]", analytics_data.netdata_mirrored_host_count);
|
||||
debug(D_ANALYTICS, "NETDATA_MIRRORED_HOSTS_REACHABLE : [%s]", analytics_data.netdata_mirrored_hosts_reachable);
|
||||
debug(D_ANALYTICS, "NETDATA_MIRRORED_HOSTS_UNREACHABLE : [%s]", analytics_data.netdata_mirrored_hosts_unreachable);
|
||||
debug(D_ANALYTICS, "NETDATA_NOTIFICATION_METHODS : [%s]", analytics_data.netdata_notification_methods);
|
||||
debug(D_ANALYTICS, "NETDATA_ALARMS_NORMAL : [%s]", analytics_data.netdata_alarms_normal);
|
||||
debug(D_ANALYTICS, "NETDATA_ALARMS_WARNING : [%s]", analytics_data.netdata_alarms_warning);
|
||||
debug(D_ANALYTICS, "NETDATA_ALARMS_CRITICAL : [%s]", analytics_data.netdata_alarms_critical);
|
||||
debug(D_ANALYTICS, "NETDATA_CHARTS_COUNT : [%s]", analytics_data.netdata_charts_count);
|
||||
debug(D_ANALYTICS, "NETDATA_METRICS_COUNT : [%s]", analytics_data.netdata_metrics_count);
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_IS_PARENT : [%s]", analytics_data.netdata_config_is_parent);
|
||||
debug(D_ANALYTICS, "NETDATA_CONFIG_HOSTS_AVAILABLE : [%s]", analytics_data.netdata_config_hosts_available);
|
||||
debug(D_ANALYTICS, "NETDATA_HOST_CLOUD_AVAILABLE : [%s]", analytics_data.netdata_host_cloud_available);
|
||||
debug(D_ANALYTICS, "NETDATA_HOST_ACLK_AVAILABLE : [%s]", analytics_data.netdata_host_aclk_available);
|
||||
debug(D_ANALYTICS, "NETDATA_HOST_ACLK_IMPLEMENTATION : [%s]", analytics_data.netdata_host_aclk_implementation);
|
||||
debug(D_ANALYTICS, "NETDATA_HOST_AGENT_CLAIMED : [%s]", analytics_data.netdata_host_agent_claimed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free data
|
||||
*/
|
||||
void analytics_free_data(void)
|
||||
{
|
||||
freez(analytics_data.netdata_config_stream_enabled);
|
||||
freez(analytics_data.netdata_config_memory_mode);
|
||||
freez(analytics_data.netdata_config_exporting_enabled);
|
||||
freez(analytics_data.netdata_exporting_connectors);
|
||||
freez(analytics_data.netdata_allmetrics_prometheus_used);
|
||||
freez(analytics_data.netdata_allmetrics_shell_used);
|
||||
freez(analytics_data.netdata_allmetrics_json_used);
|
||||
freez(analytics_data.netdata_dashboard_used);
|
||||
freez(analytics_data.netdata_collectors);
|
||||
freez(analytics_data.netdata_collectors_count);
|
||||
freez(analytics_data.netdata_buildinfo);
|
||||
freez(analytics_data.netdata_config_page_cache_size);
|
||||
freez(analytics_data.netdata_config_multidb_disk_quota);
|
||||
freez(analytics_data.netdata_config_https_enabled);
|
||||
freez(analytics_data.netdata_config_web_enabled);
|
||||
freez(analytics_data.netdata_config_release_channel);
|
||||
freez(analytics_data.netdata_mirrored_host_count);
|
||||
freez(analytics_data.netdata_mirrored_hosts_reachable);
|
||||
freez(analytics_data.netdata_mirrored_hosts_unreachable);
|
||||
freez(analytics_data.netdata_notification_methods);
|
||||
freez(analytics_data.netdata_alarms_normal);
|
||||
freez(analytics_data.netdata_alarms_warning);
|
||||
freez(analytics_data.netdata_alarms_critical);
|
||||
freez(analytics_data.netdata_charts_count);
|
||||
freez(analytics_data.netdata_metrics_count);
|
||||
freez(analytics_data.netdata_config_is_parent);
|
||||
freez(analytics_data.netdata_config_hosts_available);
|
||||
freez(analytics_data.netdata_host_cloud_available);
|
||||
freez(analytics_data.netdata_host_aclk_available);
|
||||
freez(analytics_data.netdata_host_aclk_implementation);
|
||||
freez(analytics_data.netdata_host_agent_claimed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a numeric/boolean data with a value
|
||||
*/
|
||||
void analytics_set_data(char **name, char *value)
|
||||
{
|
||||
if (*name) {
|
||||
analytics_data.data_length -= strlen(*name);
|
||||
freez(*name);
|
||||
}
|
||||
*name = strdupz(value);
|
||||
analytics_data.data_length += strlen(*name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a string data with a value
|
||||
*/
|
||||
void analytics_set_data_str(char **name, char *value)
|
||||
{
|
||||
size_t value_string_len;
|
||||
if (*name) {
|
||||
analytics_data.data_length -= strlen(*name);
|
||||
freez(*name);
|
||||
}
|
||||
value_string_len = strlen(value) + 4;
|
||||
*name = mallocz(sizeof(char) * value_string_len);
|
||||
snprintfz(*name, value_string_len - 1, "\"%s\"", value);
|
||||
analytics_data.data_length += strlen(*name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get data, used by web api v1
|
||||
*/
|
||||
void analytics_get_data(char *name, BUFFER *wb)
|
||||
{
|
||||
buffer_strcat(wb, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Log hits on the allmetrics page, with prometheus parameter
|
||||
*/
|
||||
void analytics_log_prometheus(void)
|
||||
{
|
||||
if (likely(analytics_data.prometheus_hits < ANALYTICS_MAX_PROMETHEUS_HITS)) {
|
||||
analytics_data.prometheus_hits++;
|
||||
char b[7];
|
||||
snprintfz(b, 6, "%d", analytics_data.prometheus_hits);
|
||||
analytics_set_data(&analytics_data.netdata_allmetrics_prometheus_used, b);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Log hits on the allmetrics page, with shell parameter (or default)
|
||||
*/
|
||||
void analytics_log_shell(void)
|
||||
{
|
||||
if (likely(analytics_data.shell_hits < ANALYTICS_MAX_SHELL_HITS)) {
|
||||
analytics_data.shell_hits++;
|
||||
char b[7];
|
||||
snprintfz(b, 6, "%d", analytics_data.shell_hits);
|
||||
analytics_set_data(&analytics_data.netdata_allmetrics_shell_used, b);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Log hits on the allmetrics page, with json parameter
|
||||
*/
|
||||
void analytics_log_json(void)
|
||||
{
|
||||
if (likely(analytics_data.json_hits < ANALYTICS_MAX_JSON_HITS)) {
|
||||
analytics_data.json_hits++;
|
||||
char b[7];
|
||||
snprintfz(b, 6, "%d", analytics_data.json_hits);
|
||||
analytics_set_data(&analytics_data.netdata_allmetrics_json_used, b);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Log hits on the dashboard, (when calling HELLO).
|
||||
*/
|
||||
void analytics_log_dashboard(void)
|
||||
{
|
||||
if (likely(analytics_data.dashboard_hits < ANALYTICS_MAX_DASHBOARD_HITS)) {
|
||||
analytics_data.dashboard_hits++;
|
||||
char b[7];
|
||||
snprintfz(b, 6, "%d", analytics_data.dashboard_hits);
|
||||
analytics_set_data(&analytics_data.netdata_dashboard_used, b);
|
||||
}
|
||||
}
|
||||
|
||||
void analytics_mirrored_hosts(void)
|
||||
{
|
||||
RRDHOST *host;
|
||||
int count = 0;
|
||||
int reachable = 0;
|
||||
int unreachable = 0;
|
||||
char b[11];
|
||||
|
||||
rrd_rdlock();
|
||||
rrdhost_foreach_read(host)
|
||||
{
|
||||
if (rrdhost_flag_check(host, RRDHOST_FLAG_ARCHIVED))
|
||||
continue;
|
||||
|
||||
netdata_mutex_lock(&host->receiver_lock);
|
||||
((host->receiver || host == localhost) ? reachable++ : unreachable++);
|
||||
netdata_mutex_unlock(&host->receiver_lock);
|
||||
|
||||
count++;
|
||||
}
|
||||
rrd_unlock();
|
||||
|
||||
snprintfz(b, 10, "%d", count);
|
||||
analytics_set_data(&analytics_data.netdata_mirrored_host_count, b);
|
||||
snprintfz(b, 10, "%d", reachable);
|
||||
analytics_set_data(&analytics_data.netdata_mirrored_hosts_reachable, b);
|
||||
snprintfz(b, 10, "%d", unreachable);
|
||||
analytics_set_data(&analytics_data.netdata_mirrored_hosts_unreachable, b);
|
||||
}
|
||||
|
||||
void analytics_exporters(void)
|
||||
{
|
||||
//when no exporters are available, an empty string will be sent
|
||||
//decide if something else is more suitable (but propably not null)
|
||||
BUFFER *bi = buffer_create(1000);
|
||||
analytics_exporting_connectors(bi);
|
||||
analytics_set_data_str(&analytics_data.netdata_exporting_connectors, (char *)buffer_tostring(bi));
|
||||
buffer_free(bi);
|
||||
}
|
||||
|
||||
int collector_counter_callb(void *entry, void *data)
|
||||
{
|
||||
struct array_printer *ap = (struct array_printer *)data;
|
||||
struct collector *col = (struct collector *)entry;
|
||||
|
||||
BUFFER *bt = ap->both;
|
||||
|
||||
if (likely(ap->c)) {
|
||||
buffer_strcat(bt, ",");
|
||||
}
|
||||
|
||||
buffer_strcat(bt, "{");
|
||||
buffer_strcat(bt, " \"plugin\": \"");
|
||||
buffer_strcat(bt, col->plugin);
|
||||
buffer_strcat(bt, "\", \"module\":\"");
|
||||
buffer_strcat(bt, col->module);
|
||||
buffer_strcat(bt, "\" }");
|
||||
|
||||
(ap->c)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a JSON array of available collectors, same as in api/v1/info
|
||||
*/
|
||||
void analytics_collectors(void)
|
||||
{
|
||||
RRDSET *st;
|
||||
DICTIONARY *dict = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
|
||||
char name[500];
|
||||
BUFFER *bt = buffer_create(1000);
|
||||
|
||||
rrdset_foreach_read(st, localhost)
|
||||
{
|
||||
if (rrdset_is_available_for_viewers(st)) {
|
||||
struct collector col = { .plugin = st->plugin_name ? st->plugin_name : "",
|
||||
.module = st->module_name ? st->module_name : "" };
|
||||
snprintfz(name, 499, "%s:%s", col.plugin, col.module);
|
||||
dictionary_set(dict, name, &col, sizeof(struct collector));
|
||||
}
|
||||
}
|
||||
|
||||
struct array_printer ap;
|
||||
ap.c = 0;
|
||||
ap.both = bt;
|
||||
|
||||
dictionary_get_all(dict, collector_counter_callb, &ap);
|
||||
dictionary_destroy(dict);
|
||||
|
||||
analytics_set_data(&analytics_data.netdata_collectors, (char *)buffer_tostring(ap.both));
|
||||
|
||||
{
|
||||
char b[7];
|
||||
snprintfz(b, 6, "%d", ap.c);
|
||||
analytics_set_data(&analytics_data.netdata_collectors_count, b);
|
||||
}
|
||||
|
||||
buffer_free(bt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run alarm-notify.sh script using the dump_methods parameter
|
||||
* SEND_CUSTOM is always available
|
||||
*/
|
||||
void analytics_alarms_notifications(void)
|
||||
{
|
||||
char *script;
|
||||
script = mallocz(
|
||||
sizeof(char) * (strlen(netdata_configured_primary_plugins_dir) + strlen("alarm-notify.sh dump_methods") + 2));
|
||||
sprintf(script, "%s/%s", netdata_configured_primary_plugins_dir, "alarm-notify.sh");
|
||||
if (unlikely(access(script, R_OK) != 0)) {
|
||||
info("Alarm notify script %s not found.", script);
|
||||
freez(script);
|
||||
return;
|
||||
}
|
||||
|
||||
strcat(script, " dump_methods");
|
||||
|
||||
pid_t command_pid;
|
||||
|
||||
info("Executing %s", script);
|
||||
|
||||
BUFFER *b = buffer_create(1000);
|
||||
int cnt = 0;
|
||||
FILE *fp = mypopen(script, &command_pid);
|
||||
if (fp) {
|
||||
char line[200 + 1];
|
||||
|
||||
while (fgets(line, 200, fp) != NULL) {
|
||||
char *end = line;
|
||||
while (*end && *end != '\n')
|
||||
end++;
|
||||
*end = '\0';
|
||||
|
||||
if (likely(cnt))
|
||||
buffer_strcat(b, "|");
|
||||
|
||||
buffer_strcat(b, line);
|
||||
|
||||
cnt++;
|
||||
}
|
||||
mypclose(fp, command_pid);
|
||||
}
|
||||
freez(script);
|
||||
|
||||
analytics_set_data_str(&analytics_data.netdata_notification_methods, (char *)buffer_tostring(b));
|
||||
|
||||
buffer_free(b);
|
||||
}
|
||||
|
||||
void analytics_charts(void)
|
||||
{
|
||||
RRDSET *st;
|
||||
int c = 0;
|
||||
rrdset_foreach_read(st, localhost)
|
||||
{
|
||||
if (rrdset_is_available_for_viewers(st)) {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
{
|
||||
char b[7];
|
||||
snprintfz(b, 6, "%d", c);
|
||||
analytics_set_data(&analytics_data.netdata_charts_count, b);
|
||||
}
|
||||
}
|
||||
|
||||
void analytics_metrics(void)
|
||||
{
|
||||
RRDSET *st;
|
||||
long int dimensions = 0;
|
||||
RRDDIM *rd;
|
||||
rrdset_foreach_read(st, localhost)
|
||||
{
|
||||
rrdset_rdlock(st);
|
||||
rrddim_foreach_read(rd, st)
|
||||
{
|
||||
if (rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN) || rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE))
|
||||
continue;
|
||||
dimensions++;
|
||||
}
|
||||
rrdset_unlock(st);
|
||||
}
|
||||
{
|
||||
char b[7];
|
||||
snprintfz(b, 6, "%ld", dimensions);
|
||||
analytics_set_data(&analytics_data.netdata_metrics_count, b);
|
||||
}
|
||||
}
|
||||
|
||||
void analytics_alarms(void)
|
||||
{
|
||||
int alarm_warn = 0, alarm_crit = 0, alarm_normal = 0;
|
||||
char b[10];
|
||||
RRDCALC *rc;
|
||||
for (rc = localhost->alarms; rc; rc = rc->next) {
|
||||
if (unlikely(!rc->rrdset || !rc->rrdset->last_collected_time.tv_sec))
|
||||
continue;
|
||||
|
||||
switch (rc->status) {
|
||||
case RRDCALC_STATUS_WARNING:
|
||||
alarm_warn++;
|
||||
break;
|
||||
case RRDCALC_STATUS_CRITICAL:
|
||||
alarm_crit++;
|
||||
break;
|
||||
default:
|
||||
alarm_normal++;
|
||||
}
|
||||
}
|
||||
|
||||
snprintfz(b, 9, "%d", alarm_normal);
|
||||
analytics_set_data(&analytics_data.netdata_alarms_normal, b);
|
||||
snprintfz(b, 9, "%d", alarm_warn);
|
||||
analytics_set_data(&analytics_data.netdata_alarms_warning, b);
|
||||
snprintfz(b, 9, "%d", alarm_crit);
|
||||
analytics_set_data(&analytics_data.netdata_alarms_critical, b);
|
||||
}
|
||||
|
||||
/*
|
||||
* Misc attributes to get (run from meta)
|
||||
*/
|
||||
void analytics_misc(void)
|
||||
{
|
||||
#ifdef ENABLE_ACLK
|
||||
analytics_set_data(&analytics_data.netdata_host_cloud_available, "true");
|
||||
#ifdef ACLK_NG
|
||||
analytics_set_data_str(&analytics_data.netdata_host_aclk_implementation, "Next Generation");
|
||||
#else
|
||||
analytics_set_data_str(&analytics_data.netdata_host_aclk_implementation, "legacy");
|
||||
#endif
|
||||
#else
|
||||
analytics_set_data(&analytics_data.netdata_host_cloud_available, "false");
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ACLK
|
||||
if (aclk_connected)
|
||||
analytics_set_data(&analytics_data.netdata_host_aclk_available, "true");
|
||||
else
|
||||
#endif
|
||||
analytics_set_data(&analytics_data.netdata_host_aclk_available, "false");
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the meta data, called from the thread once after the original delay
|
||||
* These are values that won't change between agent restarts, and therefore
|
||||
* don't try to read them on each META event send
|
||||
*/
|
||||
void analytics_gather_immutable_meta_data(void)
|
||||
{
|
||||
analytics_misc();
|
||||
analytics_exporters();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the meta data, called from the thread on every heartbeat, and right before the EXIT event
|
||||
* These are values that can change between agent restarts, and therefore
|
||||
* try to read them on each META event send
|
||||
*/
|
||||
void analytics_gather_mutable_meta_data(void)
|
||||
{
|
||||
rrdhost_rdlock(localhost);
|
||||
|
||||
analytics_collectors();
|
||||
analytics_alarms();
|
||||
analytics_charts();
|
||||
analytics_metrics();
|
||||
|
||||
rrdhost_unlock(localhost);
|
||||
|
||||
analytics_mirrored_hosts();
|
||||
analytics_alarms_notifications();
|
||||
|
||||
analytics_set_data(
|
||||
&analytics_data.netdata_config_is_parent, (localhost->next || configured_as_parent()) ? "true" : "false");
|
||||
|
||||
if (is_agent_claimed())
|
||||
analytics_set_data(&analytics_data.netdata_host_agent_claimed, "true");
|
||||
else {
|
||||
analytics_set_data(&analytics_data.netdata_host_agent_claimed, "false");
|
||||
}
|
||||
|
||||
{
|
||||
char b[7];
|
||||
snprintfz(b, 6, "%d", analytics_data.prometheus_hits);
|
||||
analytics_set_data(&analytics_data.netdata_allmetrics_prometheus_used, b);
|
||||
|
||||
snprintfz(b, 6, "%d", analytics_data.shell_hits);
|
||||
analytics_set_data(&analytics_data.netdata_allmetrics_shell_used, b);
|
||||
|
||||
snprintfz(b, 6, "%d", analytics_data.json_hits);
|
||||
analytics_set_data(&analytics_data.netdata_allmetrics_json_used, b);
|
||||
|
||||
snprintfz(b, 6, "%d", analytics_data.dashboard_hits);
|
||||
analytics_set_data(&analytics_data.netdata_dashboard_used, b);
|
||||
|
||||
snprintfz(b, 6, "%zu", rrd_hosts_available);
|
||||
analytics_set_data(&analytics_data.netdata_config_hosts_available, b);
|
||||
}
|
||||
}
|
||||
|
||||
void analytics_main_cleanup(void *ptr)
|
||||
{
|
||||
struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
|
||||
static_thread->enabled = NETDATA_MAIN_THREAD_EXITING;
|
||||
|
||||
debug(D_ANALYTICS, "Cleaning up...");
|
||||
|
||||
static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
|
||||
}
|
||||
|
||||
/*
|
||||
* The analytics thread. Sleep for ANALYTICS_INIT_SLEEP_SEC,
|
||||
* gather the data, and then go to a loop where every ANALYTICS_HEARTBEAT
|
||||
* it will send a new META event after gathering data that could be changed
|
||||
* while the agent is running
|
||||
*/
|
||||
void *analytics_main(void *ptr)
|
||||
{
|
||||
netdata_thread_cleanup_push(analytics_main_cleanup, ptr);
|
||||
unsigned int sec = 0;
|
||||
heartbeat_t hb;
|
||||
heartbeat_init(&hb);
|
||||
usec_t step_ut = USEC_PER_SEC;
|
||||
|
||||
debug(D_ANALYTICS, "Analytics thread starts");
|
||||
|
||||
//first delay after agent start
|
||||
while (!netdata_exit && likely(sec <= ANALYTICS_INIT_SLEEP_SEC)) {
|
||||
heartbeat_next(&hb, step_ut);
|
||||
sec++;
|
||||
}
|
||||
|
||||
if (unlikely(netdata_exit))
|
||||
goto cleanup;
|
||||
|
||||
analytics_gather_immutable_meta_data();
|
||||
analytics_gather_mutable_meta_data();
|
||||
send_statistics("META", "-", "-");
|
||||
analytics_log_data();
|
||||
|
||||
sec = 0;
|
||||
while (1) {
|
||||
heartbeat_next(&hb, step_ut * 2);
|
||||
sec += 2;
|
||||
|
||||
if (unlikely(netdata_exit))
|
||||
break;
|
||||
|
||||
if (likely(sec < ANALYTICS_HEARTBEAT))
|
||||
continue;
|
||||
|
||||
analytics_gather_mutable_meta_data();
|
||||
send_statistics("META", "-", "-");
|
||||
analytics_log_data();
|
||||
sec = 0;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
netdata_thread_cleanup_pop(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *verify_required_directory(const char *dir)
|
||||
{
|
||||
if (chdir(dir) == -1)
|
||||
fatal("Cannot change directory to '%s'", dir);
|
||||
|
||||
DIR *d = opendir(dir);
|
||||
if (!d)
|
||||
fatal("Cannot examine the contents of directory '%s'", dir);
|
||||
closedir(d);
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called after the rrdinit
|
||||
* These values will be sent on the START event
|
||||
*/
|
||||
void set_late_global_environment()
|
||||
{
|
||||
analytics_set_data(&analytics_data.netdata_config_stream_enabled, default_rrdpush_enabled ? "true" : "false");
|
||||
analytics_set_data_str(&analytics_data.netdata_config_memory_mode, (char *)rrd_memory_mode_name(default_rrd_memory_mode));
|
||||
analytics_set_data(&analytics_data.netdata_config_exporting_enabled, appconfig_get_boolean(&exporting_config, CONFIG_SECTION_EXPORTING, "enabled", 1) ? "true" : "false");
|
||||
|
||||
#ifdef ENABLE_DBENGINE
|
||||
{
|
||||
char b[16];
|
||||
snprintfz(b, 15, "%d", default_rrdeng_page_cache_mb);
|
||||
analytics_set_data(&analytics_data.netdata_config_page_cache_size, b);
|
||||
|
||||
snprintfz(b, 15, "%d", default_multidb_disk_quota_mb);
|
||||
analytics_set_data(&analytics_data.netdata_config_multidb_disk_quota, b);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
analytics_set_data(&analytics_data.netdata_config_https_enabled, "true");
|
||||
#else
|
||||
analytics_set_data(&analytics_data.netdata_config_https_enabled, "false");
|
||||
#endif
|
||||
|
||||
if (web_server_mode == WEB_SERVER_MODE_NONE)
|
||||
analytics_set_data(&analytics_data.netdata_config_web_enabled, "false");
|
||||
else
|
||||
analytics_set_data(&analytics_data.netdata_config_web_enabled, "true");
|
||||
|
||||
analytics_set_data_str(&analytics_data.netdata_config_release_channel, (char *)get_release_channel());
|
||||
|
||||
{
|
||||
BUFFER *bi = buffer_create(1000);
|
||||
analytics_build_info(bi);
|
||||
analytics_set_data_str(&analytics_data.netdata_buildinfo, (char *)buffer_tostring(bi));
|
||||
buffer_free(bi);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_system_timezone(void)
|
||||
{
|
||||
// avoid flood calls to stat(/etc/localtime)
|
||||
// http://stackoverflow.com/questions/4554271/how-to-avoid-excessive-stat-etc-localtime-calls-in-strftime-on-linux
|
||||
const char *tz = getenv("TZ");
|
||||
if (!tz || !*tz)
|
||||
setenv("TZ", config_get(CONFIG_SECTION_GLOBAL, "TZ environment variable", ":/etc/localtime"), 0);
|
||||
|
||||
char buffer[FILENAME_MAX + 1] = "";
|
||||
const char *timezone = NULL;
|
||||
ssize_t ret;
|
||||
|
||||
// use the TZ variable
|
||||
if (tz && *tz && *tz != ':') {
|
||||
timezone = tz;
|
||||
info("TIMEZONE: using TZ variable '%s'", timezone);
|
||||
}
|
||||
|
||||
// use the contents of /etc/timezone
|
||||
if (!timezone && !read_file("/etc/timezone", buffer, FILENAME_MAX)) {
|
||||
timezone = buffer;
|
||||
info("TIMEZONE: using the contents of /etc/timezone: '%s'", timezone);
|
||||
}
|
||||
|
||||
// read the link /etc/localtime
|
||||
if (!timezone) {
|
||||
ret = readlink("/etc/localtime", buffer, FILENAME_MAX);
|
||||
|
||||
if (ret > 0) {
|
||||
buffer[ret] = '\0';
|
||||
|
||||
char *cmp = "/usr/share/zoneinfo/";
|
||||
size_t cmp_len = strlen(cmp);
|
||||
|
||||
char *s = strstr(buffer, cmp);
|
||||
if (s && s[cmp_len]) {
|
||||
timezone = &s[cmp_len];
|
||||
info("TIMEZONE: using the link of /etc/localtime: '%s'", timezone);
|
||||
}
|
||||
} else
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
|
||||
// find the timezone from strftime()
|
||||
if (!timezone) {
|
||||
time_t t;
|
||||
struct tm *tmp, tmbuf;
|
||||
|
||||
t = now_realtime_sec();
|
||||
tmp = localtime_r(&t, &tmbuf);
|
||||
|
||||
if (tmp != NULL) {
|
||||
if (strftime(buffer, FILENAME_MAX, "%Z", tmp) == 0)
|
||||
buffer[0] = '\0';
|
||||
else {
|
||||
buffer[FILENAME_MAX] = '\0';
|
||||
timezone = buffer;
|
||||
info("TIMEZONE: using strftime(): '%s'", timezone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timezone && *timezone) {
|
||||
// make sure it does not have illegal characters
|
||||
// info("TIMEZONE: fixing '%s'", timezone);
|
||||
|
||||
size_t len = strlen(timezone);
|
||||
char tmp[len + 1];
|
||||
char *d = tmp;
|
||||
*d = '\0';
|
||||
|
||||
while (*timezone) {
|
||||
if (isalnum(*timezone) || *timezone == '_' || *timezone == '/')
|
||||
*d++ = *timezone++;
|
||||
else
|
||||
timezone++;
|
||||
}
|
||||
*d = '\0';
|
||||
strncpyz(buffer, tmp, len);
|
||||
timezone = buffer;
|
||||
info("TIMEZONE: fixed as '%s'", timezone);
|
||||
}
|
||||
|
||||
if (!timezone || !*timezone)
|
||||
timezone = "unknown";
|
||||
|
||||
netdata_configured_timezone = config_get(CONFIG_SECTION_GLOBAL, "timezone", timezone);
|
||||
}
|
||||
|
||||
void set_global_environment()
|
||||
{
|
||||
{
|
||||
char b[16];
|
||||
snprintfz(b, 15, "%d", default_rrd_update_every);
|
||||
setenv("NETDATA_UPDATE_EVERY", b, 1);
|
||||
}
|
||||
|
||||
setenv("NETDATA_VERSION", program_version, 1);
|
||||
setenv("NETDATA_HOSTNAME", netdata_configured_hostname, 1);
|
||||
setenv("NETDATA_CONFIG_DIR", verify_required_directory(netdata_configured_user_config_dir), 1);
|
||||
setenv("NETDATA_USER_CONFIG_DIR", verify_required_directory(netdata_configured_user_config_dir), 1);
|
||||
setenv("NETDATA_STOCK_CONFIG_DIR", verify_required_directory(netdata_configured_stock_config_dir), 1);
|
||||
setenv("NETDATA_PLUGINS_DIR", verify_required_directory(netdata_configured_primary_plugins_dir), 1);
|
||||
setenv("NETDATA_WEB_DIR", verify_required_directory(netdata_configured_web_dir), 1);
|
||||
setenv("NETDATA_CACHE_DIR", verify_required_directory(netdata_configured_cache_dir), 1);
|
||||
setenv("NETDATA_LIB_DIR", verify_required_directory(netdata_configured_varlib_dir), 1);
|
||||
setenv("NETDATA_LOCK_DIR", netdata_configured_lock_dir, 1);
|
||||
setenv("NETDATA_LOG_DIR", verify_required_directory(netdata_configured_log_dir), 1);
|
||||
setenv("HOME", verify_required_directory(netdata_configured_home_dir), 1);
|
||||
setenv("NETDATA_HOST_PREFIX", netdata_configured_host_prefix, 1);
|
||||
|
||||
analytics_data.data_length = 0;
|
||||
analytics_set_data(&analytics_data.netdata_config_stream_enabled, "null");
|
||||
analytics_set_data(&analytics_data.netdata_config_memory_mode, "null");
|
||||
analytics_set_data(&analytics_data.netdata_config_exporting_enabled, "null");
|
||||
analytics_set_data(&analytics_data.netdata_exporting_connectors, "null");
|
||||
analytics_set_data(&analytics_data.netdata_allmetrics_prometheus_used, "null");
|
||||
analytics_set_data(&analytics_data.netdata_allmetrics_shell_used, "null");
|
||||
analytics_set_data(&analytics_data.netdata_allmetrics_json_used, "null");
|
||||
analytics_set_data(&analytics_data.netdata_dashboard_used, "null");
|
||||
analytics_set_data(&analytics_data.netdata_collectors, "null");
|
||||
analytics_set_data(&analytics_data.netdata_collectors_count, "null");
|
||||
analytics_set_data(&analytics_data.netdata_buildinfo, "null");
|
||||
analytics_set_data(&analytics_data.netdata_config_page_cache_size, "null");
|
||||
analytics_set_data(&analytics_data.netdata_config_multidb_disk_quota, "null");
|
||||
analytics_set_data(&analytics_data.netdata_config_https_enabled, "null");
|
||||
analytics_set_data(&analytics_data.netdata_config_web_enabled, "null");
|
||||
analytics_set_data(&analytics_data.netdata_config_release_channel, "null");
|
||||
analytics_set_data(&analytics_data.netdata_mirrored_host_count, "null");
|
||||
analytics_set_data(&analytics_data.netdata_mirrored_hosts_reachable, "null");
|
||||
analytics_set_data(&analytics_data.netdata_mirrored_hosts_unreachable, "null");
|
||||
analytics_set_data(&analytics_data.netdata_notification_methods, "null");
|
||||
analytics_set_data(&analytics_data.netdata_alarms_normal, "null");
|
||||
analytics_set_data(&analytics_data.netdata_alarms_warning, "null");
|
||||
analytics_set_data(&analytics_data.netdata_alarms_critical, "null");
|
||||
analytics_set_data(&analytics_data.netdata_charts_count, "null");
|
||||
analytics_set_data(&analytics_data.netdata_metrics_count, "null");
|
||||
analytics_set_data(&analytics_data.netdata_config_is_parent, "null");
|
||||
analytics_set_data(&analytics_data.netdata_config_hosts_available, "null");
|
||||
analytics_set_data(&analytics_data.netdata_host_cloud_available, "null");
|
||||
analytics_set_data(&analytics_data.netdata_host_aclk_implementation, "null");
|
||||
analytics_set_data(&analytics_data.netdata_host_aclk_available, "null");
|
||||
analytics_set_data(&analytics_data.netdata_host_agent_claimed, "null");
|
||||
|
||||
analytics_data.prometheus_hits = 0;
|
||||
analytics_data.shell_hits = 0;
|
||||
analytics_data.json_hits = 0;
|
||||
analytics_data.dashboard_hits = 0;
|
||||
|
||||
char *default_port = appconfig_get(&netdata_config, CONFIG_SECTION_WEB, "default port", NULL);
|
||||
int clean = 0;
|
||||
if (!default_port) {
|
||||
default_port = strdupz("19999");
|
||||
clean = 1;
|
||||
}
|
||||
|
||||
setenv("NETDATA_LISTEN_PORT", default_port, 1);
|
||||
if (clean)
|
||||
freez(default_port);
|
||||
|
||||
get_system_timezone();
|
||||
|
||||
// set the path we need
|
||||
char path[1024 + 1], *p = getenv("PATH");
|
||||
if (!p)
|
||||
p = "/bin:/usr/bin";
|
||||
snprintfz(path, 1024, "%s:%s", p, "/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin");
|
||||
setenv("PATH", config_get(CONFIG_SECTION_PLUGINS, "PATH environment variable", path), 1);
|
||||
|
||||
// python options
|
||||
p = getenv("PYTHONPATH");
|
||||
if (!p)
|
||||
p = "";
|
||||
setenv("PYTHONPATH", config_get(CONFIG_SECTION_PLUGINS, "PYTHONPATH environment variable", p), 1);
|
||||
|
||||
// disable buffering for python plugins
|
||||
setenv("PYTHONUNBUFFERED", "1", 1);
|
||||
|
||||
// switch to standard locale for plugins
|
||||
setenv("LC_ALL", "C", 1);
|
||||
}
|
||||
|
||||
void send_statistics(const char *action, const char *action_result, const char *action_data)
|
||||
{
|
||||
static char *as_script;
|
||||
|
||||
if (netdata_anonymous_statistics_enabled == -1) {
|
||||
char *optout_file = mallocz(
|
||||
sizeof(char) *
|
||||
(strlen(netdata_configured_user_config_dir) + strlen(".opt-out-from-anonymous-statistics") + 2));
|
||||
sprintf(optout_file, "%s/%s", netdata_configured_user_config_dir, ".opt-out-from-anonymous-statistics");
|
||||
if (likely(access(optout_file, R_OK) != 0)) {
|
||||
as_script = mallocz(
|
||||
sizeof(char) *
|
||||
(strlen(netdata_configured_primary_plugins_dir) + strlen("anonymous-statistics.sh") + 2));
|
||||
sprintf(as_script, "%s/%s", netdata_configured_primary_plugins_dir, "anonymous-statistics.sh");
|
||||
if (unlikely(access(as_script, R_OK) != 0)) {
|
||||
netdata_anonymous_statistics_enabled = 0;
|
||||
info("Anonymous statistics script %s not found.", as_script);
|
||||
freez(as_script);
|
||||
} else {
|
||||
netdata_anonymous_statistics_enabled = 1;
|
||||
}
|
||||
} else {
|
||||
netdata_anonymous_statistics_enabled = 0;
|
||||
as_script = NULL;
|
||||
}
|
||||
freez(optout_file);
|
||||
}
|
||||
if (!netdata_anonymous_statistics_enabled)
|
||||
return;
|
||||
if (!action)
|
||||
return;
|
||||
if (!action_result)
|
||||
action_result = "";
|
||||
if (!action_data)
|
||||
action_data = "";
|
||||
char *command_to_run = mallocz(
|
||||
sizeof(char) * (strlen(action) + strlen(action_result) + strlen(action_data) + strlen(as_script) +
|
||||
analytics_data.data_length + (ANALYTICS_NO_OF_ITEMS * 3) + 15));
|
||||
pid_t command_pid;
|
||||
|
||||
sprintf(
|
||||
command_to_run,
|
||||
"%s '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' ",
|
||||
as_script, action, action_result, action_data, analytics_data.netdata_config_stream_enabled,
|
||||
analytics_data.netdata_config_memory_mode, analytics_data.netdata_config_exporting_enabled,
|
||||
analytics_data.netdata_exporting_connectors, analytics_data.netdata_allmetrics_prometheus_used,
|
||||
analytics_data.netdata_allmetrics_shell_used, analytics_data.netdata_allmetrics_json_used,
|
||||
analytics_data.netdata_dashboard_used, analytics_data.netdata_collectors,
|
||||
analytics_data.netdata_collectors_count, analytics_data.netdata_buildinfo,
|
||||
analytics_data.netdata_config_page_cache_size, analytics_data.netdata_config_multidb_disk_quota,
|
||||
analytics_data.netdata_config_https_enabled, analytics_data.netdata_config_web_enabled,
|
||||
analytics_data.netdata_config_release_channel, analytics_data.netdata_mirrored_host_count,
|
||||
analytics_data.netdata_mirrored_hosts_reachable, analytics_data.netdata_mirrored_hosts_unreachable,
|
||||
analytics_data.netdata_notification_methods, analytics_data.netdata_alarms_normal,
|
||||
analytics_data.netdata_alarms_warning, analytics_data.netdata_alarms_critical,
|
||||
analytics_data.netdata_charts_count, analytics_data.netdata_metrics_count,
|
||||
analytics_data.netdata_config_is_parent, analytics_data.netdata_config_hosts_available,
|
||||
analytics_data.netdata_host_cloud_available, analytics_data.netdata_host_aclk_available,
|
||||
analytics_data.netdata_host_aclk_implementation, analytics_data.netdata_host_agent_claimed);
|
||||
|
||||
info("%s", command_to_run);
|
||||
|
||||
FILE *fp = mypopen(command_to_run, &command_pid);
|
||||
if (fp) {
|
||||
char buffer[100 + 1];
|
||||
while (fgets(buffer, 100, fp) != NULL)
|
||||
;
|
||||
mypclose(fp, command_pid);
|
||||
}
|
||||
freez(command_to_run);
|
||||
}
|
89
daemon/analytics.h
Normal file
89
daemon/analytics.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#ifndef NETDATA_ANALYTICS_H
|
||||
#define NETDATA_ANALYTICS_H 1
|
||||
|
||||
#include "../daemon/common.h"
|
||||
|
||||
/* Max number of seconds before the first META analytics is sent */
|
||||
#define ANALYTICS_INIT_SLEEP_SEC 120
|
||||
|
||||
/* Send a META event every X seconds */
|
||||
#define ANALYTICS_HEARTBEAT 7200
|
||||
|
||||
/* Maximum number of hits to log */
|
||||
#define ANALYTICS_MAX_PROMETHEUS_HITS 255
|
||||
#define ANALYTICS_MAX_SHELL_HITS 255
|
||||
#define ANALYTICS_MAX_JSON_HITS 255
|
||||
#define ANALYTICS_MAX_DASHBOARD_HITS 255
|
||||
|
||||
#define NETDATA_PLUGIN_HOOK_ANALYTICS \
|
||||
{ \
|
||||
.name = "ANALYTICS", \
|
||||
.config_section = NULL, \
|
||||
.config_name = NULL, \
|
||||
.enabled = 0, \
|
||||
.thread = NULL, \
|
||||
.init_routine = NULL, \
|
||||
.start_routine = analytics_main \
|
||||
},
|
||||
|
||||
/* Needed to calculate the space needed for parameters */
|
||||
#define ANALYTICS_NO_OF_ITEMS 31
|
||||
|
||||
struct analytics_data {
|
||||
char *netdata_config_stream_enabled;
|
||||
char *netdata_config_memory_mode;
|
||||
char *netdata_exporting_connectors;
|
||||
char *netdata_config_exporting_enabled;
|
||||
char *netdata_allmetrics_prometheus_used;
|
||||
char *netdata_allmetrics_shell_used;
|
||||
char *netdata_allmetrics_json_used;
|
||||
char *netdata_dashboard_used;
|
||||
char *netdata_collectors;
|
||||
char *netdata_collectors_count;
|
||||
char *netdata_buildinfo;
|
||||
char *netdata_config_page_cache_size;
|
||||
char *netdata_config_multidb_disk_quota;
|
||||
char *netdata_config_https_enabled;
|
||||
char *netdata_config_web_enabled;
|
||||
char *netdata_config_release_channel;
|
||||
char *netdata_mirrored_host_count;
|
||||
char *netdata_mirrored_hosts_reachable;
|
||||
char *netdata_mirrored_hosts_unreachable;
|
||||
char *netdata_notification_methods;
|
||||
char *netdata_alarms_normal;
|
||||
char *netdata_alarms_warning;
|
||||
char *netdata_alarms_critical;
|
||||
char *netdata_charts_count;
|
||||
char *netdata_metrics_count;
|
||||
char *netdata_config_is_parent;
|
||||
char *netdata_config_hosts_available;
|
||||
char *netdata_host_cloud_available;
|
||||
char *netdata_host_aclk_available;
|
||||
char *netdata_host_aclk_implementation;
|
||||
char *netdata_host_agent_claimed;
|
||||
|
||||
size_t data_length;
|
||||
|
||||
uint8_t prometheus_hits;
|
||||
uint8_t shell_hits;
|
||||
uint8_t json_hits;
|
||||
uint8_t dashboard_hits;
|
||||
};
|
||||
|
||||
extern void *analytics_main(void *ptr);
|
||||
extern void analytics_get_data(char *name, BUFFER *wb);
|
||||
extern void set_late_global_environment(void);
|
||||
extern void analytics_free_data(void);
|
||||
extern void set_global_environment(void);
|
||||
extern void send_statistics(const char *action, const char *action_result, const char *action_data);
|
||||
extern void analytics_log_shell(void);
|
||||
extern void analytics_log_json(void);
|
||||
extern void analytics_log_prometheus(void);
|
||||
extern void analytics_log_dashboard(void);
|
||||
extern void analytics_gather_mutable_meta_data(void);
|
||||
|
||||
extern struct analytics_data analytics_data;
|
||||
|
||||
#endif //NETDATA_ANALYTICS_H
|
|
@ -26,6 +26,39 @@ fi
|
|||
NETDATA_VERSION=$(echo "${NETDATA_VERSION}" | sed 's/-.*//g' | tr -d 'v')
|
||||
|
||||
# -------------------------------------------------------------------------------------------------
|
||||
# Get the extra variables
|
||||
|
||||
NETDATA_CONFIG_STREAM_ENABLED="${4}"
|
||||
NETDATA_CONFIG_MEMORY_MODE="${5}"
|
||||
NETDATA_CONFIG_EXPORTING_ENABLED="${6}"
|
||||
NETDATA_EXPORTING_CONNECTORS="${7}"
|
||||
NETDATA_ALLMETRICS_PROMETHEUS_USED="${8}"
|
||||
NETDATA_ALLMETRICS_SHELL_USED="${9}"
|
||||
NETDATA_ALLMETRICS_JSON_USED="${10}"
|
||||
NETDATA_DASHBOARD_USED="${11}"
|
||||
NETDATA_COLLECTORS="${12}"
|
||||
NETDATA_COLLECTORS_COUNT="${13}"
|
||||
NETDATA_BUILDINFO="${14}"
|
||||
NETDATA_CONFIG_PAGE_CACHE_SIZE="${15}"
|
||||
NETDATA_CONFIG_MULTIDB_DISK_QUOTA="${16}"
|
||||
NETDATA_CONFIG_HTTPS_ENABLED="${17}"
|
||||
NETDATA_CONFIG_WEB_ENABLED="${18}"
|
||||
NETDATA_CONFIG_RELEASE_CHANNEL="${19}"
|
||||
NETDATA_MIRRORED_HOST_COUNT="${20}"
|
||||
NETDATA_MIRRORED_HOSTS_REACHABLE="${21}"
|
||||
NETDATA_MIRRORED_HOSTS_UNREACHABLE="${22}"
|
||||
NETDATA_NOTIFICATION_METHODS="${23}"
|
||||
NETDATA_ALARMS_NORMAL="${24}"
|
||||
NETDATA_ALARMS_WARNING="${25}"
|
||||
NETDATA_ALARMS_CRITICAL="${26}"
|
||||
NETDATA_CHARTS_COUNT="${27}"
|
||||
NETDATA_METRICS_COUNT="${28}"
|
||||
NETDATA_CONFIG_IS_PARENT="${29}"
|
||||
NETDATA_CONFIG_HOSTS_AVAILABLE="${30}"
|
||||
NETDATA_HOST_CLOUD_AVAILABLE="${31}"
|
||||
NETDATA_HOST_ACLK_AVAILABLE="${32}"
|
||||
NETDATA_HOST_ACLK_IMPLEMENTATION="${33}"
|
||||
NETDATA_HOST_AGENT_CLAIMED="${34}"
|
||||
|
||||
# define body of request to be sent
|
||||
REQ_BODY="$(cat << EOF
|
||||
|
@ -44,6 +77,8 @@ REQ_BODY="$(cat << EOF
|
|||
"action_data": "${ACTION_DATA}",
|
||||
"netdata_machine_guid": "${NETDATA_REGISTRY_UNIQUE_ID}",
|
||||
"netdata_version": "${NETDATA_VERSION}",
|
||||
"netdata_buildinfo": ${NETDATA_BUILDINFO},
|
||||
"netdata_release_channel": ${NETDATA_CONFIG_RELEASE_CHANNEL},
|
||||
"host_os_name": "${NETDATA_HOST_OS_NAME}",
|
||||
"host_os_id": "${NETDATA_HOST_OS_ID}",
|
||||
"host_os_id_like": "${NETDATA_HOST_OS_ID_LIKE}",
|
||||
|
@ -72,7 +107,38 @@ REQ_BODY="$(cat << EOF
|
|||
"system_disk_detection": "${NETDATA_SYSTEM_DISK_DETECTION}",
|
||||
"system_ram_detection": "${NETDATA_SYSTEM_RAM_DETECTION}",
|
||||
"system_total_disk_size": "${NETDATA_SYSTEM_TOTAL_DISK_SIZE}",
|
||||
"system_total_ram": "${NETDATA_SYSTEM_TOTAL_RAM}"
|
||||
"system_total_ram": "${NETDATA_SYSTEM_TOTAL_RAM}",
|
||||
"config_stream_enabled": ${NETDATA_CONFIG_STREAM_ENABLED},
|
||||
"config_memory_mode": ${NETDATA_CONFIG_MEMORY_MODE},
|
||||
"config_page_cache_size": ${NETDATA_CONFIG_PAGE_CACHE_SIZE},
|
||||
"config_multidb_disk_quota": ${NETDATA_CONFIG_MULTIDB_DISK_QUOTA},
|
||||
"config_https_enabled": ${NETDATA_CONFIG_HTTPS_ENABLED},
|
||||
"config_web_enabled": ${NETDATA_CONFIG_WEB_ENABLED},
|
||||
"config_exporting_enabled": ${NETDATA_CONFIG_EXPORTING_ENABLED},
|
||||
"config_is_parent": ${NETDATA_CONFIG_IS_PARENT},
|
||||
"config_hosts_available": ${NETDATA_CONFIG_HOSTS_AVAILABLE},
|
||||
"alarms_normal": ${NETDATA_ALARMS_NORMAL},
|
||||
"alarms_warning": ${NETDATA_ALARMS_WARNING},
|
||||
"alarms_critical": ${NETDATA_ALARMS_CRITICAL},
|
||||
"host_charts_count": ${NETDATA_CHARTS_COUNT},
|
||||
"host_metrics_count": ${NETDATA_METRICS_COUNT},
|
||||
"host_collectors":[
|
||||
${NETDATA_COLLECTORS}
|
||||
],
|
||||
"host_collectors_count": ${NETDATA_COLLECTORS_COUNT},
|
||||
"host_notification_methods": ${NETDATA_NOTIFICATION_METHODS},
|
||||
"host_allmetrics_prometheus_used": ${NETDATA_ALLMETRICS_PROMETHEUS_USED},
|
||||
"host_allmetrics_shell_used": ${NETDATA_ALLMETRICS_SHELL_USED},
|
||||
"host_allmetrics_json_used": ${NETDATA_ALLMETRICS_JSON_USED},
|
||||
"host_dashboard_used": ${NETDATA_DASHBOARD_USED},
|
||||
"host_cloud_available": ${NETDATA_HOST_CLOUD_AVAILABLE},
|
||||
"host_agent_claimed": ${NETDATA_HOST_AGENT_CLAIMED},
|
||||
"host_aclk_available": ${NETDATA_HOST_ACLK_AVAILABLE},
|
||||
"host_aclk_implementation": ${NETDATA_HOST_ACLK_IMPLEMENTATION},
|
||||
"mirrored_host_count": ${NETDATA_MIRRORED_HOST_COUNT},
|
||||
"mirrored_hosts_reachable": ${NETDATA_MIRRORED_HOSTS_REACHABLE},
|
||||
"mirrored_hosts_unreachable": ${NETDATA_MIRRORED_HOSTS_UNREACHABLE},
|
||||
"exporting_connectors": ${NETDATA_EXPORTING_CONNECTORS}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include "./config.h"
|
||||
#include "common.h"
|
||||
|
||||
// Optional features
|
||||
|
||||
|
@ -312,3 +313,49 @@ void print_build_info_json(void) {
|
|||
printf(" }\n");
|
||||
printf("}\n");
|
||||
};
|
||||
|
||||
//return a list of enabled features for use in analytics
|
||||
//find a way to have proper |
|
||||
void analytics_build_info(BUFFER *b) {
|
||||
if(FEAT_DBENGINE) buffer_strcat (b, "dbengine");
|
||||
if(FEAT_NATIVE_HTTPS) buffer_strcat (b, "|Native HTTPS");
|
||||
if(FEAT_CLOUD) buffer_strcat (b, "|Netdata Cloud");
|
||||
if(FEAT_TLS_HOST_VERIFY) buffer_strcat (b, "|TLS Host Verification");
|
||||
|
||||
if(FEAT_JEMALLOC) buffer_strcat (b, "|jemalloc");
|
||||
if(FEAT_JSONC) buffer_strcat (b, "|JSON-C");
|
||||
if(FEAT_LIBCAP) buffer_strcat (b, "|libcap");
|
||||
if(FEAT_CRYPTO) buffer_strcat (b, "|libcrypto");
|
||||
if(FEAT_LIBM) buffer_strcat (b, "|libm");
|
||||
|
||||
#ifndef ACLK_NG
|
||||
#if defined(ENABLE_ACLK)
|
||||
{
|
||||
char buf[20];
|
||||
snprintfz(buf, 19, "|LWS v%d.%d.%d", LWS_LIBRARY_VERSION_MAJOR, LWS_LIBRARY_VERSION_MINOR, LWS_LIBRARY_VERSION_PATCH);
|
||||
if(FEAT_LWS) buffer_strcat(b, buf);
|
||||
}
|
||||
#else
|
||||
if(FEAT_LWS) buffer_strcat(b, "|LWS");
|
||||
#endif
|
||||
if(FEAT_MOSQUITTO) buffer_strcat(b, "|mosquitto");
|
||||
#endif
|
||||
if(FEAT_TCMALLOC) buffer_strcat(b, "|tcalloc");
|
||||
if(FEAT_ZLIB) buffer_strcat(b, "|zlib");
|
||||
|
||||
if(FEAT_APPS_PLUGIN) buffer_strcat(b, "|apps");
|
||||
if(FEAT_CGROUP_NET) buffer_strcat(b, "|cgroup Network Tracking");
|
||||
if(FEAT_CUPS) buffer_strcat(b, "|CUPS");
|
||||
if(FEAT_EBPF) buffer_strcat(b, "|EBPF");
|
||||
if(FEAT_IPMI) buffer_strcat(b, "|IPMI");
|
||||
if(FEAT_NFACCT) buffer_strcat(b, "|NFACCT");
|
||||
if(FEAT_PERF) buffer_strcat(b, "|perf");
|
||||
if(FEAT_SLABINFO) buffer_strcat(b, "|slabinfo");
|
||||
if(FEAT_XEN) buffer_strcat(b, "|Xen");
|
||||
if(FEAT_XEN_VBD_ERROR) buffer_strcat(b, "|Xen VBD Error Tracking");
|
||||
|
||||
if(FEAT_KINESIS) buffer_strcat(b, "|AWS Kinesis");
|
||||
if(FEAT_PUBSUB) buffer_strcat(b, "|GCP PubSub");
|
||||
if(FEAT_MONGO) buffer_strcat(b, "|MongoDB");
|
||||
if(FEAT_REMOTE_WRITE) buffer_strcat(b, "|Prometheus Remote Write");
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
#include "main.h"
|
||||
#include "signals.h"
|
||||
#include "commands.h"
|
||||
#include "analytics.h"
|
||||
|
||||
// global netdata daemon variables
|
||||
extern char *netdata_configured_hostname;
|
||||
|
|
211
daemon/main.c
211
daemon/main.c
|
@ -28,6 +28,7 @@ void netdata_cleanup_and_exit(int ret) {
|
|||
info("EXIT: netdata prepares to exit with code %d...", ret);
|
||||
|
||||
send_statistics("EXIT", ret?"ERROR":"OK","-");
|
||||
analytics_free_data();
|
||||
|
||||
char agent_crash_file[FILENAME_MAX + 1];
|
||||
snprintfz(agent_crash_file, FILENAME_MAX, "%s/.agent_crash", netdata_configured_varlib_dir);
|
||||
|
@ -99,6 +100,7 @@ struct netdata_static_thread static_threads[] = {
|
|||
|
||||
NETDATA_PLUGIN_HOOK_PLUGINSD
|
||||
NETDATA_PLUGIN_HOOK_HEALTH
|
||||
NETDATA_PLUGIN_HOOK_ANALYTICS
|
||||
|
||||
{NULL, NULL, NULL, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
@ -397,18 +399,6 @@ void remove_option(int opt_index, int *argc, char **argv) {
|
|||
} while(argv[i][0] != '-' && opt_index >= *argc);
|
||||
}
|
||||
|
||||
static const char *verify_required_directory(const char *dir) {
|
||||
if(chdir(dir) == -1)
|
||||
fatal("Cannot cd to directory '%s'", dir);
|
||||
|
||||
DIR *d = opendir(dir);
|
||||
if(!d)
|
||||
fatal("Cannot examine the contents of directory '%s'", dir);
|
||||
closedir(d);
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
static void security_init(){
|
||||
char filename[FILENAME_MAX + 1];
|
||||
|
@ -612,147 +602,6 @@ static void get_netdata_configured_variables() {
|
|||
|
||||
}
|
||||
|
||||
static void get_system_timezone(void) {
|
||||
// avoid flood calls to stat(/etc/localtime)
|
||||
// http://stackoverflow.com/questions/4554271/how-to-avoid-excessive-stat-etc-localtime-calls-in-strftime-on-linux
|
||||
const char *tz = getenv("TZ");
|
||||
if(!tz || !*tz)
|
||||
setenv("TZ", config_get(CONFIG_SECTION_GLOBAL, "TZ environment variable", ":/etc/localtime"), 0);
|
||||
|
||||
char buffer[FILENAME_MAX + 1] = "";
|
||||
const char *timezone = NULL;
|
||||
ssize_t ret;
|
||||
|
||||
// use the TZ variable
|
||||
if(tz && *tz && *tz != ':') {
|
||||
timezone = tz;
|
||||
// info("TIMEZONE: using TZ variable '%s'", timezone);
|
||||
}
|
||||
|
||||
// use the contents of /etc/timezone
|
||||
if(!timezone && !read_file("/etc/timezone", buffer, FILENAME_MAX)) {
|
||||
timezone = buffer;
|
||||
// info("TIMEZONE: using the contents of /etc/timezone: '%s'", timezone);
|
||||
}
|
||||
|
||||
// read the link /etc/localtime
|
||||
if(!timezone) {
|
||||
ret = readlink("/etc/localtime", buffer, FILENAME_MAX);
|
||||
|
||||
if(ret > 0) {
|
||||
buffer[ret] = '\0';
|
||||
|
||||
char *cmp = "/usr/share/zoneinfo/";
|
||||
size_t cmp_len = strlen(cmp);
|
||||
|
||||
char *s = strstr(buffer, cmp);
|
||||
if (s && s[cmp_len]) {
|
||||
timezone = &s[cmp_len];
|
||||
// info("TIMEZONE: using the link of /etc/localtime: '%s'", timezone);
|
||||
}
|
||||
}
|
||||
else
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
|
||||
// find the timezone from strftime()
|
||||
if(!timezone) {
|
||||
time_t t;
|
||||
struct tm *tmp, tmbuf;
|
||||
|
||||
t = now_realtime_sec();
|
||||
tmp = localtime_r(&t, &tmbuf);
|
||||
|
||||
if (tmp != NULL) {
|
||||
if(strftime(buffer, FILENAME_MAX, "%Z", tmp) == 0)
|
||||
buffer[0] = '\0';
|
||||
else {
|
||||
buffer[FILENAME_MAX] = '\0';
|
||||
timezone = buffer;
|
||||
// info("TIMEZONE: using strftime(): '%s'", timezone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(timezone && *timezone) {
|
||||
// make sure it does not have illegal characters
|
||||
// info("TIMEZONE: fixing '%s'", timezone);
|
||||
|
||||
size_t len = strlen(timezone);
|
||||
char tmp[len + 1];
|
||||
char *d = tmp;
|
||||
*d = '\0';
|
||||
|
||||
while(*timezone) {
|
||||
if(isalnum(*timezone) || *timezone == '_' || *timezone == '/')
|
||||
*d++ = *timezone++;
|
||||
else
|
||||
timezone++;
|
||||
}
|
||||
*d = '\0';
|
||||
strncpyz(buffer, tmp, len);
|
||||
timezone = buffer;
|
||||
// info("TIMEZONE: fixed as '%s'", timezone);
|
||||
}
|
||||
|
||||
if(!timezone || !*timezone)
|
||||
timezone = "unknown";
|
||||
|
||||
netdata_configured_timezone = config_get(CONFIG_SECTION_GLOBAL, "timezone", timezone);
|
||||
}
|
||||
|
||||
void set_global_environment() {
|
||||
{
|
||||
char b[16];
|
||||
snprintfz(b, 15, "%d", default_rrd_update_every);
|
||||
setenv("NETDATA_UPDATE_EVERY", b, 1);
|
||||
}
|
||||
|
||||
setenv("NETDATA_VERSION" , program_version, 1);
|
||||
setenv("NETDATA_HOSTNAME" , netdata_configured_hostname, 1);
|
||||
setenv("NETDATA_CONFIG_DIR" , verify_required_directory(netdata_configured_user_config_dir), 1);
|
||||
setenv("NETDATA_USER_CONFIG_DIR" , verify_required_directory(netdata_configured_user_config_dir), 1);
|
||||
setenv("NETDATA_STOCK_CONFIG_DIR" , verify_required_directory(netdata_configured_stock_config_dir), 1);
|
||||
setenv("NETDATA_PLUGINS_DIR" , verify_required_directory(netdata_configured_primary_plugins_dir), 1);
|
||||
setenv("NETDATA_WEB_DIR" , verify_required_directory(netdata_configured_web_dir), 1);
|
||||
setenv("NETDATA_CACHE_DIR" , verify_required_directory(netdata_configured_cache_dir), 1);
|
||||
setenv("NETDATA_LIB_DIR" , verify_required_directory(netdata_configured_varlib_dir), 1);
|
||||
setenv("NETDATA_LOCK_DIR" , netdata_configured_lock_dir, 1);
|
||||
setenv("NETDATA_LOG_DIR" , verify_required_directory(netdata_configured_log_dir), 1);
|
||||
setenv("HOME" , verify_required_directory(netdata_configured_home_dir), 1);
|
||||
setenv("NETDATA_HOST_PREFIX" , netdata_configured_host_prefix, 1);
|
||||
|
||||
char *default_port = appconfig_get(&netdata_config, CONFIG_SECTION_WEB, "default port", NULL);
|
||||
int clean = 0;
|
||||
if (!default_port) {
|
||||
default_port = strdupz("19999");
|
||||
clean = 1;
|
||||
}
|
||||
|
||||
setenv("NETDATA_LISTEN_PORT" , default_port, 1);
|
||||
if(clean)
|
||||
freez(default_port);
|
||||
|
||||
get_system_timezone();
|
||||
|
||||
// set the path we need
|
||||
char path[1024 + 1], *p = getenv("PATH");
|
||||
if(!p) p = "/bin:/usr/bin";
|
||||
snprintfz(path, 1024, "%s:%s", p, "/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin");
|
||||
setenv("PATH", config_get(CONFIG_SECTION_PLUGINS, "PATH environment variable", path), 1);
|
||||
|
||||
// python options
|
||||
p = getenv("PYTHONPATH");
|
||||
if(!p) p = "";
|
||||
setenv("PYTHONPATH", config_get(CONFIG_SECTION_PLUGINS, "PYTHONPATH environment variable", p), 1);
|
||||
|
||||
// disable buffering for python plugins
|
||||
setenv("PYTHONUNBUFFERED", "1", 1);
|
||||
|
||||
// switch to standard locale for plugins
|
||||
setenv("LC_ALL", "C", 1);
|
||||
}
|
||||
|
||||
static int load_netdata_conf(char *filename, char overwrite_used) {
|
||||
errno = 0;
|
||||
|
||||
|
@ -835,47 +684,6 @@ int get_system_info(struct rrdhost_system_info *system_info) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void send_statistics( const char *action, const char *action_result, const char *action_data) {
|
||||
static char *as_script;
|
||||
|
||||
if (netdata_anonymous_statistics_enabled == -1) {
|
||||
char *optout_file = mallocz(sizeof(char) * (strlen(netdata_configured_user_config_dir) +strlen(".opt-out-from-anonymous-statistics") + 2));
|
||||
sprintf(optout_file, "%s/%s", netdata_configured_user_config_dir, ".opt-out-from-anonymous-statistics");
|
||||
if (likely(access(optout_file, R_OK) != 0)) {
|
||||
as_script = mallocz(sizeof(char) * (strlen(netdata_configured_primary_plugins_dir) + strlen("anonymous-statistics.sh") + 2));
|
||||
sprintf(as_script, "%s/%s", netdata_configured_primary_plugins_dir, "anonymous-statistics.sh");
|
||||
if (unlikely(access(as_script, R_OK) != 0)) {
|
||||
netdata_anonymous_statistics_enabled=0;
|
||||
info("Anonymous statistics script %s not found.",as_script);
|
||||
freez(as_script);
|
||||
} else {
|
||||
netdata_anonymous_statistics_enabled=1;
|
||||
}
|
||||
} else {
|
||||
netdata_anonymous_statistics_enabled = 0;
|
||||
as_script = NULL;
|
||||
}
|
||||
freez(optout_file);
|
||||
}
|
||||
if(!netdata_anonymous_statistics_enabled) return;
|
||||
if (!action) return;
|
||||
if (!action_result) action_result="";
|
||||
if (!action_data) action_data="";
|
||||
char *command_to_run=mallocz(sizeof(char) * (strlen(action) + strlen(action_result) + strlen(action_data) + strlen(as_script) + 10));
|
||||
pid_t command_pid;
|
||||
|
||||
sprintf(command_to_run,"%s '%s' '%s' '%s'", as_script, action, action_result, action_data);
|
||||
info("%s", command_to_run);
|
||||
|
||||
FILE *fp = mypopen(command_to_run, &command_pid);
|
||||
if(fp) {
|
||||
char buffer[100 + 1];
|
||||
while (fgets(buffer, 100, fp) != NULL);
|
||||
mypclose(fp, command_pid);
|
||||
}
|
||||
freez(command_to_run);
|
||||
}
|
||||
|
||||
void set_silencers_filename() {
|
||||
char filename[FILENAME_MAX + 1];
|
||||
snprintfz(filename, FILENAME_MAX, "%s/health.silencers.json", netdata_configured_varlib_dir);
|
||||
|
@ -1511,10 +1319,25 @@ int main(int argc, char **argv) {
|
|||
info("netdata initialization completed. Enjoy real-time performance monitoring!");
|
||||
netdata_ready = 1;
|
||||
|
||||
set_late_global_environment();
|
||||
|
||||
send_statistics("START", "-", "-");
|
||||
if (crash_detected)
|
||||
send_statistics("CRASH", "-", "-");
|
||||
|
||||
//check if ANALYTICS needs to start
|
||||
if (netdata_anonymous_statistics_enabled == 1) {
|
||||
for (i = 0; static_threads[i].name != NULL; i++) {
|
||||
if (!strncmp(static_threads[i].name, "ANALYTICS", 9)) {
|
||||
struct netdata_static_thread *st = &static_threads[i];
|
||||
st->thread = mallocz(sizeof(netdata_thread_t));
|
||||
st->enabled = 1;
|
||||
debug(D_SYSTEM, "Starting thread %s.", st->name);
|
||||
netdata_thread_create(st->thread, st->name, NETDATA_THREAD_OPTION_DEFAULT, st->start_routine, st);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Report ACLK build failure
|
||||
#ifndef ENABLE_ACLK
|
||||
|
|
|
@ -4,6 +4,64 @@
|
|||
|
||||
static struct engine *engine = NULL;
|
||||
|
||||
void analytics_exporting_connectors(BUFFER *b)
|
||||
{
|
||||
if (!engine)
|
||||
return;
|
||||
|
||||
uint8_t count = 0;
|
||||
|
||||
for (struct instance *instance = engine->instance_root; instance; instance = instance->next) {
|
||||
if (count)
|
||||
buffer_strcat(b, "|");
|
||||
|
||||
switch (instance->config.type) {
|
||||
case EXPORTING_CONNECTOR_TYPE_GRAPHITE:
|
||||
buffer_strcat(b, "Graphite");
|
||||
break;
|
||||
case EXPORTING_CONNECTOR_TYPE_GRAPHITE_HTTP:
|
||||
buffer_strcat(b, "GraphiteHTTP");
|
||||
break;
|
||||
case EXPORTING_CONNECTOR_TYPE_JSON:
|
||||
buffer_strcat(b, "JSON");
|
||||
break;
|
||||
case EXPORTING_CONNECTOR_TYPE_JSON_HTTP:
|
||||
buffer_strcat(b, "JSONHTTP");
|
||||
break;
|
||||
case EXPORTING_CONNECTOR_TYPE_OPENTSDB:
|
||||
buffer_strcat(b, "OpenTSDB");
|
||||
break;
|
||||
case EXPORTING_CONNECTOR_TYPE_OPENTSDB_HTTP:
|
||||
buffer_strcat(b, "OpenTSDBHTTP");
|
||||
break;
|
||||
case EXPORTING_CONNECTOR_TYPE_PROMETHEUS_REMOTE_WRITE:
|
||||
#if ENABLE_PROMETHEUS_REMOTE_WRITE
|
||||
buffer_strcat(b, "PrometheusRemoteWrite");
|
||||
#endif
|
||||
break;
|
||||
case EXPORTING_CONNECTOR_TYPE_KINESIS:
|
||||
#if HAVE_KINESIS
|
||||
buffer_strcat(b, "Kinesis");
|
||||
#endif
|
||||
break;
|
||||
case EXPORTING_CONNECTOR_TYPE_PUBSUB:
|
||||
#if ENABLE_EXPORTING_PUBSUB
|
||||
buffer_strcat(b, "Pubsub");
|
||||
#endif
|
||||
break;
|
||||
case EXPORTING_CONNECTOR_TYPE_MONGODB:
|
||||
#if HAVE_MONGOC
|
||||
buffer_strcat(b, "MongoDB");
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
buffer_strcat(b, "Unknown");
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exporting Clean Engine
|
||||
*
|
||||
|
|
|
@ -794,6 +794,9 @@ static inline time_t prometheus_preparation(
|
|||
time_t now,
|
||||
PROMETHEUS_OUTPUT_OPTIONS output_options)
|
||||
{
|
||||
#ifndef UNIT_TESTING
|
||||
analytics_log_prometheus();
|
||||
#endif
|
||||
if (!server || !*server)
|
||||
server = "default";
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ extern "C" {
|
|||
#define D_STATSD 0x0000000010000000
|
||||
#define D_POLLFD 0x0000000020000000
|
||||
#define D_STREAM 0x0000000040000000
|
||||
#define D_ANALYTICS 0x0000000080000000
|
||||
#define D_RRDENGINE 0x0000000100000000
|
||||
#define D_ACLK 0x0000000200000000
|
||||
#define D_METADATALOG 0x0000000400000000
|
||||
|
|
|
@ -23,6 +23,7 @@ static inline size_t shell_name_copy(char *d, const char *s, size_t usable) {
|
|||
#define SHELL_ELEMENT_MAX 100
|
||||
|
||||
void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) {
|
||||
analytics_log_shell();
|
||||
rrdhost_rdlock(host);
|
||||
|
||||
// for each chart
|
||||
|
@ -92,6 +93,7 @@ void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) {
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
void rrd_stats_api_v1_charts_allmetrics_json(RRDHOST *host, BUFFER *wb) {
|
||||
analytics_log_json();
|
||||
rrdhost_rdlock(host);
|
||||
|
||||
buffer_strcat(wb, "{");
|
||||
|
|
|
@ -750,6 +750,7 @@ inline int web_client_api_request_v1_registry(RRDHOST *host, struct web_client *
|
|||
|
||||
if(unlikely(action == 'H')) {
|
||||
// HELLO request, dashboard ACL
|
||||
analytics_log_dashboard();
|
||||
if(unlikely(!web_client_can_access_dashboard(w)))
|
||||
return web_client_permission_denied(w);
|
||||
}
|
||||
|
@ -995,10 +996,82 @@ inline int web_client_api_request_v1_info_fill_buffer(RRDHOST *host, BUFFER *wb)
|
|||
}
|
||||
#ifdef ENABLE_ACLK
|
||||
if (aclk_connected)
|
||||
buffer_strcat(wb, "\t\"aclk-available\": true\n");
|
||||
buffer_strcat(wb, "\t\"aclk-available\": true,\n");
|
||||
else
|
||||
#endif
|
||||
buffer_strcat(wb, "\t\"aclk-available\": false\n"); // Intentionally valid with/without #ifdef above
|
||||
buffer_strcat(wb, "\t\"aclk-available\": false,\n"); // Intentionally valid with/without #ifdef above
|
||||
|
||||
buffer_strcat(wb, "\t\"memory-mode\": ");
|
||||
analytics_get_data(analytics_data.netdata_config_memory_mode, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"multidb-disk-quota\": ");
|
||||
analytics_get_data(analytics_data.netdata_config_multidb_disk_quota, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"page-cache-size\": ");
|
||||
analytics_get_data(analytics_data.netdata_config_page_cache_size, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"stream-enabled\": ");
|
||||
analytics_get_data(analytics_data.netdata_config_stream_enabled, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"hosts-available\": ");
|
||||
analytics_get_data(analytics_data.netdata_config_hosts_available, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"https-enabled\": ");
|
||||
analytics_get_data(analytics_data.netdata_config_https_enabled, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"buildinfo\": ");
|
||||
analytics_get_data(analytics_data.netdata_buildinfo, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"release-channel\": ");
|
||||
analytics_get_data(analytics_data.netdata_config_release_channel, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"web-enabled\": ");
|
||||
analytics_get_data(analytics_data.netdata_config_web_enabled, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"notification-methods\": ");
|
||||
analytics_get_data(analytics_data.netdata_notification_methods, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"exporting-enabled\": ");
|
||||
analytics_get_data(analytics_data.netdata_config_exporting_enabled, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"exporting-connectors\": ");
|
||||
analytics_get_data(analytics_data.netdata_exporting_connectors, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"allmetrics-prometheus-used\": ");
|
||||
analytics_get_data(analytics_data.netdata_allmetrics_prometheus_used, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"allmetrics-shell-used\": ");
|
||||
analytics_get_data(analytics_data.netdata_allmetrics_shell_used, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"allmetrics-json-used\": ");
|
||||
analytics_get_data(analytics_data.netdata_allmetrics_json_used, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"dashboard-used\": ");
|
||||
analytics_get_data(analytics_data.netdata_dashboard_used, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"charts-count\": ");
|
||||
analytics_get_data(analytics_data.netdata_charts_count, wb);
|
||||
buffer_strcat(wb, ",\n");
|
||||
|
||||
buffer_strcat(wb, "\t\"metrics-count\": ");
|
||||
analytics_get_data(analytics_data.netdata_metrics_count, wb);
|
||||
buffer_strcat(wb, "\n");
|
||||
|
||||
buffer_strcat(wb, "}");
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue