xref: /PHP-7.4/sapi/fpm/fpm/fpm_systemd.c (revision 1ad08256)
1 #include "fpm_config.h"
2 
3 #include <sys/types.h>
4 #include <systemd/sd-daemon.h>
5 
6 #include "fpm.h"
7 #include "fpm_clock.h"
8 #include "fpm_worker_pool.h"
9 #include "fpm_scoreboard.h"
10 #include "zlog.h"
11 #include "fpm_systemd.h"
12 
13 
fpm_systemd()14 static void fpm_systemd() /* {{{ */
15 {
16 	static unsigned long int last=0;
17 	struct fpm_worker_pool_s *wp;
18 	unsigned long int requests=0, slow_req=0;
19 	int active=0, idle=0;
20 
21 
22 	for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
23 		if (wp->scoreboard) {
24 			active   += wp->scoreboard->active;
25 			idle     += wp->scoreboard->idle;
26 			requests += wp->scoreboard->requests;
27 			slow_req += wp->scoreboard->slow_rq;
28 		}
29 	}
30 
31 /*
32 	zlog(ZLOG_DEBUG, "systemd %s (Processes active:%d, idle:%d, Requests:%lu, slow:%lu, Traffic:%.3greq/sec)",
33 			fpm_global_config.systemd_watchdog ? "watchdog" : "heartbeat",
34 			active, idle, requests, slow_req, ((float)requests - last) * 1000.0 / fpm_global_config.systemd_interval);
35 */
36 
37 	if (0 > sd_notifyf(0, "READY=1\n%s"
38 				"STATUS=Processes active: %d, idle: %d, Requests: %lu, slow: %lu, Traffic: %.3greq/sec",
39 				fpm_global_config.systemd_watchdog ? "WATCHDOG=1\n" : "",
40 				active, idle, requests, slow_req, ((float)requests - last) * 1000.0 / fpm_global_config.systemd_interval)) {
41 		zlog(ZLOG_NOTICE, "failed to notify status to systemd");
42 	}
43 
44 	last = requests;
45 }
46 /* }}} */
47 
fpm_systemd_heartbeat(struct fpm_event_s * ev,short which,void * arg)48 void fpm_systemd_heartbeat(struct fpm_event_s *ev, short which, void *arg) /* {{{ */
49 {
50 	static struct fpm_event_s heartbeat;
51 
52 	if (fpm_globals.parent_pid != getpid()) {
53 		return; /* sanity check */
54 	}
55 
56 	if (which == FPM_EV_TIMEOUT) {
57 		fpm_systemd();
58 
59 		return;
60 	}
61 
62 	if (0 > sd_notifyf(0, "READY=1\n"
63 			          "STATUS=Ready to handle connections\n"
64 			          "MAINPID=%lu",
65 			          (unsigned long) getpid())) {
66 		zlog(ZLOG_WARNING, "failed to notify start to systemd");
67 	} else {
68 		zlog(ZLOG_DEBUG, "have notify start to systemd");
69 	}
70 
71 	/* first call without setting which to initialize the timer */
72 	if (fpm_global_config.systemd_interval > 0) {
73 		fpm_event_set_timer(&heartbeat, FPM_EV_PERSIST, &fpm_systemd_heartbeat, NULL);
74 		fpm_event_add(&heartbeat, fpm_global_config.systemd_interval);
75 		zlog(ZLOG_NOTICE, "systemd monitor interval set to %dms", fpm_global_config.systemd_interval);
76 	} else {
77 		zlog(ZLOG_NOTICE, "systemd monitor disabled");
78 	}
79 }
80 /* }}} */
81 
fpm_systemd_conf()82 int fpm_systemd_conf() /* {{{ */
83 {
84 	char *watchdog;
85 	int  interval = 0;
86 
87 	watchdog = getenv("WATCHDOG_USEC");
88 	if (watchdog) {
89 		/* usec to msec, and half the configured delay */
90 		interval = (int)(atol(watchdog) / 2000L);
91 		zlog(ZLOG_DEBUG, "WATCHDOG_USEC=%s, interval=%d", watchdog, interval);
92 	}
93 
94 	if (interval > 1000) {
95 		if (fpm_global_config.systemd_interval > 0) {
96 			zlog(ZLOG_WARNING, "systemd_interval option ignored");
97 		}
98 		zlog(ZLOG_NOTICE, "systemd watchdog configured to %.3gsec", (float)interval / 1000.0);
99 		fpm_global_config.systemd_watchdog = 1;
100 		fpm_global_config.systemd_interval = interval;
101 
102 	} else if (fpm_global_config.systemd_interval < 0) {
103 		/* not set => default value */
104 		fpm_global_config.systemd_interval = FPM_SYSTEMD_DEFAULT_HEARTBEAT;
105 
106 	} else {
107 		/* sec to msec */
108 		fpm_global_config.systemd_interval *= 1000;
109 	}
110 	return 0;
111 }
112 /* }}} */
113