root/src/noitd.c

Revision f9655217efc95714767f6b885d986facd6430e2c, 9.0 kB (checked in by Jonas Kunze <kunze.jonas@gmail.com>, 2 months ago)

Reverted a8a86eb: mtev_metric_director doesn't connect to fq otherwise

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007-2010, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  * Copyright (c) 2015, Circonus, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above
13  *       copyright notice, this list of conditions and the following
14  *       disclaimer in the documentation and/or other materials provided
15  *       with the distribution.
16  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
17  *       of its contributors may be used to endorse or promote products
18  *       derived from this software without specific prior written
19  *       permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include "noit_config.h"
35 #include "noit_version.h"
36 #include <mtev_defines.h>
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <sys/mman.h>
44 #include <signal.h>
45 #ifdef HAVE_SYS_WAIT_H
46 #include <sys/wait.h>
47 #endif
48
49 #include <mtev_main.h>
50 #include <eventer/eventer.h>
51 #include <mtev_memory.h>
52 #include <mtev_log.h>
53 #include <mtev_hash.h>
54 #include <mtev_security.h>
55 #include <mtev_watchdog.h>
56 #include <mtev_lockfile.h>
57 #include <mtev_listener.h>
58 #include <mtev_console.h>
59 #include <mtev_rest.h>
60 #include <mtev_reverse_socket.h>
61 #include <mtev_capabilities_listener.h>
62 #include <mtev_conf.h>
63 #include <mtev_events_rest.h>
64 #include <mtev_cluster.h>
65
66 #include "noit_mtev_bridge.h"
67 #include "noit_jlog_listener.h"
68 #include "noit_check_rest.h"
69 #include "noit_livestream_listener.h"
70 #include "noit_websocket_handler.h"
71 #include "noit_module.h"
72 #include "noit_conf_checks.h"
73 #include "noit_filters.h"
74 #include "noit_metric_director.h"
75 #include "noit_check_tools_shared.h"
76 #include "noit_check.h"
77
78 #define APPNAME "noit"
79 #define CHILD_WATCHDOG_TIMEOUT 5 /*seconds*/
80
81 static char *config_file = ETC_DIR "/" APPNAME ".conf";
82 static char *xpath = NULL;
83 static const char *droptouser = NULL;
84 static const char *droptogroup = NULL;
85 static const char *chrootpath = NULL;
86 static int foreground = 0;
87 static int debug = 0;
88 static int strict_module_load = 0;
89 static char *glider = NULL;
90
91 #include "man/noitd.usage.h"
92 static void usage(const char *progname) {
93   printf("Usage for %s:\n", progname);
94 #ifdef NOITD_USAGE
95   mtevAssert(write(STDOUT_FILENO,
96                NOITD_USAGE,
97                sizeof(NOITD_USAGE)-1) == sizeof(NOITD_USAGE)-1);
98 #else
99   printf("\nError in usage, build problem.\n");
100 #endif
101   return;
102 }
103
104 void parse_clargs(int argc, char **argv) {
105   int c;
106   while((c = getopt(argc, argv, "x:Mhc:dDu:g:n:t:l:L:G:")) != EOF) {
107     switch(c) {
108       case 'x':
109         xpath = strdup(optarg);
110         foreground = 1;
111         break;
112       case 'G':
113         glider = strdup(optarg);
114         break;
115       case 'M':
116         strict_module_load = 1;
117         break;
118       case 'h':
119         usage(argv[0]);
120         exit(1);
121         break;
122       case 'l':
123         mtev_main_enable_log(optarg);
124         break;
125       case 'L':
126         mtev_main_disable_log(optarg);
127         break;
128       case 'n':
129         {
130           char *cp = optarg ? strchr(optarg, ':') : NULL;
131           if(!cp) mtev_listener_skip(optarg, 0);
132           else {
133             if(cp == optarg) optarg = NULL;
134             *cp++ = '\0';
135             mtev_listener_skip(optarg, atoi(cp));
136           }
137         }
138         break;
139       case 'u':
140         droptouser = strdup(optarg);
141         break;
142       case 'g':
143         droptogroup = strdup(optarg);
144         break;
145       case 't':
146         chrootpath = strdup(optarg);
147         break;
148       case 'c':
149         config_file = strdup(optarg);
150         break;
151       case 'D':
152         foreground++;
153         break;
154       case 'd':
155         debug++;
156         break;
157       default:
158         break;
159     }
160   }
161 }
162
163 static int __reload_needed = 0;
164 static void request_conf_reload(int sig) {
165   if(sig == SIGHUP) {
166     __reload_needed = 1;
167   }
168 }
169 static int notice_hup(eventer_t e, int mask, void *unused, struct timeval *now) {
170   if(__reload_needed) {
171     mtevL(noit_error, "SIGHUP received, performing reload\n");
172     if(mtev_conf_load(config_file) == -1) {
173       mtevL(noit_error, "Cannot load config: '%s'\n", config_file);
174       exit(-1);
175     }
176     noit_poller_reload(NULL);
177     __reload_needed = 0;
178   }
179   return 0;
180 }
181
182 static int noit_console_stopword(const char *word) {
183   return(!strcmp(word, "check") ||
184          !strcmp(word, "noit") ||
185          !strcmp(word, "filterset") ||
186          !strcmp(word, "config"));
187 }
188 const char *reverse_prefix = "noit/";
189 const char *reverse_prefix_cns[] = { NULL };
190
191 static int child_main() {
192   eventer_t e;
193   char noit_version[80];
194
195   /* Send out a birth notice. */
196   mtev_watchdog_child_heartbeat();
197
198   noit_mtev_bridge_init();
199   mtev_override_console_stopword(noit_console_stopword);
200
201   /* Load our config...
202    * to ensure it is current w.r.t. to this child starting */
203   if(mtev_conf_load(config_file) == -1) {
204     mtevL(noit_error, "Cannot load config: '%s'\n", config_file);
205     exit(2);
206   }
207   if(xpath) {
208     int cnt, i;
209     mtev_conf_section_t *parts = NULL;
210     parts = mtev_conf_get_sections(NULL, xpath, &cnt);
211     if(cnt == 0) exit(2);
212     for(i=0; i<cnt; i++) {
213       fprintf(stdout, "%d: ", i); fflush(stdout);
214       mtev_conf_write_section(parts[i], 1);
215     }
216     free(parts);
217     exit(0);
218   }
219
220   mtev_log_reopen_all();
221   mtevL(noit_notice, "process starting: %d\n", (int)getpid());
222   mtev_log_go_asynch();
223
224   signal(SIGHUP, request_conf_reload);
225
226   /* initialize the eventer */
227   if(eventer_init() == -1) {
228     mtevL(noit_stderr, "Cannot initialize eventer\n");
229     exit(-1);
230   }
231   /* rotation init requires, eventer_init() */
232   mtev_conf_log_init_rotate(APPNAME, mtev_false);
233
234   /* Setup our heartbeat */
235   mtev_watchdog_child_eventer_heartbeat();
236
237   e = eventer_alloc();
238   e->mask = EVENTER_RECURRENT;
239   e->callback = notice_hup;
240   eventer_add_recurrent(e);
241
242   /* Initialized shared tools */
243   noit_check_tools_shared_init();
244
245   /* Initialize all of our listeners */
246   mtev_console_init(APPNAME);
247   mtev_console_conf_init();
248   mtev_capabilities_listener_init();
249   noit_build_version(noit_version, sizeof(noit_version));
250   mtev_capabilities_add_feature("noit", noit_version);
251   mtev_http_rest_init();
252   mtev_reverse_socket_init(reverse_prefix, reverse_prefix_cns);
253   mtev_reverse_socket_acl(mtev_reverse_socket_denier);
254   mtev_events_rest_init();
255   noit_console_conf_checks_init();
256   noit_jlog_listener_init();
257   noit_check_rest_init();
258   noit_filters_rest_init();
259   noit_livestream_listener_init();
260   noit_websocket_handler_init();
261
262   mtev_dso_init();
263   noit_module_init();
264   mtev_dso_post_init();
265   if(strict_module_load &&
266      (mtev_dso_load_failures() > 0 || noit_module_load_failures() > 0)) {
267     mtevL(noit_stderr, "Failed to load some modules and -M given.\n");
268     exit(2);
269   }
270
271   mtev_listener_init(APPNAME);
272   mtev_cluster_init();
273   noit_metric_director_init();
274
275   /* Drop privileges */
276   mtev_conf_security_init(APPNAME, droptouser, droptogroup, chrootpath);
277
278   /* Prepare for launch... */
279   noit_filters_init();
280   noit_poller_init();
281
282   /* Allow the noit web dashboard to be served (only if document_root is set) */
283   mtevAssert(mtev_http_rest_register_auth(
284     "GET", "/", "^(.*)$", mtev_rest_simple_file_handler,
285            mtev_http_rest_client_cert_auth
286   ) == 0);
287
288   /* Write our log out, and setup a watchdog to write it out on change. */
289   mtev_conf_write_log(NULL);
290   mtev_conf_coalesce_changes(10); /* 10 seconds of no changes before we write */
291   mtev_conf_watch_and_journal_watchdog(mtev_conf_write_log, NULL);
292
293   eventer_loop();
294   return 0;
295 }
296
297 void
298 noitd_init_globals(void) {
299   noit_check_init_globals();
300   noit_check_tools_shared_init_globals();
301   noit_conf_checks_init_globals();
302   noit_filters_init_globals();
303   noit_jlog_listener_init_globals();
304   noit_metric_director_init_globals();
305   noit_module_init_globals();
306 }
307
308 int main(int argc, char **argv) {
309   int lock = MTEV_LOCK_OP_LOCK;
310   mtev_memory_init();
311   parse_clargs(argc, argv);
312   if (xpath) lock = MTEV_LOCK_OP_NONE;
313   noitd_init_globals();
314   return mtev_main(APPNAME, config_file, debug, foreground,
315                    lock, glider, droptouser, droptogroup,
316                    child_main);
317 }
Note: See TracBrowser for help on using the browser.