@cryptotaxi247 / netdata-1 / commits / 2994ab47e

new log file management, now 3 logs are supported: access, error, debug

Costa Tsaousis (ktsaou) committed May 3, 2014 at 15:09 UTC 2994ab47e856e9e6b69b175cc7f9d70fb4d6c425
1 file changed +191 -98
netdata.c
+191 -98
@@ -208,14 +208,12 @@ void mypclose(FILE *fp)
208
209 unsigned long long debug_flags = DEBUG;
210
211 -char *debug_log = NULL;
212 -int debug_fd = -1;
213 -
214 -char *access_log = NULL;
211 int access_fd = -1;
212 FILE *stdaccess = NULL;
213
218 -int log_syslog = 1;
214 +int access_log_syslog = 1;
215 +int error_log_syslog = 1;
216 +int output_log_syslog = 1; // debug log
217
218
219 void log_date(FILE *out)
@@ -242,12 +240,18 @@ void debug_int( const char *file, const char *function, const unsigned long line
240 if(file) { ; }
241 va_list args;
242
245 - log_date(stderr);
243 + log_date(stdout);
244 va_start( args, fmt );
247 - fprintf(stderr, "DEBUG (%04lu@%-15.15s): ", line, function);
248 - vfprintf( stderr, fmt, args );
245 + fprintf(stdout, "DEBUG (%04lu@%-15.15s): ", line, function);
246 + vfprintf( stdout, fmt, args );
247 va_end( args );
250 - fprintf(stderr, "\n");
248 + fprintf(stdout, "\n");
249 +
250 + if(output_log_syslog) {
251 + va_start( args, fmt );
252 + vsyslog(LOG_ERR, fmt, args );
253 + va_end( args );
254 + }
255 }
256
257 #define error(args...) error_int(__FILE__, __FUNCTION__, __LINE__, ##args)
@@ -257,22 +261,20 @@ void error_int( const char *file, const char *function, const unsigned long line
261 if(file) { ; }
262 va_list args;
263
260 - if(!silent) {
261 - log_date(stderr);
264 + log_date(stderr);
265
263 - va_start( args, fmt );
264 - fprintf(stderr, "ERROR (%04lu@%-15.15s): ", line, function);
265 - vfprintf( stderr, fmt, args );
266 - va_end( args );
266 + va_start( args, fmt );
267 + fprintf(stderr, "ERROR (%04lu@%-15.15s): ", line, function);
268 + vfprintf( stderr, fmt, args );
269 + va_end( args );
270
268 - if(errno) {
269 - fprintf(stderr, " (errno %d, %s)\n", errno, strerror(errno));
270 - errno = 0;
271 - }
272 - else fprintf(stderr, "\n");
271 + if(errno) {
272 + fprintf(stderr, " (errno %d, %s)\n", errno, strerror(errno));
273 + errno = 0;
274 }
275 + else fprintf(stderr, "\n");
276
275 - if(log_syslog) {
277 + if(error_log_syslog) {
278 va_start( args, fmt );
279 vsyslog(LOG_ERR, fmt, args );
280 va_end( args );
@@ -286,19 +288,17 @@ void fatal_int( const char *file, const char *function, const unsigned long line
288 if(file) { ; }
289 va_list args;
290
289 - if(!silent) {
290 - log_date(stderr);
291 + log_date(stderr);
292
292 - va_start( args, fmt );
293 - fprintf(stderr, "FATAL (%04lu@%-15.15s): ", line, function);
294 - vfprintf( stderr, fmt, args );
295 - va_end( args );
293 + va_start( args, fmt );
294 + fprintf(stderr, "FATAL (%04lu@%-15.15s): ", line, function);
295 + vfprintf( stderr, fmt, args );
296 + va_end( args );
297
297 - perror(" # ");
298 - fprintf(stderr, "\n");
299 - }
298 + perror(" # ");
299 + fprintf(stderr, "\n");
300
301 - if(log_syslog) {
301 + if(error_log_syslog) {
302 va_start( args, fmt );
303 vsyslog(LOG_CRIT, fmt, args );
304 va_end( args );
@@ -321,7 +321,7 @@ void log_access( const char *fmt, ... )
321 fflush( stdaccess );
322 }
323
324 - if(log_syslog) {
324 + if(access_log_syslog) {
325 va_start( args, fmt );
326 vsyslog(LOG_INFO, fmt, args );
327 va_end( args );
@@ -2092,7 +2092,7 @@ void generate_config(struct web_buffer *wb, int only_changed)
2092 }
2093
2094 for(co = config_root; co ; co = co->next) {
2095 - if(strcmp(co->name, "global") == 0 || strcmp(co->name, "debug") == 0 || strcmp(co->name, "plugins") == 0) pri = 0;
2095 + if(strcmp(co->name, "global") == 0 || strcmp(co->name, "plugins") == 0) pri = 0;
2096 else if(strncmp(co->name, "plugin:", 7) == 0) pri = 1;
2097 else pri = 2;
2098
@@ -3198,7 +3198,7 @@ void *new_client(void *ptr)
3198 // 3. spawns a new pthread to serve the client (this is optimal for keep-alive clients)
3199 // 4. cleans up old web_clients that their pthreads have been exited
3200
3201 -void syslog_allocations(void)
3201 +void log_allocations(void)
3202 {
3203 static int mem = 0;
3204
@@ -3275,7 +3275,7 @@ void *socket_listen_main(void *ptr)
3275 debug(D_WEB_CLIENT, "%llu: Removing client.", w->id);
3276 // pthread_join(w->thread, NULL);
3277 w = web_client_free(w);
3278 - syslog_allocations();
3278 + log_allocations();
3279 }
3280 }
3281 }
@@ -6031,10 +6031,79 @@ int fd_is_valid(int fd)
6031 return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
6032 }
6033
6034 -void become_daemon()
6034 +int become_daemon(int close_all_files, const char *input, const char *output, const char *error, const char *access, int *access_fd, FILE **access_fp)
6035 {
6036 fflush(NULL);
6037
6038 + // open the files before forking
6039 + int input_fd = -1, output_fd = -1, error_fd = -1, dev_null = -1;
6040 +
6041 + if(input && *input) {
6042 + if((input_fd = open(input, O_RDONLY, 0666)) == -1) {
6043 + fprintf(stderr, "Cannot open input file '%s' (%s).", input, strerror(errno));
6044 + return -1;
6045 + }
6046 + }
6047 +
6048 + if(output && *output) {
6049 + if((output_fd = open(output, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {
6050 + fprintf(stderr, "Cannot open output log file '%s' (%s).", output, strerror(errno));
6051 + if(input_fd != -1) close(input_fd);
6052 + return -1;
6053 + }
6054 + }
6055 +
6056 + if(error && *error) {
6057 + if((error_fd = open(error, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {
6058 + fprintf(stderr, "Cannot open error log file '%s' (%s).", error, strerror(errno));
6059 + if(input_fd != -1) close(input_fd);
6060 + if(output_fd != -1) close(output_fd);
6061 + return -1;
6062 + }
6063 + }
6064 +
6065 + if(access && *access && access_fd) {
6066 + if((*access_fd = open(access, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {
6067 + fprintf(stderr, "Cannot open access log file '%s' (%s).", access, strerror(errno));
6068 + if(input_fd != -1) close(input_fd);
6069 + if(output_fd != -1) close(output_fd);
6070 + if(error_fd != -1) close(error_fd);
6071 + return -1;
6072 + }
6073 +
6074 + if(access_fp) {
6075 + *access_fp = fdopen(*access_fd, "w");
6076 + if(!*access_fp) {
6077 + fprintf(stderr, "Cannot migrate file's '%s' fd %d (%s).\n", access, *access_fd, strerror(errno));
6078 + if(input_fd != -1) close(input_fd);
6079 + if(output_fd != -1) close(output_fd);
6080 + if(error_fd != -1) close(error_fd);
6081 + close(*access_fd);
6082 + *access_fd = -1;
6083 + return -1;
6084 + }
6085 + }
6086 + }
6087 +
6088 + if((dev_null = open("/dev/null", O_RDWR, 0666)) == -1) {
6089 + perror("Cannot open /dev/null");
6090 + if(input_fd != -1) close(input_fd);
6091 + if(output_fd != -1) close(output_fd);
6092 + if(error_fd != -1) close(error_fd);
6093 + if(access && access_fd && *access_fd != -1) {
6094 + close(*access_fd);
6095 + *access_fd = -1;
6096 + if(access_fp) {
6097 + fclose(*access_fp);
6098 + *access_fp = NULL;
6099 + }
6100 + }
6101 + return -1;
6102 + }
6103 +
6104 + // all files opened
6105 + // lets do it
6106 +
6107 int i = fork();
6108 if(i == -1) {
6109 perror("cannot fork");
@@ -6066,31 +6135,62 @@ void become_daemon()
6135 umask(0);
6136
6137 // close all files
6069 - for(i = sysconf(_SC_OPEN_MAX); i > 0; i--)
6070 - if(i != debug_fd && i != access_fd && i != listen_fd && fd_is_valid(i)) close(i);
6138 + if(close_all_files) {
6139 + for(i = sysconf(_SC_OPEN_MAX); i > 0; i--)
6140 + if(
6141 + ((access_fd && i != *access_fd) || !access_fd)
6142 + && i != dev_null
6143 + && i != input_fd
6144 + && i != output_fd
6145 + && i != error_fd
6146 + && fd_is_valid(i)
6147 + ) close(i);
6148 + }
6149 + else {
6150 + close(STDIN_FILENO);
6151 + close(STDOUT_FILENO);
6152 + close(STDERR_FILENO);
6153 + }
6154
6072 - silent = 0;
6073 - if(debug_fd == -1) {
6074 - silent = 1;
6075 - debug_fd = open("/dev/null", O_RDWR | O_APPEND | O_CREAT, 0666);
6155 + // put the opened files
6156 + // to our standard file descriptors
6157 + if(input_fd != -1) {
6158 + if(input_fd != STDIN_FILENO) {
6159 + dup2(input_fd, STDIN_FILENO);
6160 + close(input_fd);
6161 + }
6162 + input_fd = -1;
6163 + }
6164 + else dup2(dev_null, STDIN_FILENO);
6165 +
6166 + if(output_fd != -1) {
6167 + if(output_fd != STDOUT_FILENO) {
6168 + dup2(output_fd, STDOUT_FILENO);
6169 + close(output_fd);
6170 + }
6171 + output_fd = -1;
6172 }
6173 + else dup2(dev_null, STDOUT_FILENO);
6174
6078 - if(debug_fd != -1) {
6079 - if(dup2(debug_fd, STDIN_FILENO) < 0)
6080 - silent = 1;
6175 + if(error_fd != -1) {
6176 + if(error_fd != STDERR_FILENO) {
6177 + dup2(error_fd, STDERR_FILENO);
6178 + close(error_fd);
6179 + }
6180 + error_fd = -1;
6181 + }
6182 + else dup2(dev_null, STDERR_FILENO);
6183
6082 - if(dup2(debug_fd, STDOUT_FILENO) < 0)
6083 - silent = 1;
6184 + // close /dev/null
6185 + if(dev_null != STDIN_FILENO && dev_null != STDOUT_FILENO && dev_null != STDERR_FILENO)
6186 + close(dev_null);
6187
6085 - if(dup2(debug_fd, STDERR_FILENO) < 0)
6086 - silent = 1;
6087 - }
6088 - else silent = 1;
6188 + return(0);
6189 }
6190
6191 int main(int argc, char **argv)
6192 {
6093 - int i, daemon = 0;
6193 + int i;
6194 int config_loaded = 0;
6195
6196
@@ -6107,10 +6207,7 @@ int main(int argc, char **argv)
6207 }
6208 i++;
6209 }
6110 - else if(strcmp(argv[i], "-dl") == 0 && (i+1) < argc) { config_set("debug", "log", argv[i+1]); i++; }
6111 - else if(strcmp(argv[i], "-df") == 0 && (i+1) < argc) { config_set("debug", "flags", argv[i+1]); i++; }
6112 - else if(strcmp(argv[i], "-d") == 0) { config_set_number("global", "daemon", 1); }
6113 - else if(strcmp(argv[i], "-nd") == 0) { config_set_number("global", "daemon", 0); }
6210 + else if(strcmp(argv[i], "-df") == 0 && (i+1) < argc) { config_set("global", "debug flags", argv[i+1]); i++; }
6211 else if(strcmp(argv[i], "-p") == 0 && (i+1) < argc) { config_set("global", "port", argv[i+1]); i++; }
6212 else if(strcmp(argv[i], "-u") == 0 && (i+1) < argc) { config_set("global", "run as user", argv[i+1]); i++; }
6213 else if(strcmp(argv[i], "-l") == 0 && (i+1) < argc) { config_set("global", "history", argv[i+1]); i++; }
@@ -6119,13 +6216,10 @@ int main(int argc, char **argv)
6216 fprintf(stderr, "Cannot understand option '%s'.\n", argv[i]);
6217 fprintf(stderr, "\nUSAGE: %s [-d] [-l LINES_TO_SAVE] [-u UPDATE_TIMER] [-p LISTEN_PORT] [-dl debug log file] [-df debug flags].\n\n", argv[0]);
6218 fprintf(stderr, " -c CONFIG FILE the configuration file to load. Default: %s.\n", CONFIG_FILENAME);
6122 - fprintf(stderr, " -d enable daemon mode (run in the background).\n");
6123 - fprintf(stderr, " -nd disable daemon mode (do not run in the background).\n");
6219 fprintf(stderr, " -l LINES_TO_SAVE can be from 5 to %d lines in JSON data. Default: %d.\n", HISTORY_MAX, HISTORY);
6220 fprintf(stderr, " -t UPDATE_TIMER can be from 1 to %d seconds. Default: %d.\n", UPDATE_EVERY_MAX, UPDATE_EVERY);
6221 fprintf(stderr, " -p LISTEN_PORT can be from 1 to %d. Default: %d.\n", 65535, LISTEN_PORT);
6222 fprintf(stderr, " -u USERNAME can be any system username to run as. Default: none.\n");
6128 - fprintf(stderr, " -dl FILENAME write debug log to FILENAME. Default: none.\n");
6223 fprintf(stderr, " -df FLAGS debug options. Default: 0x%8llx.\n", debug_flags);
6224 exit(1);
6225 }
@@ -6133,59 +6227,58 @@ int main(int argc, char **argv)
6227
6228 if(!config_loaded) load_config(NULL, 0);
6229
6230 + char *input_log_file = NULL;
6231 + char *output_log_file = NULL;
6232 + char *error_log_file = NULL;
6233 + char *access_log_file = NULL;
6234 {
6235 char buffer[1024];
6236
6237 // --------------------------------------------------------------------
6238
6239 sprintf(buffer, "0x%08llx", debug_flags);
6142 - char *flags = config_get("debug", "flags", buffer);
6240 + char *flags = config_get("global", "debug flags", buffer);
6241 debug_flags = strtoull(flags, NULL, 0);
6242 debug(D_OPTIONS, "Debug flags set to '0x%8llx'.", debug_flags);
6243
6244 // --------------------------------------------------------------------
6245
6148 - debug_log = config_get("debug", "log", "");
6149 - if(*debug_log) {
6150 - debug_fd = open(debug_log, O_RDWR | O_APPEND | O_CREAT, 0666);
6151 - if(debug_fd < 0) {
6152 - fprintf(stderr, "Cannot open file '%s'. Reason: %s\n", debug_log, strerror(errno));
6153 - exit(1);
6154 - }
6155 - debug(D_OPTIONS, "Debug LOG set to '%s'.", debug_log);
6246 + output_log_file = config_get("global", "debug log", "none");
6247 + if(strcmp(output_log_file, "syslog") == 0) {
6248 + output_log_syslog = 1;
6249 + output_log_file = NULL;
6250 + }
6251 + else if(strcmp(output_log_file, "none") == 0) {
6252 + output_log_syslog = 0;
6253 + output_log_file = NULL;
6254 }
6255 + else output_log_syslog = 0;
6256
6257 // --------------------------------------------------------------------
6258
6160 - access_log = config_get("global", "access log", "syslog");
6161 - if(strcmp(access_log, "syslog") == 0) {
6162 - log_syslog = 1;
6163 - access_fd = -1;
6164 - stdaccess = NULL;
6165 -
6166 - debug(D_OPTIONS, "access log on syslog.");
6259 + error_log_file = config_get("global", "error log", "syslog");
6260 + if(strcmp(error_log_file, "syslog") == 0) {
6261 + error_log_syslog = 1;
6262 + error_log_file = NULL;
6263 }
6168 - else if(strcmp(access_log, "none") == 0) {
6169 - log_syslog = 0;
6170 - access_fd = -1;
6171 - stdaccess = NULL;
6172 - debug(D_OPTIONS, "access log disabled.");
6264 + else if(strcmp(error_log_file, "none") == 0) {
6265 + error_log_syslog = 0;
6266 + error_log_file = NULL;
6267 }
6174 - else {
6175 - access_fd = open(access_log, O_WRONLY | O_APPEND | O_CREAT, 0666);
6176 - if(access_fd < 0) {
6177 - fprintf(stderr, "Cannot open file '%s'. Reason: %s\n", access_log, strerror(errno));
6178 - exit(1);
6179 - }
6268 + else error_log_syslog = 0;
6269
6181 - stdaccess = fdopen(access_fd, "w");
6182 - if(!stdaccess) {
6183 - fprintf(stderr, "Cannot migrate file's '%s' fd %d. Reason: %s\n", access_log, access_fd, strerror(errno));
6184 - exit(1);
6185 - }
6270 + // --------------------------------------------------------------------
6271
6187 - debug(D_OPTIONS, "access log to file '%s'.", access_log);
6272 + access_log_file = config_get("global", "access log", "syslog");
6273 + if(strcmp(access_log_file, "syslog") == 0) {
6274 + access_log_syslog = 1;
6275 + access_log_file = NULL;
6276 + }
6277 + else if(strcmp(access_log_file, "none") == 0) {
6278 + access_log_syslog = 0;
6279 + access_log_file = NULL;
6280 }
6281 + else access_log_syslog = 0;
6282
6283 // --------------------------------------------------------------------
6284
@@ -6235,10 +6328,6 @@ int main(int argc, char **argv)
6328 else debug(D_OPTIONS, "listen port set to %d.", listen_port);
6329
6330 listen_fd = create_listen_socket(listen_port);
6238 -
6239 - // --------------------------------------------------------------------
6240 -
6241 - daemon = config_get_boolean("global", "daemon", 0);
6331 }
6332
6333 // never become a problem
@@ -6250,9 +6339,13 @@ int main(int argc, char **argv)
6339 fprintf(stderr, "\n\nWARNING:\nThis system does not support [long double] variables properly.\nArithmetic overflows and rounding errors may occur.\n\n");
6340 }
6341
6253 - if(daemon) become_daemon();
6342 + if(become_daemon(0, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1) {
6343 + fprintf(stderr, "Cannot demonize myself (%s).", strerror(errno));
6344 + exit(1);
6345 + }
6346 +
6347
6255 - if(log_syslog) {
6348 + if(output_log_syslog || error_log_syslog || access_log_syslog) {
6349 openlog("netdata", LOG_PID, LOG_DAEMON);
6350 syslog(LOG_NOTICE, "netdata started.");
6351 }