summaryrefslogtreecommitdiffstats
path: root/daemon/analytics.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/analytics.c')
-rw-r--r--daemon/analytics.c202
1 files changed, 179 insertions, 23 deletions
diff --git a/daemon/analytics.c b/daemon/analytics.c
index 08923a3cb..bb878f708 100644
--- a/daemon/analytics.c
+++ b/daemon/analytics.c
@@ -4,6 +4,7 @@
struct analytics_data analytics_data;
extern void analytics_exporting_connectors (BUFFER *b);
+extern void analytics_exporting_connectors_ssl (BUFFER *b);
extern void analytics_build_info (BUFFER *b);
extern int aclk_connected;
@@ -54,6 +55,12 @@ void analytics_log_data(void)
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);
debug(D_ANALYTICS, "NETDATA_HOST_CLOUD_ENABLED : [%s]", analytics_data.netdata_host_cloud_enabled);
+ debug(D_ANALYTICS, "NETDATA_CONFIG_HTTPS_AVAILABLE : [%s]", analytics_data.netdata_config_https_available);
+ debug(D_ANALYTICS, "NETDATA_INSTALL_TYPE : [%s]", analytics_data.netdata_install_type);
+ debug(D_ANALYTICS, "NETDATA_PREBUILT_DISTRO : [%s]", analytics_data.netdata_prebuilt_distro);
+ debug(D_ANALYTICS, "NETDATA_CONFIG_IS_PRIVATE_REGISTRY : [%s]", analytics_data.netdata_config_is_private_registry);
+ debug(D_ANALYTICS, "NETDATA_CONFIG_USE_PRIVATE_REGISTRY: [%s]", analytics_data.netdata_config_use_private_registry);
+ debug(D_ANALYTICS, "NETDATA_CONFIG_OOM_SCORE : [%s]", analytics_data.netdata_config_oom_score);
}
/*
@@ -93,6 +100,12 @@ void analytics_free_data(void)
freez(analytics_data.netdata_host_aclk_implementation);
freez(analytics_data.netdata_host_agent_claimed);
freez(analytics_data.netdata_host_cloud_enabled);
+ freez(analytics_data.netdata_config_https_available);
+ freez(analytics_data.netdata_install_type);
+ freez(analytics_data.netdata_config_is_private_registry);
+ freez(analytics_data.netdata_config_use_private_registry);
+ freez(analytics_data.netdata_config_oom_score);
+ freez(analytics_data.netdata_prebuilt_distro);
}
/*
@@ -137,7 +150,7 @@ void analytics_get_data(char *name, BUFFER *wb)
*/
void analytics_log_prometheus(void)
{
- if (likely(analytics_data.prometheus_hits < ANALYTICS_MAX_PROMETHEUS_HITS)) {
+ if (netdata_anonymous_statistics_enabled == 1 && likely(analytics_data.prometheus_hits < ANALYTICS_MAX_PROMETHEUS_HITS)) {
analytics_data.prometheus_hits++;
char b[7];
snprintfz(b, 6, "%d", analytics_data.prometheus_hits);
@@ -150,7 +163,7 @@ void analytics_log_prometheus(void)
*/
void analytics_log_shell(void)
{
- if (likely(analytics_data.shell_hits < ANALYTICS_MAX_SHELL_HITS)) {
+ if (netdata_anonymous_statistics_enabled == 1 && likely(analytics_data.shell_hits < ANALYTICS_MAX_SHELL_HITS)) {
analytics_data.shell_hits++;
char b[7];
snprintfz(b, 6, "%d", analytics_data.shell_hits);
@@ -163,7 +176,7 @@ void analytics_log_shell(void)
*/
void analytics_log_json(void)
{
- if (likely(analytics_data.json_hits < ANALYTICS_MAX_JSON_HITS)) {
+ if (netdata_anonymous_statistics_enabled == 1 && likely(analytics_data.json_hits < ANALYTICS_MAX_JSON_HITS)) {
analytics_data.json_hits++;
char b[7];
snprintfz(b, 6, "%d", analytics_data.json_hits);
@@ -176,7 +189,7 @@ void analytics_log_json(void)
*/
void analytics_log_dashboard(void)
{
- if (likely(analytics_data.dashboard_hits < ANALYTICS_MAX_DASHBOARD_HITS)) {
+ if (netdata_anonymous_statistics_enabled == 1 && likely(analytics_data.dashboard_hits < ANALYTICS_MAX_DASHBOARD_HITS)) {
analytics_data.dashboard_hits++;
char b[7];
snprintfz(b, 6, "%d", analytics_data.dashboard_hits);
@@ -184,6 +197,15 @@ void analytics_log_dashboard(void)
}
}
+/*
+ * Called when setting the oom score
+ */
+void analytics_report_oom_score(long long int score){
+ char b[7];
+ snprintfz(b, 6, "%d", (int)score);
+ analytics_set_data(&analytics_data.netdata_config_oom_score, b);
+}
+
void analytics_mirrored_hosts(void)
{
RRDHOST *host;
@@ -217,7 +239,7 @@ void analytics_mirrored_hosts(void)
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)
+ //decide if something else is more suitable (but probably not null)
BUFFER *bi = buffer_create(1000);
analytics_exporting_connectors(bi);
analytics_set_data_str(&analytics_data.netdata_exporting_connectors, (char *)buffer_tostring(bi));
@@ -335,6 +357,67 @@ void analytics_alarms_notifications(void)
buffer_free(b);
}
+char *get_value_from_key(char *buffer, char *key)
+{
+ char *s = NULL, *t = NULL;
+ s = t = buffer + strlen(key) + 2;
+ if (s) {
+ while (*s == '\'')
+ s++;
+ while (*++t != '\0');
+ while (--t > s && *t == '\'')
+ *t = '\0';
+ }
+ return s;
+}
+
+/*
+ * Checks for the existence of .install_type file and reads it
+ */
+void analytics_get_install_type(void)
+{
+ char *install_type_filename;
+ analytics_set_data_str(&analytics_data.netdata_install_type, "");
+ analytics_set_data_str(&analytics_data.netdata_prebuilt_distro, "");
+
+ int install_type_filename_len = (strlen(netdata_configured_user_config_dir) + strlen(".install-type") + 3);
+ install_type_filename = mallocz(sizeof(char) * install_type_filename_len);
+ snprintfz(install_type_filename, install_type_filename_len - 1, "%s/%s", netdata_configured_user_config_dir, ".install-type");
+
+ FILE *fp = fopen(install_type_filename, "r");
+ if (fp) {
+ char *s, buf[256 + 1];
+ size_t len = 0;
+
+ while ((s = fgets_trim_len(buf, 256, fp, &len))) {
+ if (!strncmp(buf, "INSTALL_TYPE='", 14))
+ analytics_set_data_str(&analytics_data.netdata_install_type, (char *)get_value_from_key(buf, "INSTALL_TYPE"));
+ else if (!strncmp(buf, "PREBUILT_DISTRO='", 17))
+ analytics_set_data_str(&analytics_data.netdata_prebuilt_distro, (char *)get_value_from_key(buf, "PREBUILT_DISTRO"));
+ }
+ fclose(fp);
+ }
+ freez(install_type_filename);
+}
+
+/*
+ * Pick up if https is actually used
+ */
+void analytics_https(void)
+{
+ BUFFER *b = buffer_create(30);
+#ifdef ENABLE_HTTPS
+ analytics_exporting_connectors_ssl(b);
+ buffer_strcat(b, netdata_client_ctx && localhost->ssl.flags == NETDATA_SSL_HANDSHAKE_COMPLETE && localhost->rrdpush_sender_connected == 1 ? "streaming|" : "|");
+ buffer_strcat(b, netdata_srv_ctx ? "web" : "");
+#else
+ buffer_strcat(b, "||");
+#endif
+
+ analytics_set_data_str(&analytics_data.netdata_config_https_available, (char *)buffer_tostring(b));
+ buffer_free(b);
+}
+
void analytics_charts(void)
{
RRDSET *st;
@@ -411,13 +494,13 @@ 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
+ if (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");
#else
analytics_set_data(&analytics_data.netdata_host_cloud_available, "false");
+ analytics_set_data_str(&analytics_data.netdata_host_aclk_implementation, "");
#endif
#ifdef ENABLE_ACLK
@@ -426,17 +509,33 @@ void analytics_misc(void)
else
#endif
analytics_set_data(&analytics_data.netdata_host_aclk_available, "false");
+
+ analytics_set_data(&analytics_data.netdata_config_exporting_enabled, appconfig_get_boolean(&exporting_config, CONFIG_SECTION_EXPORTING, "enabled", CONFIG_BOOLEAN_NO) ? "true" : "false");
+
+ analytics_set_data(&analytics_data.netdata_config_is_private_registry, "false");
+ analytics_set_data(&analytics_data.netdata_config_use_private_registry, "false");
+
+ if (strcmp(
+ config_get(CONFIG_SECTION_REGISTRY, "registry to announce", "https://registry.my-netdata.io"),
+ "https://registry.my-netdata.io"))
+ analytics_set_data(&analytics_data.netdata_config_use_private_registry, "true");
+
+ //do we need both registry to announce and enabled to indicate that this is a private registry ?
+ if (config_get_boolean(CONFIG_SECTION_REGISTRY, "enabled", CONFIG_BOOLEAN_NO) &&
+ web_server_mode != WEB_SERVER_MODE_NONE)
+ analytics_set_data(&analytics_data.netdata_config_is_private_registry, "true");
}
/*
* 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
+ * These are values that won't change during agent runtime, and therefore
* don't try to read them on each META event send
*/
void analytics_gather_immutable_meta_data(void)
{
analytics_misc();
analytics_exporters();
+ analytics_https();
}
/*
@@ -490,6 +589,7 @@ void analytics_main_cleanup(void *ptr)
static_thread->enabled = NETDATA_MAIN_THREAD_EXITING;
debug(D_ANALYTICS, "Cleaning up...");
+ analytics_free_data();
static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
}
@@ -521,7 +621,7 @@ void *analytics_main(void *ptr)
analytics_gather_immutable_meta_data();
analytics_gather_mutable_meta_data();
- send_statistics("META", "-", "-");
+ send_statistics("META_START", "-", "-");
analytics_log_data();
sec = 0;
@@ -567,7 +667,6 @@ 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", CONFIG_BOOLEAN_NO) ? "true" : "false");
#ifdef DISABLE_CLOUD
analytics_set_data(&analytics_data.netdata_host_cloud_enabled, "false");
@@ -607,9 +706,11 @@ void set_late_global_environment()
analytics_set_data_str(&analytics_data.netdata_buildinfo, (char *)buffer_tostring(bi));
buffer_free(bi);
}
+
+ analytics_get_install_type();
}
-static void get_system_timezone(void)
+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
@@ -630,7 +731,7 @@ static void get_system_timezone(void)
// 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);
+ info("TIMEZONE: using the contents of /etc/timezone");
}
// read the link /etc/localtime
@@ -696,6 +797,46 @@ static void get_system_timezone(void)
timezone = "unknown";
netdata_configured_timezone = config_get(CONFIG_SECTION_GLOBAL, "timezone", timezone);
+
+ //get the utc offset, and the timezone as returned by strftime
+ //will be sent to the cloud
+ //Note: This will need an agent restart to get new offset on time change (dst, etc).
+ {
+ time_t t;
+ struct tm *tmp, tmbuf;
+ char zone[FILENAME_MAX + 1];
+ char sign[2], hh[3], mm[3];
+
+ t = now_realtime_sec();
+ tmp = localtime_r(&t, &tmbuf);
+
+ if (tmp != NULL) {
+ if (strftime(zone, FILENAME_MAX, "%Z", tmp) == 0) {
+ netdata_configured_abbrev_timezone = strdupz("UTC");
+ } else
+ netdata_configured_abbrev_timezone = strdupz(zone);
+
+ if (strftime(zone, FILENAME_MAX, "%z", tmp) == 0) {
+ netdata_configured_utc_offset = 0;
+ } else {
+ sign[0] = zone[0] == '-' || zone[0] == '+' ? zone[0] : '0';
+ sign[1] = '\0';
+ hh[0] = isdigit(zone[1]) ? zone[1] : '0';
+ hh[1] = isdigit(zone[2]) ? zone[2] : '0';
+ hh[2] = '\0';
+ mm[0] = isdigit(zone[3]) ? zone[3] : '0';
+ mm[1] = isdigit(zone[4]) ? zone[4] : '0';
+ mm[2] = '\0';
+
+ netdata_configured_utc_offset = (str2i(hh) * 3600) + (str2i(mm) * 60);
+ netdata_configured_utc_offset =
+ sign[0] == '-' ? -netdata_configured_utc_offset : netdata_configured_utc_offset;
+ }
+ } else {
+ netdata_configured_abbrev_timezone = strdupz("UTC");
+ netdata_configured_utc_offset = 0;
+ }
+ }
}
void set_global_environment()
@@ -753,6 +894,12 @@ void set_global_environment()
analytics_set_data(&analytics_data.netdata_host_aclk_available, "null");
analytics_set_data(&analytics_data.netdata_host_agent_claimed, "null");
analytics_set_data(&analytics_data.netdata_host_cloud_enabled, "null");
+ analytics_set_data(&analytics_data.netdata_config_https_available, "null");
+ analytics_set_data(&analytics_data.netdata_install_type, "null");
+ analytics_set_data(&analytics_data.netdata_config_is_private_registry, "null");
+ analytics_set_data(&analytics_data.netdata_config_use_private_registry, "null");
+ analytics_set_data(&analytics_data.netdata_config_oom_score, "null");
+ analytics_set_data(&analytics_data.netdata_prebuilt_distro, "null");
analytics_data.prometheus_hits = 0;
analytics_data.shell_hits = 0;
@@ -770,8 +917,6 @@ void set_global_environment()
if (clean)
freez(default_port);
- get_system_timezone();
-
// set the path we need
char path[1024 + 1], *p = getenv("PATH");
if (!p)
@@ -834,7 +979,7 @@ void send_statistics(const char *action, const char *action_result, const char *
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' '%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' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' ",
as_script,
action,
action_result,
@@ -870,16 +1015,27 @@ void send_statistics(const char *action, const char *action_result, const char *
analytics_data.netdata_host_aclk_available,
analytics_data.netdata_host_aclk_implementation,
analytics_data.netdata_host_agent_claimed,
- analytics_data.netdata_host_cloud_enabled);
+ analytics_data.netdata_host_cloud_enabled,
+ analytics_data.netdata_config_https_available,
+ analytics_data.netdata_install_type,
+ analytics_data.netdata_config_is_private_registry,
+ analytics_data.netdata_config_use_private_registry,
+ analytics_data.netdata_config_oom_score,
+ analytics_data.netdata_prebuilt_distro);
info("%s '%s' '%s' '%s'", as_script, action, action_result, action_data);
FILE *fp = mypopen(command_to_run, &command_pid);
if (fp) {
- char buffer[100 + 1];
- while (fgets(buffer, 100, fp) != NULL)
- ;
- mypclose(fp, command_pid);
+ char buffer[4 + 1];
+ char *s = fgets(buffer, 4, fp);
+ int exit_code = mypclose(fp, command_pid);
+ if (exit_code)
+ error("Execution of anonymous statistics script returned %d.", exit_code);
+ if (s && strncmp(buffer, "200", 3))
+ error("Execution of anonymous statistics script returned http code %s.", buffer);
+ } else {
+ error("Failed to run anonymous statistics script %s.", as_script);
}
freez(command_to_run);
}