summaryrefslogtreecommitdiffstats
path: root/daemon/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/main.c')
-rw-r--r--daemon/main.c235
1 files changed, 34 insertions, 201 deletions
diff --git a/daemon/main.c b/daemon/main.c
index 93ec78b6..61041f54 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -28,10 +28,13 @@ 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];
+ char agent_incomplete_shutdown_file[FILENAME_MAX + 1];
snprintfz(agent_crash_file, FILENAME_MAX, "%s/.agent_crash", netdata_configured_varlib_dir);
- (void) unlink(agent_crash_file);
+ snprintfz(agent_incomplete_shutdown_file, FILENAME_MAX, "%s/.agent_incomplete_shutdown", netdata_configured_varlib_dir);
+ (void) rename(agent_crash_file, agent_incomplete_shutdown_file);
// cleanup/save the database and exit
info("EXIT: cleaning up the database...");
@@ -67,10 +70,12 @@ void netdata_cleanup_and_exit(int ret) {
security_clean_openssl();
#endif
info("EXIT: all done - netdata is now exiting - bye bye...");
+ (void) unlink(agent_incomplete_shutdown_file);
exit(ret);
}
struct netdata_static_thread static_threads[] = {
+ NETDATA_PLUGIN_HOOK_GLOBAL_STATISTICS
NETDATA_PLUGIN_HOOK_CHECKS
NETDATA_PLUGIN_HOOK_FREEBSD
@@ -79,6 +84,7 @@ struct netdata_static_thread static_threads[] = {
// linux internal plugins
NETDATA_PLUGIN_HOOK_LINUX_PROC
NETDATA_PLUGIN_HOOK_LINUX_DISKSPACE
+ NETDATA_PLUGIN_HOOK_LINUX_TIMEX
NETDATA_PLUGIN_HOOK_LINUX_CGROUPS
NETDATA_PLUGIN_HOOK_LINUX_TC
@@ -97,6 +103,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}
};
@@ -395,18 +402,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];
@@ -610,147 +605,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;
@@ -833,47 +687,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);
@@ -920,7 +733,7 @@ int main(int argc, char **argv) {
// set the name for logging
program_name = "netdata";
- // parse depercated options
+ // parse deprecated options
// TODO: Remove this block with the next major release.
{
i = 1;
@@ -1106,21 +919,21 @@ int main(int argc, char **argv) {
return 1;
}
- const char *heystack = argv[optind];
+ const char *haystack = argv[optind];
const char *needle = argv[optind + 1];
size_t len = strlen(needle) + 1;
char wildcarded[len];
- SIMPLE_PATTERN *p = simple_pattern_create(heystack, NULL, SIMPLE_PATTERN_EXACT);
+ SIMPLE_PATTERN *p = simple_pattern_create(haystack, NULL, SIMPLE_PATTERN_EXACT);
int ret = simple_pattern_matches_extract(p, needle, wildcarded, len);
simple_pattern_free(p);
if(ret) {
- fprintf(stdout, "RESULT: MATCHED - pattern '%s' matches '%s', wildcarded '%s'\n", heystack, needle, wildcarded);
+ fprintf(stdout, "RESULT: MATCHED - pattern '%s' matches '%s', wildcarded '%s'\n", haystack, needle, wildcarded);
return 0;
}
else {
- fprintf(stdout, "RESULT: NOT MATCHED - pattern '%s' does not match '%s', wildcarded '%s'\n", heystack, needle, wildcarded);
+ fprintf(stdout, "RESULT: NOT MATCHED - pattern '%s' does not match '%s', wildcarded '%s'\n", haystack, needle, wildcarded);
return 1;
}
}
@@ -1437,7 +1250,7 @@ int main(int argc, char **argv) {
netdata_threads_init_after_fork((size_t)config_get_number(CONFIG_SECTION_GLOBAL, "pthread stack size", (long)default_stacksize));
- // initialyze internal registry
+ // initialize internal registry
registry_init();
// fork the spawn server
spawn_init();
@@ -1461,6 +1274,9 @@ int main(int argc, char **argv) {
fatal("Cannot initialize localhost instance with name '%s'.", netdata_configured_hostname);
char agent_crash_file[FILENAME_MAX + 1];
+ char agent_incomplete_shutdown_file[FILENAME_MAX + 1];
+ snprintfz(agent_incomplete_shutdown_file, FILENAME_MAX, "%s/.agent_incomplete_shutdown", netdata_configured_varlib_dir);
+ int incomplete_shutdown_detected = (unlink(agent_incomplete_shutdown_file) == 0);
snprintfz(agent_crash_file, FILENAME_MAX, "%s/.agent_crash", netdata_configured_varlib_dir);
int crash_detected = (unlink(agent_crash_file) == 0);
int fd = open(agent_crash_file, O_WRONLY | O_CREAT | O_TRUNC, 444);
@@ -1509,9 +1325,26 @@ 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", "-", "-");
+ if (incomplete_shutdown_detected)
+ send_statistics("INCOMPLETE_SHUTDOWN", "-", "-");
+
+ //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