Permalink
Browse files

- Implemented FR #54577 (Enhanced status page with full status and de…

…tails about each processes

- Added a web page (status.html) for real-time FPM status
- Fixed missing Expires and Cache-Control headers for ping and status pages
  • Loading branch information...
1 parent 7a40224 commit 1e0cb5fec5bec603ff26414731051e683c0e482b Jérôme Loyet committed Jul 2, 2011
View
@@ -18,3 +18,6 @@ install-fpm: $(SAPI_FPM_PATH)
@$(mkinstalldirs) $(INSTALL_ROOT)$(mandir)/man8
@$(INSTALL_DATA) sapi/fpm/php-fpm.8 $(INSTALL_ROOT)$(mandir)/man8/php-fpm$(program_suffix).8
+ @echo "Installing PHP FPM status page: $(INSTALL_ROOT)$(datadir)/fpm/"
+ @$(mkinstalldirs) $(INSTALL_ROOT)$(datadir)/fpm
+ @$(INSTALL_DATA) sapi/fpm/status.html $(INSTALL_ROOT)$(datadir)/fpm/status.html
View
@@ -49,7 +49,6 @@ int fpm_init(int argc, char **argv, char *config, char *prefix, int test_conf) /
if (0 > fpm_php_init_main() ||
0 > fpm_stdio_init_main() ||
- 0 > fpm_log_init_main() ||
0 > fpm_conf_init_main(test_conf) ||
0 > fpm_unix_init_main() ||
0 > fpm_scoreboard_init_main() ||
@@ -344,7 +344,8 @@ static void fpm_child_resources_use(struct fpm_child_s *child) /* {{{ */
}
fpm_scoreboard_free(wp->scoreboard);
}
- fpm_scoreboard_child_use(child->wp->scoreboard, child->scoreboard_i, child->pid);
+
+ fpm_scoreboard_child_use(child->wp->scoreboard, child->scoreboard_i, getpid());
fpm_stdio_child_use_pipes(child);
fpm_child_free(child);
}
View
@@ -29,9 +29,6 @@
static char *fpm_log_format = NULL;
static int fpm_log_fd = -1;
-#ifdef HAVE_TIMES
-static float tick;
-#endif
int fpm_log_open(int reopen) /* {{{ */
{
@@ -67,24 +64,6 @@ int fpm_log_open(int reopen) /* {{{ */
}
/* }}} */
-int fpm_log_init_main() /* {{{ */
-{
-#ifdef HAVE_TIMES
-#if (defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK))
- tick = sysconf(_SC_CLK_TCK);
-#else /* _SC_CLK_TCK */
-#ifdef HZ
- tick = HZ;
-#else /* HZ */
- tick = 100;
-#endif /* HZ */
-#endif /* _SC_CLK_TCK */
- zlog(ZLOG_DEBUG, "got clock tick '%.0f'", tick);
-#endif /* HAVE_TIMES */
- return 0;
-}
-/* }}} */
-
/* }}} */
int fpm_log_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
{
@@ -122,7 +101,6 @@ int fpm_log_write(char *log_format TSRMLS_DC) /* {{{ */
size_t len, len2;
struct fpm_scoreboard_proc_s proc, *proc_p;
struct fpm_scoreboard_s *scoreboard;
- struct timeval uptime, now;
char tmp[129];
char format[129];
time_t now_epoch;
@@ -141,7 +119,6 @@ int fpm_log_write(char *log_format TSRMLS_DC) /* {{{ */
test = 1;
}
- fpm_clock_get(&now);
now_epoch = time(NULL);
if (!test) {
@@ -157,8 +134,6 @@ int fpm_log_write(char *log_format TSRMLS_DC) /* {{{ */
}
proc = *proc_p;
fpm_scoreboard_proc_release(proc_p);
-
- timersub(&now, &proc.accepted, &uptime);
}
token = 0;
@@ -198,19 +173,15 @@ int fpm_log_write(char *log_format TSRMLS_DC) /* {{{ */
case 'C': /* %CPU */
if (format[0] == '\0' || !strcasecmp(format, "total")) {
if (!test) {
- tms_total =
- (proc.cpu_finished.tms_utime + proc.cpu_finished.tms_stime + proc.cpu_finished.tms_cutime + proc.cpu_finished.tms_cstime)
- -
- (proc.cpu_accepted.tms_utime + proc.cpu_accepted.tms_stime + proc.cpu_accepted.tms_cutime + proc.cpu_accepted.tms_cstime)
- ;
+ tms_total = proc.last_request_cpu.tms_utime + proc.last_request_cpu.tms_stime + proc.last_request_cpu.tms_cutime + proc.last_request_cpu.tms_cstime;
}
} else if (!strcasecmp(format, "user")) {
if (!test) {
- tms_total = (proc.cpu_finished.tms_utime + proc.cpu_finished.tms_cutime) - (proc.cpu_accepted.tms_utime + proc.cpu_accepted.tms_cutime);
+ tms_total = proc.last_request_cpu.tms_utime + proc.last_request_cpu.tms_cutime;
}
} else if (!strcasecmp(format, "system")) {
if (!test) {
- tms_total = (proc.cpu_finished.tms_stime + proc.cpu_finished.tms_cstime) - (proc.cpu_accepted.tms_stime + proc.cpu_accepted.tms_cstime);
+ tms_total = proc.last_request_cpu.tms_stime + proc.last_request_cpu.tms_cstime;
}
} else {
zlog(ZLOG_WARNING, "only 'total', 'user' or 'system' are allowed as a modifier for %%%c ('%s')", *s, format);
@@ -219,7 +190,7 @@ int fpm_log_write(char *log_format TSRMLS_DC) /* {{{ */
format[0] = '\0';
if (!test) {
- len2 = snprintf(b, FPM_LOG_BUFFER - len, "%.2f", tms_total / tick / (proc.cpu_duration.tv_sec + proc.cpu_duration.tv_usec / 1000000.) * 100.);
+ len2 = snprintf(b, FPM_LOG_BUFFER - len, "%.2f", tms_total / fpm_scoreboard_get_tick() / (proc.cpu_duration.tv_sec + proc.cpu_duration.tv_usec / 1000000.) * 100.);
}
break;
#endif
@@ -228,19 +199,19 @@ int fpm_log_write(char *log_format TSRMLS_DC) /* {{{ */
/* seconds */
if (format[0] == '\0' || !strcasecmp(format, "seconds")) {
if (!test) {
- len2 = snprintf(b, FPM_LOG_BUFFER - len, "%.3f", uptime.tv_sec + uptime.tv_usec / 1000000.);
+ len2 = snprintf(b, FPM_LOG_BUFFER - len, "%.3f", proc.duration.tv_sec + proc.duration.tv_usec / 1000000.);
}
/* miliseconds */
} else if (!strcasecmp(format, "miliseconds") || !strcasecmp(format, "mili")) {
if (!test) {
- len2 = snprintf(b, FPM_LOG_BUFFER - len, "%.3f", uptime.tv_sec * 1000. + uptime.tv_usec / 1000.);
+ len2 = snprintf(b, FPM_LOG_BUFFER - len, "%.3f", proc.duration.tv_sec * 1000. + proc.duration.tv_usec / 1000.);
}
/* microseconds */
} else if (!strcasecmp(format, "microseconds") || !strcasecmp(format, "micro")) {
if (!test) {
- len2 = snprintf(b, FPM_LOG_BUFFER - len, "%lu", uptime.tv_sec * 1000000UL + uptime.tv_usec);
+ len2 = snprintf(b, FPM_LOG_BUFFER - len, "%lu", proc.duration.tv_sec * 1000000UL + proc.duration.tv_usec);
}
} else {
View
@@ -6,7 +6,6 @@
#define FPM_LOG_H 1
#include "fpm_worker_pool.h"
-int fpm_log_init_main();
int fpm_log_init_child(struct fpm_worker_pool_s *wp);
int fpm_log_write(char *log_format TSRMLS_DC);
int fpm_log_open(int reopen);
View
@@ -23,6 +23,19 @@
#include "zlog.h"
+static const char *requests_stages[] = {
+ [FPM_REQUEST_ACCEPTING] = "Idle",
+ [FPM_REQUEST_READING_HEADERS] = "Reading headers",
+ [FPM_REQUEST_INFO] = "Getting request informations",
+ [FPM_REQUEST_EXECUTING] = "Running",
+ [FPM_REQUEST_END] = "Ending",
+ [FPM_REQUEST_FINISHED] = "Finishing",
+};
+
+const char *fpm_request_get_stage_name(int stage) {
+ return requests_stages[stage];
+}
+
void fpm_request_accepting() /* {{{ */
{
struct fpm_scoreboard_proc_s *proc;
@@ -38,10 +51,6 @@ void fpm_request_accepting() /* {{{ */
proc->request_stage = FPM_REQUEST_ACCEPTING;
proc->tv = now;
- proc->request_uri[0] = '\0';
- proc->request_method[0] = '\0';
- proc->script_filename[0] = '\0';
- proc->content_length = 0;
fpm_scoreboard_proc_release(proc);
/* idle++, active-- */
@@ -78,6 +87,12 @@ void fpm_request_reading_headers() /* {{{ */
#ifdef HAVE_TIMES
proc->cpu_accepted = cpu;
#endif
+ proc->requests++;
+ proc->request_uri[0] = '\0';
+ proc->request_method[0] = '\0';
+ proc->script_filename[0] = '\0';
+ proc->query_string[0] = '\0';
+ proc->content_length = 0;
fpm_scoreboard_proc_release(proc);
/* idle--, active++, request++ */
@@ -176,9 +191,13 @@ void fpm_request_end(TSRMLS_D) /* {{{ */
}
proc->request_stage = FPM_REQUEST_FINISHED;
proc->tv = now;
+ timersub(&now, &proc->accepted, &proc->duration);
#ifdef HAVE_TIMES
- proc->cpu_finished = cpu;
timersub(&proc->tv, &proc->accepted, &proc->cpu_duration);
+ proc->last_request_cpu.tms_utime = cpu.tms_utime - proc->cpu_accepted.tms_utime;
+ proc->last_request_cpu.tms_stime = cpu.tms_stime - proc->cpu_accepted.tms_stime;
+ proc->last_request_cpu.tms_cutime = cpu.tms_cutime - proc->cpu_accepted.tms_cutime;
+ proc->last_request_cpu.tms_cstime = cpu.tms_cstime - proc->cpu_accepted.tms_cstime;
#endif
proc->memory = memory;
fpm_scoreboard_proc_release(proc);
@@ -17,6 +17,7 @@ struct timeval;
void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *tv, int terminate_timeout, int slowlog_timeout);
int fpm_request_is_idle(struct fpm_child_s *child);
+const char *fpm_request_get_stage_name(int stage);
enum fpm_request_stage_e {
FPM_REQUEST_ACCEPTING = 1,
@@ -17,12 +17,30 @@
static struct fpm_scoreboard_s *fpm_scoreboard = NULL;
static int fpm_scoreboard_i = -1;
+#ifdef HAVE_TIMES
+static float fpm_scoreboard_tick;
+#endif
+
int fpm_scoreboard_init_main() /* {{{ */
{
struct fpm_worker_pool_s *wp;
int i;
+#ifdef HAVE_TIMES
+#if (defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK))
+ fpm_scoreboard_tick = sysconf(_SC_CLK_TCK);
+#else /* _SC_CLK_TCK */
+#ifdef HZ
+ fpm_scoreboard_tick = HZ;
+#else /* HZ */
+ fpm_scoreboard_tick = 100;
+#endif /* HZ */
+#endif /* _SC_CLK_TCK */
+ zlog(ZLOG_DEBUG, "got clock tick '%.0f'", fpm_scoreboard_tick);
+#endif /* HAVE_TIMES */
+
+
for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
if (wp->config->pm_max_children < 1) {
zlog(ZLOG_ERROR, "[pool %s] Unable to create scoreboard SHM because max_client is not set", wp->config->name);
@@ -40,7 +58,11 @@ int fpm_scoreboard_init_main() /* {{{ */
}
wp->scoreboard->nprocs = wp->config->pm_max_children;
for (i=0; i<wp->scoreboard->nprocs; i++) {
- wp->scoreboard->procs[i] = NULL;
+ wp->scoreboard->procs[i] = fpm_shm_alloc(sizeof(struct fpm_scoreboard_proc_s));
+ if (!wp->scoreboard->procs[i]) {
+ return -1;
+ }
+ memset(wp->scoreboard->procs[i], 0, sizeof(struct fpm_scoreboard_proc_s));
}
wp->scoreboard->pm = wp->config->pm;
@@ -229,6 +251,7 @@ void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_ind
return;
}
proc->pid = pid;
+ proc->start_epoch = time(NULL);
}
/* }}} */
@@ -242,9 +265,8 @@ void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_ind
return;
}
- if (scoreboard->procs[child_index]) {
- fpm_shm_free(scoreboard->procs[child_index], sizeof(struct fpm_scoreboard_proc_s));
- scoreboard->procs[child_index] = NULL;
+ if (scoreboard->procs[child_index] && scoreboard->procs[child_index]->used > 0) {
+ memset(scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
}
/* set this slot as free to avoid search on next alloc */
@@ -262,15 +284,15 @@ int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_in
/* first try the slot which is supposed to be free */
if (scoreboard->free_proc >= 0 && scoreboard->free_proc < scoreboard->nprocs) {
- if (!scoreboard->procs[scoreboard->free_proc]) {
+ if (scoreboard->procs[scoreboard->free_proc] && !scoreboard->procs[scoreboard->free_proc]->used) {
i = scoreboard->free_proc;
}
}
if (i < 0) { /* the supposed free slot is not, let's search for a free slot */
zlog(ZLOG_DEBUG, "[pool %s] the proc->free_slot was not free. Let's search", scoreboard->pool);
for (i=0; i<scoreboard->nprocs; i++) {
- if (!scoreboard->procs[i]) { /* found */
+ if (scoreboard->procs[i] && !scoreboard->procs[i]->used) { /* found */
break;
}
}
@@ -282,10 +304,7 @@ int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_in
return -1;
}
- scoreboard->procs[i] = fpm_shm_alloc(sizeof(struct fpm_scoreboard_proc_s));
- if (!scoreboard->procs[i]) {
- return -1;
- }
+ scoreboard->procs[i]->used = 1;
*child_index = i;
/* supposed next slot is free */
@@ -299,3 +318,11 @@ int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_in
}
/* }}} */
+#ifdef HAVE_TIMES
+float fpm_scoreboard_get_tick() /* {{{ */
+{
+ return fpm_scoreboard_tick;
+}
+/* }}} */
+#endif
+
@@ -22,9 +22,13 @@ struct fpm_scoreboard_proc_s {
atomic_t lock;
char dummy[16];
};
+ int used;
+ time_t start_epoch;
pid_t pid;
+ unsigned long requests;
enum fpm_request_stage_e request_stage;
struct timeval accepted;
+ struct timeval duration;
time_t accepted_epoch;
struct timeval tv;
char request_uri[128];
@@ -35,8 +39,9 @@ struct fpm_scoreboard_proc_s {
char auth_user[32];
#ifdef HAVE_TIMES
struct tms cpu_accepted;
- struct tms cpu_finished;
struct timeval cpu_duration;
+ struct tms last_request_cpu;
+ struct timeval last_request_cpu_duration;
#endif
size_t memory;
};
@@ -81,4 +86,8 @@ void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_ind
void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index);
int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index);
+#ifdef HAVE_TIMES
+float fpm_scoreboard_get_tick();
+#endif
+
#endif
Oops, something went wrong.

0 comments on commit 1e0cb5f

Please sign in to comment.