@cryptotaxi247 / netdata-1 / commits / 7be4d1e56

proper log file management; re-opening logs on SIGHUP; updated logrotate; updated systemd.service

Costa Tsaousis committed Aug 12, 2016 at 21:18 UTC 7be4d1e56904c079e40a45b4e1ac85e5e940653a
7 files changed +218 -230
src/daemon.c
+24 -147
@@ -5,22 +5,32 @@ char pidfile[FILENAME_MAX + 1] = "";
5
6 void sig_handler_exit(int signo)
7 {
8 - if(signo) {
9 - error_log_limit_unlimited();
10 - error("Received signal %d. Exiting...", signo);
11 - netdata_exit = 1;
12 - }
8 + if(signo) {
9 + error_log_limit_unlimited();
10 + error("Received signal %d. Exiting...", signo);
11 + netdata_exit = 1;
12 + }
13 +}
14 +
15 +void sig_handler_logrotate(int signo)
16 +{
17 + if(signo) {
18 + error_log_limit_reset();
19 + info("Received signal %d to re-open the log files", signo);
20 + reopen_all_log_files();
21 + }
22 }
23
24 void sig_handler_save(int signo)
25 {
26 if(signo) {
27 + error_log_limit_reset();
28 info("Received signal %d to save the database...", signo);
29 rrdset_save_all();
30 }
31 }
32
23 -static void properly_chown_netdata_generated_file(int fd, uid_t uid, gid_t gid) {
33 +static void chown_open_file(int fd, uid_t uid, gid_t gid) {
34 if(fd == -1) return;
35
36 struct stat buf;
@@ -36,7 +46,7 @@ static void properly_chown_netdata_generated_file(int fd, uid_t uid, gid_t gid)
46 }
47 }
48
39 -int become_user(const char *username, int access_fd, int output_fd, int error_fd, int pid_fd)
49 +int become_user(const char *username, int pid_fd)
50 {
51 struct passwd *pw = getpwnam(username);
52 if(!pw) {
@@ -59,10 +69,10 @@ int become_user(const char *username, int access_fd, int output_fd, int error_fd
69 }
70 }
71
62 - properly_chown_netdata_generated_file(access_fd, uid, gid);
63 - properly_chown_netdata_generated_file(output_fd, uid, gid);
64 - properly_chown_netdata_generated_file(error_fd, uid, gid);
65 - properly_chown_netdata_generated_file(pid_fd, uid, gid);
72 + chown_open_file(STDOUT_FILENO, uid, gid);
73 + chown_open_file(STDERR_FILENO, uid, gid);
74 + chown_open_file(stdaccess_fd, uid, gid);
75 + chown_open_file(pid_fd, uid, gid);
76
77 if(supplementary_groups && ngroups) {
78 if(setgroups(ngroups, supplementary_groups) == -1)
@@ -133,81 +143,8 @@ int sched_setscheduler_idle(void) {
143 return i;
144 }
145
136 -int become_daemon(int dont_fork, int close_all_files, const char *user, const char *input, const char *output, const char *error, const char *access, int *access_fd, FILE **access_fp)
146 +int become_daemon(int dont_fork, const char *user)
147 {
138 - fflush(NULL);
139 -
140 - // open the files before forking
141 - int input_fd = -1, output_fd = -1, error_fd = -1, dev_null;
142 -
143 - if(input && *input) {
144 - if((input_fd = open(input, O_RDONLY, 0666)) == -1) {
145 - error("Cannot open input file '%s'.", input);
146 - return -1;
147 - }
148 - }
149 -
150 - if(output && *output && strcmp(output, "/dev/null") != 0) {
151 - if((output_fd = open(output, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {
152 - error("Cannot open output log file '%s'", output);
153 - if(input_fd != -1) close(input_fd);
154 - return -1;
155 - }
156 - }
157 -
158 - if(error && *error && strcmp(error, "/dev/null") != 0) {
159 - if((error_fd = open(error, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {
160 - error("Cannot open error log file '%s'.", error);
161 - if(input_fd != -1) close(input_fd);
162 - if(output_fd != -1) close(output_fd);
163 - return -1;
164 - }
165 - }
166 -
167 - if(access && *access && access_fd && strcmp(access, "/dev/null") != 0) {
168 - if((*access_fd = open(access, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {
169 - error("Cannot open access log file '%s'", access);
170 - if(input_fd != -1) close(input_fd);
171 - if(output_fd != -1) close(output_fd);
172 - if(error_fd != -1) close(error_fd);
173 - return -1;
174 - }
175 -
176 - if(access_fp) {
177 - *access_fp = fdopen(*access_fd, "w");
178 - if(!*access_fp) {
179 - error("Cannot migrate file's '%s' fd %d.", access, *access_fd);
180 - if(input_fd != -1) close(input_fd);
181 - if(output_fd != -1) close(output_fd);
182 - if(error_fd != -1) close(error_fd);
183 - close(*access_fd);
184 - *access_fd = -1;
185 - return -1;
186 - }
187 - if(setvbuf(*access_fp, NULL, _IOLBF, 0) != 0)
188 - error("Cannot set line buffering on access.log");
189 - }
190 - }
191 -
192 - if((dev_null = open("/dev/null", O_RDWR, 0666)) == -1) {
193 - perror("Cannot open /dev/null");
194 - if(input_fd != -1) close(input_fd);
195 - if(output_fd != -1) close(output_fd);
196 - if(error_fd != -1) close(error_fd);
197 - if(access && access_fd && *access_fd != -1) {
198 - close(*access_fd);
199 - *access_fd = -1;
200 - if(access_fp) {
201 - fclose(*access_fp);
202 - *access_fp = NULL;
203 - }
204 - }
205 - return -1;
206 - }
207 -
208 - // all files opened
209 - // lets do it
210 -
148 if(!dont_fork) {
149 int i = fork();
150 if(i == -1) {
@@ -235,70 +172,10 @@ int become_daemon(int dont_fork, int close_all_files, const char *user, const ch
172 }
173 }
174
238 - // close all files
239 - if(close_all_files) {
240 - int i;
241 - for(i = (int) (sysconf(_SC_OPEN_MAX) - 1); i > 0; i--)
242 - if(
243 - ((access_fd && i != *access_fd) || !access_fd)
244 - && i != dev_null
245 - && i != input_fd
246 - && i != output_fd
247 - && i != error_fd
248 - && fd_is_valid(i)
249 - ) close(i);
250 - }
251 - else {
252 - close(STDIN_FILENO);
253 - close(STDOUT_FILENO);
254 - close(STDERR_FILENO);
255 - }
256 -
257 - // put the opened files
258 - // to our standard file descriptors
259 - if(input_fd != -1) {
260 - if(input_fd != STDIN_FILENO) {
261 - dup2(input_fd, STDIN_FILENO);
262 - close(input_fd);
263 - }
264 - input_fd = -1;
265 - }
266 - else dup2(dev_null, STDIN_FILENO);
267 -
268 - if(output_fd != -1) {
269 - if(output_fd != STDOUT_FILENO) {
270 - dup2(output_fd, STDOUT_FILENO);
271 - close(output_fd);
272 - }
273 -
274 - if(setvbuf(stdout, NULL, _IOLBF, 0) != 0)
275 - error("Cannot set line buffering on debug.log");
276 -
277 - output_fd = STDOUT_FILENO;
278 - }
279 - else dup2(dev_null, STDOUT_FILENO);
280 -
281 - if(error_fd != -1) {
282 - if(error_fd != STDERR_FILENO) {
283 - dup2(error_fd, STDERR_FILENO);
284 - close(error_fd);
285 - }
286 -
287 - if(setvbuf(stderr, NULL, _IOLBF, 0) != 0)
288 - error("Cannot set line buffering on error.log");
289 -
290 - error_fd = STDERR_FILENO;
291 - }
292 - else dup2(dev_null, STDERR_FILENO);
293 -
294 - // close /dev/null
295 - if(dev_null != STDIN_FILENO && dev_null != STDOUT_FILENO && dev_null != STDERR_FILENO)
296 - close(dev_null);
297 -
175 // generate our pid file
176 int pidfd = -1;
177 if(pidfile[0]) {
301 - pidfd = open(pidfile, O_RDWR | O_CREAT, 0644);
178 + pidfd = open(pidfile, O_WRONLY | O_CREAT, 0644);
179 if(pidfd >= 0) {
180 if(ftruncate(pidfd, 0) != 0)
181 error("Cannot truncate pidfile '%s'.", pidfile);
@@ -325,7 +202,7 @@ int become_daemon(int dont_fork, int close_all_files, const char *user, const ch
202 }
203
204 if(user && *user) {
328 - if(become_user(user, (access_fd)?*access_fd:-1, output_fd, error_fd, pidfd) != 0) {
205 + if(become_user(user, pidfd) != 0) {
206 error("Cannot become user '%s'. Continuing as we are.", user);
207 }
208 else info("Successfully became user '%s'.", user);
src/daemon.h
+3 -2
@@ -3,10 +3,11 @@
3
4 extern void sig_handler_exit(int signo);
5 extern void sig_handler_save(int signo);
6 +extern void sig_handler_logrotate(int signo);
7
7 -extern int become_user(const char *username, int access_fd, int output_fd, int error_fd, int pid_fd);
8 +extern int become_user(const char *username, int pid_fd);
9
9 -extern int become_daemon(int dont_fork, int close_all_files, const char *user, const char *input, const char *output, const char *error, const char *access, int *access_fd, FILE **access_fp);
10 +extern int become_daemon(int dont_fork, const char *user);
11
12 extern void netdata_cleanup_and_exit(int i);
13
src/log.c
+132 -8
@@ -1,20 +1,125 @@
1 #include "common.h"
2
3 -// ----------------------------------------------------------------------------
4 -// LOG
5 -
3 const char *program_name = "";
4 unsigned long long debug_flags = DEBUG;
5
9 -int silent = 0;
10 -
11 -int access_fd = -1;
12 -FILE *stdaccess = NULL;
13 -
6 int access_log_syslog = 1;
7 int error_log_syslog = 1;
8 int output_log_syslog = 1; // debug log
9
10 +int stdaccess_fd = -1;
11 +FILE *stdaccess = NULL;
12 +
13 +const char *stdaccess_filename = NULL;
14 +const char *stderr_filename = NULL;
15 +const char *stdout_filename = NULL;
16 +
17 +void syslog_init(void) {
18 + static int i = 0;
19 +
20 + if(!i) {
21 + openlog(program_name, LOG_PID, LOG_DAEMON);
22 + i = 1;
23 + }
24 +}
25 +
26 +int open_log_file(int fd, FILE **fp, const char *filename, int *enabled_syslog) {
27 + int f, t;
28 +
29 + if(!filename || !*filename || !strcmp(filename, "none"))
30 + filename = "/dev/null";
31 +
32 + if(!strcmp(filename, "syslog")) {
33 + filename = "/dev/null";
34 + syslog_init();
35 + if(enabled_syslog) *enabled_syslog = 1;
36 + }
37 + else if(enabled_syslog) *enabled_syslog = 0;
38 +
39 + // don't do anything if the user is willing
40 + // to have the standard one
41 + if(!strcmp(filename, "system"))
42 + return fd;
43 +
44 + if(!strcmp(filename, "stdout"))
45 + f = STDOUT_FILENO;
46 +
47 + else if(!strcmp(filename, "stderr"))
48 + f = STDERR_FILENO;
49 +
50 + else {
51 + f = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0664);
52 + if(f == -1) {
53 + error("Cannot open file '%s'. Leaving %d to its default.", filename, fd);
54 + return fd;
55 + }
56 + }
57 +
58 + // if there is a level-2 file pointer
59 + // flush it before switching the level-1 fds
60 + if(fp && *fp)
61 + fflush(*fp);
62 +
63 + if(fd != f && fd != -1) {
64 + // it automatically closes
65 + t = dup2(f, fd);
66 + if (t == -1) {
67 + error("Cannot dup2() new fd %d to old fd %d for '%s'", f, fd, filename);
68 + close(f);
69 + return fd;
70 + }
71 + // info("dup2() new fd %d to old fd %d for '%s'", f, fd, filename);
72 + close(f);
73 + }
74 + else fd = f;
75 +
76 + if(fp && *fp == NULL) {
77 + // info("fdopen(%d) on filename '%s'", fd, filename);
78 +
79 + FILE *n = fdopen(fd, "a");
80 + if (!n)
81 + error("Cannot fdopen() fd %d ('%s')", fd, filename);
82 +
83 + else {
84 + if (setvbuf(n, NULL, _IOLBF, 0) != 0)
85 + error("Cannot set line buffering on fd %d ('%s')", fd, filename);
86 +
87 + if(!*fp)
88 + *fp = n;
89 + else {
90 + FILE *o = *fp;
91 + *fp = n;
92 + fclose(o);
93 + }
94 + }
95 + }
96 +
97 + return fd;
98 +}
99 +
100 +void reopen_all_log_files() {
101 + if(stdout_filename)
102 + open_log_file(STDOUT_FILENO, &stdout, stdout_filename, &output_log_syslog);
103 +
104 + if(stderr_filename)
105 + open_log_file(STDERR_FILENO, &stderr, stderr_filename, &error_log_syslog);
106 +
107 + if(stdaccess_filename)
108 + stdaccess_fd = open_log_file(stdaccess_fd, &stdaccess, stdaccess_filename, &access_log_syslog);
109 +}
110 +
111 +void open_all_log_files() {
112 + // disable stdin
113 + open_log_file(STDIN_FILENO, &stdin, "/dev/null", NULL);
114 +
115 + open_log_file(STDOUT_FILENO, &stdout, stdout_filename, &output_log_syslog);
116 + open_log_file(STDERR_FILENO, &stderr, stderr_filename, &error_log_syslog);
117 + stdaccess_fd = open_log_file(stdaccess_fd, &stdaccess, stdaccess_filename, &access_log_syslog);
118 +}
119 +
120 +// ----------------------------------------------------------------------------
121 +// error log throttling
122 +
123 time_t error_log_throttle_period = 1200;
124 unsigned long error_log_errors_per_period = 200;
125
@@ -94,6 +199,13 @@ int error_log_limit(int reset) {
199 return 0;
200 }
201
202 +// ----------------------------------------------------------------------------
203 +// print the date
204 +
205 +// FIXME
206 +// this should print the date in a buffer the way it
207 +// is now, logs from multiple threads may be multiplexed
208 +
209 void log_date(FILE *out)
210 {
211 char outstr[24];
@@ -109,6 +221,9 @@ void log_date(FILE *out)
221 fprintf(out, "%s: ", outstr);
222 }
223
224 +// ----------------------------------------------------------------------------
225 +// debug log
226 +
227 void debug_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... )
228 {
229 va_list args;
@@ -129,6 +244,9 @@ void debug_int( const char *file, const char *function, const unsigned long line
244 fflush(stdout);
245 }
246
247 +// ----------------------------------------------------------------------------
248 +// info log
249 +
250 void info_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... )
251 {
252 va_list args;
@@ -153,6 +271,9 @@ void info_int( const char *file, const char *function, const unsigned long line,
271 }
272 }
273
274 +// ----------------------------------------------------------------------------
275 +// error log
276 +
277 void error_int( const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ... )
278 {
279 va_list args;
@@ -207,6 +328,9 @@ void fatal_int( const char *file, const char *function, const unsigned long line
328 netdata_cleanup_and_exit(1);
329 }
330
331 +// ----------------------------------------------------------------------------
332 +// access log
333 +
334 void log_access( const char *fmt, ... )
335 {
336 va_list args;
src/log.h
+9 -4
@@ -33,11 +33,13 @@ extern unsigned long long debug_flags;
33
34 extern const char *program_name;
35
36 -extern int silent;
37 -
38 -extern int access_fd;
36 +extern int stdaccess_fd;
37 extern FILE *stdaccess;
38
39 +extern const char *stdaccess_filename;
40 +extern const char *stderr_filename;
41 +extern const char *stdout_filename;
42 +
43 extern int access_log_syslog;
44 extern int error_log_syslog;
45 extern int output_log_syslog;
@@ -46,10 +48,13 @@ extern time_t error_log_throttle_period;
48 extern unsigned long error_log_errors_per_period;
49 extern int error_log_limit(int reset);
50
51 +extern void open_all_log_files();
52 +extern void reopen_all_log_files();
53 +
54 #define error_log_limit_reset() do { error_log_limit(1); } while(0)
55 #define error_log_limit_unlimited() do { error_log_throttle_period = 0; } while(0)
56
52 -#define debug(type, args...) do { if(unlikely(!silent && (debug_flags & type))) debug_int(__FILE__, __FUNCTION__, __LINE__, ##args); } while(0)
57 +#define debug(type, args...) do { if(unlikely(debug_flags & type)) debug_int(__FILE__, __FUNCTION__, __LINE__, ##args); } while(0)
58 #define info(args...) info_int(__FILE__, __FUNCTION__, __LINE__, ##args)
59 #define infoerr(args...) error_int("INFO", __FILE__, __FUNCTION__, __LINE__, ##args)
60 #define error(args...) error_int("ERROR", __FILE__, __FUNCTION__, __LINE__, ##args)
src/main.c
+21 -51
@@ -420,10 +420,6 @@ int main(int argc, char **argv)
420 // cd to /tmp to avoid any plugins writing files at random places
421 if(chdir("/tmp")) error("netdata: ERROR: Cannot cd to /tmp");
422
423 - char *input_log_file = NULL;
424 - char *output_log_file = NULL;
425 - char *error_log_file = NULL;
426 - char *access_log_file = NULL;
423 char *user = NULL;
424 {
425 char *flags = config_get("global", "debug flags", "0x00000000");
@@ -449,36 +445,14 @@ int main(int argc, char **argv)
445
446 // --------------------------------------------------------------------
447
452 -
448 global_host_prefix = config_get("global", "host access prefix", "");
449 setenv("NETDATA_HOST_PREFIX", global_host_prefix, 1);
450
451 // --------------------------------------------------------------------
452
458 - output_log_file = config_get("global", "debug log", LOG_DIR "/debug.log");
459 - if(strcmp(output_log_file, "syslog") == 0) {
460 - output_log_syslog = 1;
461 - output_log_file = NULL;
462 - }
463 - else if(strcmp(output_log_file, "none") == 0) {
464 - output_log_syslog = 0;
465 - output_log_file = NULL;
466 - }
467 - else output_log_syslog = 0;
468 -
469 - // --------------------------------------------------------------------
470 -
471 - error_log_file = config_get("global", "error log", LOG_DIR "/error.log");
472 - if(strcmp(error_log_file, "syslog") == 0) {
473 - error_log_syslog = 1;
474 - error_log_file = NULL;
475 - }
476 - else if(strcmp(error_log_file, "none") == 0) {
477 - error_log_syslog = 0;
478 - error_log_file = NULL;
479 - // optimization - do not even generate debug log entries
480 - }
481 - else error_log_syslog = 0;
453 + stdout_filename = config_get("global", "debug log", LOG_DIR "/debug.log");
454 + stderr_filename = config_get("global", "error log", LOG_DIR "/error.log");
455 + stdaccess_filename = config_get("global", "access log", LOG_DIR "/access.log");
456
457 error_log_throttle_period = config_get_number("global", "errors flood protection period", error_log_throttle_period);
458 setenv("NETDATA_ERRORS_THROTTLE_PERIOD", config_get("global", "errors flood protection period" , ""), 1);
@@ -488,19 +462,6 @@ int main(int argc, char **argv)
462
463 // --------------------------------------------------------------------
464
491 - access_log_file = config_get("global", "access log", LOG_DIR "/access.log");
492 - if(strcmp(access_log_file, "syslog") == 0) {
493 - access_log_syslog = 1;
494 - access_log_file = NULL;
495 - }
496 - else if(strcmp(access_log_file, "none") == 0) {
497 - access_log_syslog = 0;
498 - access_log_file = NULL;
499 - }
500 - else access_log_syslog = 0;
501 -
502 - // --------------------------------------------------------------------
503 -
465 rrd_memory_mode = rrd_memory_mode_id(config_get("global", "memory mode", rrd_memory_mode_name(rrd_memory_mode)));
466
467 // --------------------------------------------------------------------
@@ -551,17 +512,13 @@ int main(int argc, char **argv)
512 error("Could not block signals for threads");
513 }
514
554 - // Catch signals which we want to use to quit savely
515 + // Catch signals which we want to use
516 struct sigaction sa;
517 sigemptyset(&sa.sa_mask);
557 - sigaddset(&sa.sa_mask, SIGHUP);
518 sigaddset(&sa.sa_mask, SIGINT);
519 sigaddset(&sa.sa_mask, SIGTERM);
520 sa.sa_handler = sig_handler_exit;
521 sa.sa_flags = 0;
562 - if(sigaction(SIGHUP, &sa, NULL) == -1) {
563 - error("Failed to change signal handler for SIGHUP");
564 - }
522 if(sigaction(SIGINT, &sa, NULL) == -1) {
523 error("Failed to change signal handler for SIGINT");
524 }
@@ -569,7 +526,17 @@ int main(int argc, char **argv)
526 error("Failed to change signal handler for SIGTERM");
527 }
528
529 + sigemptyset(&sa.sa_mask);
530 + sigaddset(&sa.sa_mask, SIGHUP);
531 + sa.sa_handler = sig_handler_logrotate;
532 + sa.sa_flags = 0;
533 + if(sigaction(SIGHUP, &sa, NULL) == -1) {
534 + error("Failed to change signal handler for SIGHUP");
535 + }
536 +
537 // save database on SIGUSR1
538 + sigemptyset(&sa.sa_mask);
539 + sigaddset(&sa.sa_mask, SIGUSR1);
540 sa.sa_handler = sig_handler_save;
541 if(sigaction(SIGUSR1, &sa, NULL) == -1) {
542 error("Failed to change signal handler for SIGUSR1");
@@ -578,6 +545,8 @@ int main(int argc, char **argv)
545 // Ignore SIGPIPE completely.
546 // INFO: If we add signals here we have to unblock them
547 // at popen.c when running a external plugin.
548 + sigemptyset(&sa.sa_mask);
549 + sigaddset(&sa.sa_mask, SIGPIPE);
550 sa.sa_handler = SIG_IGN;
551 if(sigaction(SIGPIPE, &sa, NULL) == -1) {
552 error("Failed to change signal handler for SIGPIPE");
@@ -621,7 +590,11 @@ int main(int argc, char **argv)
590 create_listen_sockets();
591 }
592
624 - if(become_daemon(dont_fork, 0, user, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1)
593 + // initialize the log files
594 + open_all_log_files();
595 +
596 + // become daemon, switch user, create pid file, set process attributes
597 + if(become_daemon(dont_fork, user) == -1)
598 fatal("Cannot demonize myself.");
599
600 #ifdef NETDATA_INTERNAL_CHECKS
@@ -633,9 +606,6 @@ int main(int argc, char **argv)
606 }
607 #endif /* NETDATA_INTERNAL_CHECKS */
608
636 - if(output_log_syslog || error_log_syslog || access_log_syslog)
637 - openlog("netdata", LOG_PID, LOG_DAEMON);
638 -
609 info("NetData started on pid %d", getpid());
610
611
system/netdata.logrotate.in
+4 -10
@@ -6,14 +6,8 @@
6 delaycompress
7 notifempty
8 sharedscripts
9 - #
10 - # if you add netdata to your init.d/system.d
11 - # comment su & copytruncate and uncomment postrotate
12 - # to have netdata restart when logs are rotated
13 - create 0640 netdata netdata
14 - copytruncate
15 - #
16 - #postrotate
17 - # /sbin/service netdata try-restart >/dev/null
18 - #endscript
9 + create 0664 netdata netdata
10 + postrotate
11 + /sbin/killall -HUP netdata
12 + endscript
13 }
system/netdata.service.in
+25 -8
@@ -1,27 +1,44 @@
1 [Unit]
2 -Description=Linux real time system monitoring, done right
2 +Description=Real time performance monitoring
3 After=network.target httpd.service squid.service nfs-server.service mysqld.service named.service postfix.service
4
5 [Service]
6 -Type=forking
6 +Type=simple
7 WorkingDirectory=/tmp
8 User=netdata
9 Group=netdata
10 RuntimeDirectory=netdata
11 -PIDFile=@localstatedir_POST@/run/netdata/netdata.pid
12 -ExecStart=@sbindir_POST@/netdata -P @localstatedir_POST@/run/netdata/netdata.pid
11 +ExecStartPre=/bin/mkdir -p @localstatedir_POST@/run/netdata
12 +ExecStartPre=/bin/chown -R netdata:netdata @localstatedir_POST@/run/netdata
13 +ExecStartPre=/bin/chmod 0775 @localstatedir_POST@/run/netdata
14 +ExecStart=@sbindir_POST@/netdata -D -P @localstatedir_POST@/run/netdata/netdata.pid
15 +
16 +# -----------------------------------------------------------------------------
17 +# Stopping netdata
18 +
19 KillMode=mixed
20 KillSignal=SIGTERM
15 -TimeoutStopSec=30
21
17 -#Hardening
22 +# saving a big db on slow disks may need some time
23 +TimeoutStopSec=60
24 +
25 +# and disable SIGKILL - if sent during save, we will loose the db
26 +SendSIGKILL=no
27 +
28 +# -----------------------------------------------------------------------------
29 +# Hardening netdata
30 +
31 AmbientCapabilities=CAP_DAC_READ_SEARCH CAP_SYS_PTRACE
32 CapabilityBoundingSet=CAP_DAC_READ_SEARCH CAP_SYS_PTRACE
33 PrivateTmp=true
34 ProtectSystem=full
35 ProtectHome=read-only
23 -#NoNewPrivileges=true is implicitly set by the MemoryDenyWriteExecute=true
24 -MemoryDenyWriteExecute=true
36 +
37 +# is implicitly set by the MemoryDenyWriteExecute=true
38 +# NoNewPrivileges=true
39 +
40 +# Do not enable - it makes node.js plugins to crash
41 +# MemoryDenyWriteExecute=true
42
43 [Install]
44 WantedBy=multi-user.target