int logger_open( log_level_t level, const char *type, const char *ident, int option, const char *facility, const char *logfile) { int error = 0; char *dup_logfile = NULL; ASSERT(g_logger != NULL); ASSERT(type != NULL); if (strcasecmp(type, "file") == 0 && (logfile == NULL || logfile[0] == '\0')) { errno = EINVAL; return 1; } if (logfile && logfile != '\0') { dup_logfile = strdup(logfile); if (dup_logfile == NULL) { return 1; } } if (g_logger->log_state == LOG_ST_OPENED) { if (g_logger->log_type == LOG_TYPE_VALUE_FILE) { if (g_logger->log == NULL) { fprintf(stderr, "did not opened log file %s.", g_logger->logfilename); } else { fclose(g_logger->log); g_logger->log = NULL; } free(g_logger->logfilename); g_logger->logfilename = NULL; } else if (g_logger->log_type == LOG_TYPE_VALUE_SYSLOG) { closelog(); } g_logger->log_state = LOG_ST_CLOSED; g_logger->log_type = LOG_TYPE_VALUE_STDERR; } if (strcasecmp(type, LOG_TYPE_FILE) == 0) { if (logger_file_open(dup_logfile)) { g_logger->log_type = LOG_TYPE_VALUE_STDERR; } else { g_logger->log_type = LOG_TYPE_VALUE_FILE; g_logger->logfilename = dup_logfile; } } else if (strcasecmp(type, LOG_TYPE_SYSLOG) == 0) { logger_syslog_open(ident, option, facility); g_logger->log_type = LOG_TYPE_VALUE_SYSLOG; } else if (strcasecmp(type, LOG_TYPE_STDOUT) == 0) { g_logger->log_type = LOG_TYPE_VALUE_STDOUT; } else { g_logger->log_type = LOG_TYPE_VALUE_STDERR; } g_logger->log_state = LOG_ST_OPENED; if (g_logger->log_type != LOG_TYPE_VALUE_FILE) { free(dup_logfile); } if (level > LOG_LV_MIN && level < LOG_LV_MAX) { g_logger->verbose_level = level; } else { g_logger->verbose_level = DEFAULT_VERBOSE_LEVEL; } g_logger->pid = getpid(); if (error) { free(dup_logfile); } else { if (g_logger->verbose_level >= LOG_LV_DEBUG) { LOG(LOG_LV_DEBUG, "logging info: type = %d, level %d, state %d, pid %d", g_logger->log_type, g_logger->verbose_level, g_logger->log_state, g_logger->pid); } } return error; }
// TODO: convert this to use metautils' common_main int main(int argc, char ** argv) { int rc = 1; service_info_t *service = NULL; setenv("GS_DEBUG_ENABLE", "0", TRUE); supervisor_children_init(); do { GError *err = NULL; regex_tag = g_regex_new("((stat|tag)\\.([^.=\\s]+))\\s*=\\s*(.*)", G_REGEX_CASELESS|G_REGEX_EXTENDED, 0, &err); if (!regex_tag) { FATAL("Cannot compile tag regex: %s", err->message); g_clear_error(&err); exit(-1); } regex_svc = g_regex_new("([^|]*)\\|([^|]*)\\|(.*)", G_REGEX_CASELESS, 0, &err); if (!regex_svc) { FATAL("Cannot compile svc regex: %s", err->message); g_clear_error(&err); exit(-1); } } while (0); static struct option long_options[] = { {"svc-id", 1, 0, 'i'}, {"monitor", 1, 0, 'm'}, {"svc-cmd", 1, 0, 'c'}, {"syslog-id", 1, 0, 's'}, {"auto-restart-children", 0, 0, 'a'}, {"monitor-period", 1, 0, 'p'}, {"no-tcp-check", 0, 0, 'n'}, {"tag", 1, 0, 't'}, {0, 0, 0, 0} }; int c; int option_index = 0; gchar *optarg2 = NULL; gchar **kv = NULL; while (-1 != (c = getopt_long(argc, argv, "ac:i:m:np:s:t:", long_options, &option_index))) { switch (c) { case 'i': g_strlcpy(svc_id, optarg, sizeof(svc_id)-1); break; case 'm': g_strlcpy(svc_mon, optarg, sizeof(svc_mon)-1); break; case 'c': g_strlcpy(svc_cmd, optarg, sizeof(svc_cmd)-1); break; case 'n': kv = g_malloc0(3 * sizeof(gchar*)); kv[0] = g_strdup("tag.agent_check"); kv[1] = g_strdup("false"); custom_tags = g_slist_prepend(custom_tags, kv); break; case 'a': auto_restart_children = TRUE; break; case 'p': monitor_period = strtoll(optarg, NULL, 10); break; case 's': g_strlcpy(syslog_id, optarg, sizeof(syslog_id)-1); break; case 't': if (!g_str_has_prefix(optarg, "tag.")) optarg2 = g_strdup_printf("tag.%s", optarg); else optarg2 = g_strdup(optarg); kv = g_strsplit(optarg2, "=", 2); if (kv && g_strv_length(kv) == 2) { custom_tags = g_slist_prepend(custom_tags, kv); } else { g_printerr("Invalid tag, must contain '=': %s", optarg); g_strfreev(kv); kv = NULL; } g_free(optarg2); optarg2 = NULL; break; default: g_printerr("Unexpected option: %c\n", c); break; } option_index = 0; } if (argc <= 1 || strlen(svc_id) == 0 || strlen(svc_cmd) == 0) { g_printerr("Usage: %s\n", argv[0]); g_printerr("Mandatory options:\n"); g_printerr("\t-i\t--svc-id <NS|type|ip:port>\n" "\t-c\t--svc-cmd </service/cmd/to/launch>\n\n" "Other options:\n" "\t-m\t--monitor </script/to/monitor>\n" "\t-p\t--monitor-period <seconds>\n" "\t-s\t--syslog-id <syslog-id>\n" "\t-t\t--tag <key=val>\n" "\t-a\t--auto-restart-children\n" "\t-n\t--no-tcp-check\n"); return 1; } if (*syslog_id) { logger_init_level(GRID_LOGLVL_INFO); logger_syslog_open(); g_log_set_default_handler(logger_syslog, NULL); } GError *error = NULL; if (!supervisor_children_register(CHILD_KEY, svc_cmd, &error)) { g_printerr("Child registration failure:\n\t%s\n", gerror_get_message(error)); goto label_error; } if (0 != supervisor_children_set_limit(CHILD_KEY, SUPERV_LIMIT_THREAD_STACK, 8192 * 1024)) WARN("Limit on thread stack size cannot be set: %s", strerror(errno)); if (0 != supervisor_children_set_limit(CHILD_KEY, SUPERV_LIMIT_MAX_FILES, 32 * 1024)) WARN("Limit on max opened files cannot be set: %s", strerror(errno)); if (0 != supervisor_children_set_limit(CHILD_KEY, SUPERV_LIMIT_CORE_SIZE, -1)) WARN("Limit on core file size cannot be set: %s", strerror(errno)); supervisor_children_set_respawn(CHILD_KEY, FALSE); supervisor_children_set_working_directory(CHILD_KEY, "/tmp"); supervisor_preserve_env(CHILD_KEY); service = g_malloc0(sizeof(service_info_t)); if (0 != init_srvinfo(svc_id, service)) { g_printerr("Internal error: failed to init srvinfo\n"); goto label_error; } freopen("/dev/null", "r", stdin); NOTICE("%s restarted, pid=%d", argv[0], getpid()); signal(SIGQUIT, sighandler_supervisor); signal(SIGTERM, sighandler_supervisor); signal(SIGINT, sighandler_supervisor); signal(SIGPIPE, sighandler_supervisor); signal(SIGUSR1, sighandler_supervisor); signal(SIGUSR2, sighandler_supervisor); signal(SIGCHLD, sighandler_supervisor); monitoring_loop(service); rc = 0; label_error: g_slist_free_full(custom_tags, (GDestroyNotify) g_strfreev); service_info_clean(service); supervisor_children_cleanall(); return rc; }