xref: /PHP-7.4/sapi/fpm/fpm/fpm_status.c (revision cb2021e5)
1 	/* (c) 2009 Jerome Loyet */
2 
3 #include "php.h"
4 #include "zend_long.h"
5 #include "SAPI.h"
6 #include <stdio.h>
7 
8 #include "fpm_config.h"
9 #include "fpm_scoreboard.h"
10 #include "fpm_status.h"
11 #include "fpm_clock.h"
12 #include "zlog.h"
13 #include "fpm_atomic.h"
14 #include "fpm_conf.h"
15 #include "fpm_php.h"
16 #include <ext/standard/html.h>
17 
18 static char *fpm_status_uri = NULL;
19 static char *fpm_status_ping_uri = NULL;
20 static char *fpm_status_ping_response = NULL;
21 
22 
fpm_status_init_child(struct fpm_worker_pool_s * wp)23 int fpm_status_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
24 {
25 	if (!wp || !wp->config) {
26 		zlog(ZLOG_ERROR, "unable to init fpm_status because conf structure is NULL");
27 		return -1;
28 	}
29 
30 	if (wp->config->pm_status_path) {
31 		fpm_status_uri = strdup(wp->config->pm_status_path);
32 	}
33 
34 	if (wp->config->ping_path) {
35 		if (!wp->config->ping_response) {
36 			zlog(ZLOG_ERROR, "[pool %s] ping is set (%s) but ping.response is not set.", wp->config->name, wp->config->ping_path);
37 			return -1;
38 		}
39 		fpm_status_ping_uri = strdup(wp->config->ping_path);
40 		fpm_status_ping_response = strdup(wp->config->ping_response);
41 	}
42 
43 	return 0;
44 }
45 /* }}} */
46 
fpm_status_export_to_zval(zval * status)47 int fpm_status_export_to_zval(zval *status)
48 {
49 	struct fpm_scoreboard_s scoreboard, *scoreboard_p;
50 	zval fpm_proc_stats, fpm_proc_stat;
51 	time_t now_epoch;
52 	struct timeval duration, now;
53 	double cpu;
54 	int i;
55 
56 
57 	scoreboard_p = fpm_scoreboard_acquire(NULL, 1);
58 	if (!scoreboard_p) {
59 		zlog(ZLOG_NOTICE, "[pool %s] status: scoreboard already in use.", scoreboard_p->pool);
60 		return -1;
61 	}
62 
63 	/* copy the scoreboard not to bother other processes */
64 	scoreboard = *scoreboard_p;
65 	struct fpm_scoreboard_proc_s procs[scoreboard.nprocs];
66 
67 	struct fpm_scoreboard_proc_s *proc_p;
68 	for(i=0; i<scoreboard.nprocs; i++) {
69 		proc_p = fpm_scoreboard_proc_acquire(scoreboard_p, i, 1);
70 		if (!proc_p){
71 			procs[i].used=-1;
72 			continue;
73 		}
74 		procs[i] = *proc_p;
75 		fpm_scoreboard_proc_release(proc_p);
76 	}
77 	fpm_scoreboard_release(scoreboard_p);
78 
79 	now_epoch = time(NULL);
80 	fpm_clock_get(&now);
81 
82 	array_init(status);
83 	add_assoc_string(status, "pool", scoreboard.pool);
84 	add_assoc_string(status, "process-manager", PM2STR(scoreboard.pm));
85 	add_assoc_long(status, "start-time", scoreboard.start_epoch);
86 	add_assoc_long(status, "start-since", now_epoch - scoreboard.start_epoch);
87 	add_assoc_long(status, "accepted-conn", scoreboard.requests);
88 #ifdef HAVE_FPM_LQ
89 	add_assoc_long(status, "listen-queue", scoreboard.lq);
90 	add_assoc_long(status, "max-listen-queue", scoreboard.lq_max);
91 	add_assoc_long(status, "listen-queue-len", scoreboard.lq_len);
92 #endif
93 	add_assoc_long(status, "idle-processes", scoreboard.idle);
94 	add_assoc_long(status, "active-processes", scoreboard.active);
95 	add_assoc_long(status, "total-processes", scoreboard.idle + scoreboard.active);
96 	add_assoc_long(status, "max-active-processes", scoreboard.active_max);
97 	add_assoc_long(status, "max-children-reached", scoreboard.max_children_reached);
98 	add_assoc_long(status, "slow-requests", scoreboard.slow_rq);
99 
100 	array_init(&fpm_proc_stats);
101 	for(i=0; i<scoreboard.nprocs; i++) {
102 		if (!procs[i].used) {
103 			continue;
104 		}
105 		proc_p = &procs[i];
106 #ifdef HAVE_FPM_LQ
107 		/* prevent NaN */
108 		if (procs[i].cpu_duration.tv_sec == 0 && procs[i].cpu_duration.tv_usec == 0) {
109 			cpu = 0.;
110 		} else {
111 			cpu = (procs[i].last_request_cpu.tms_utime + procs[i].last_request_cpu.tms_stime + procs[i].last_request_cpu.tms_cutime + procs[i].last_request_cpu.tms_cstime) / fpm_scoreboard_get_tick() / (procs[i].cpu_duration.tv_sec + procs[i].cpu_duration.tv_usec / 1000000.) * 100.;
112 		}
113 #endif
114 
115 		array_init(&fpm_proc_stat);
116 		add_assoc_long(&fpm_proc_stat, "pid", procs[i].pid);
117 		add_assoc_string(&fpm_proc_stat, "state", fpm_request_get_stage_name(procs[i].request_stage));
118 		add_assoc_long(&fpm_proc_stat, "start-time", procs[i].start_epoch);
119 		add_assoc_long(&fpm_proc_stat, "start-since", now_epoch - procs[i].start_epoch);
120 		add_assoc_long(&fpm_proc_stat, "requests", procs[i].requests);
121 		if (procs[i].request_stage == FPM_REQUEST_ACCEPTING) {
122 			duration = procs[i].duration;
123 		} else {
124 			timersub(&now, &procs[i].accepted, &duration);
125 		}
126 		add_assoc_long(&fpm_proc_stat, "request-duration", duration.tv_sec * 1000000UL + duration.tv_usec);
127 		add_assoc_string(&fpm_proc_stat, "request-method", procs[i].request_method[0] != '\0' ? procs[i].request_method : "-");
128 		add_assoc_string(&fpm_proc_stat, "request-uri", procs[i].request_uri);
129 		add_assoc_string(&fpm_proc_stat, "query-string", procs[i].query_string);
130 		add_assoc_long(&fpm_proc_stat, "request-length", procs[i].content_length);
131 		add_assoc_string(&fpm_proc_stat, "user", procs[i].auth_user[0] != '\0' ? procs[i].auth_user : "-");
132 		add_assoc_string(&fpm_proc_stat, "script", procs[i].script_filename[0] != '\0' ? procs[i].script_filename : "-");
133 #ifdef HAVE_FPM_LQ
134 		add_assoc_double(&fpm_proc_stat, "last-request-cpu", procs[i].request_stage == FPM_REQUEST_ACCEPTING ? cpu : 0.);
135 #endif
136 		add_assoc_long(&fpm_proc_stat, "last-request-memory", procs[i].request_stage == FPM_REQUEST_ACCEPTING ? procs[i].memory : 0);
137 		add_next_index_zval(&fpm_proc_stats, &fpm_proc_stat);
138 	}
139 	add_assoc_zval(status, "procs", &fpm_proc_stats);
140 	return 0;
141 }
142 /* }}} */
143 
fpm_status_handle_request(void)144 int fpm_status_handle_request(void) /* {{{ */
145 {
146 	struct fpm_scoreboard_s scoreboard, *scoreboard_p;
147 	struct fpm_scoreboard_proc_s proc;
148 	char *buffer, *time_format, time_buffer[64];
149 	time_t now_epoch;
150 	int full, encode;
151 	char *short_syntax, *short_post;
152 	char *full_pre, *full_syntax, *full_post, *full_separator;
153 	zend_string *_GET_str;
154 
155 	if (!SG(request_info).request_uri) {
156 		return 0;
157 	}
158 
159 	/* PING */
160 	if (fpm_status_ping_uri && fpm_status_ping_response && !strcmp(fpm_status_ping_uri, SG(request_info).request_uri)) {
161 		fpm_request_executing();
162 		sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1);
163 		sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1);
164 		sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1);
165 		SG(sapi_headers).http_response_code = 200;
166 
167 		/* handle HEAD */
168 		if (SG(request_info).headers_only) {
169 			return 1;
170 		}
171 
172 		PUTS(fpm_status_ping_response);
173 		return 1;
174 	}
175 
176 	/* STATUS */
177 	if (fpm_status_uri && !strcmp(fpm_status_uri, SG(request_info).request_uri)) {
178 		fpm_request_executing();
179 
180 		scoreboard_p = fpm_scoreboard_get();
181 		if (!scoreboard_p) {
182 			zlog(ZLOG_ERROR, "status: unable to find or access status shared memory");
183 			SG(sapi_headers).http_response_code = 500;
184 			sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1);
185 			sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1);
186 			sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1);
187 			PUTS("Internal error. Please review log file for errors.");
188 			return 1;
189 		}
190 
191 		if (!fpm_spinlock(&scoreboard_p->lock, 1)) {
192 			zlog(ZLOG_NOTICE, "[pool %s] status: scoreboard already in used.", scoreboard_p->pool);
193 			SG(sapi_headers).http_response_code = 503;
194 			sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1);
195 			sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1);
196 			sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1);
197 			PUTS("Server busy. Please try again later.");
198 			return 1;
199 		}
200 		/* copy the scoreboard not to bother other processes */
201 		scoreboard = *scoreboard_p;
202 		fpm_unlock(scoreboard_p->lock);
203 
204 		if (scoreboard.idle < 0 || scoreboard.active < 0) {
205 			zlog(ZLOG_ERROR, "[pool %s] invalid status values", scoreboard.pool);
206 			SG(sapi_headers).http_response_code = 500;
207 			sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1);
208 			sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1);
209 			sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1);
210 			PUTS("Internal error. Please review log file for errors.");
211 			return 1;
212 		}
213 
214 		/* send common headers */
215 		sapi_add_header_ex(ZEND_STRL("Expires: Thu, 01 Jan 1970 00:00:00 GMT"), 1, 1);
216 		sapi_add_header_ex(ZEND_STRL("Cache-Control: no-cache, no-store, must-revalidate, max-age=0"), 1, 1);
217 		SG(sapi_headers).http_response_code = 200;
218 
219 		/* handle HEAD */
220 		if (SG(request_info).headers_only) {
221 			return 1;
222 		}
223 
224 		/* full status ? */
225 		_GET_str = zend_string_init("_GET", sizeof("_GET")-1, 0);
226 		full = (fpm_php_get_string_from_table(_GET_str, "full") != NULL);
227 		short_syntax = short_post = NULL;
228 		full_separator = full_pre = full_syntax = full_post = NULL;
229 		encode = 0;
230 
231 		/* HTML */
232 		if (fpm_php_get_string_from_table(_GET_str, "html")) {
233 			sapi_add_header_ex(ZEND_STRL("Content-Type: text/html"), 1, 1);
234 			time_format = "%d/%b/%Y:%H:%M:%S %z";
235 			encode = 1;
236 
237 			short_syntax =
238 				"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
239 				"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
240 				"<head><title>PHP-FPM Status Page</title></head>\n"
241 				"<body>\n"
242 				"<table>\n"
243 					"<tr><th>pool</th><td>%s</td></tr>\n"
244 					"<tr><th>process manager</th><td>%s</td></tr>\n"
245 					"<tr><th>start time</th><td>%s</td></tr>\n"
246 					"<tr><th>start since</th><td>%lu</td></tr>\n"
247 					"<tr><th>accepted conn</th><td>%lu</td></tr>\n"
248 #ifdef HAVE_FPM_LQ
249 					"<tr><th>listen queue</th><td>%d</td></tr>\n"
250 					"<tr><th>max listen queue</th><td>%d</td></tr>\n"
251 					"<tr><th>listen queue len</th><td>%u</td></tr>\n"
252 #endif
253 					"<tr><th>idle processes</th><td>%d</td></tr>\n"
254 					"<tr><th>active processes</th><td>%d</td></tr>\n"
255 					"<tr><th>total processes</th><td>%d</td></tr>\n"
256 					"<tr><th>max active processes</th><td>%d</td></tr>\n"
257 					"<tr><th>max children reached</th><td>%u</td></tr>\n"
258 					"<tr><th>slow requests</th><td>%lu</td></tr>\n"
259 				"</table>\n";
260 
261 			if (!full) {
262 				short_post = "</body></html>";
263 			} else {
264 				full_pre =
265 					"<table border=\"1\">\n"
266 					"<tr>"
267 						"<th>pid</th>"
268 						"<th>state</th>"
269 						"<th>start time</th>"
270 						"<th>start since</th>"
271 						"<th>requests</th>"
272 						"<th>request duration</th>"
273 						"<th>request method</th>"
274 						"<th>request uri</th>"
275 						"<th>content length</th>"
276 						"<th>user</th>"
277 						"<th>script</th>"
278 #ifdef HAVE_FPM_LQ
279 						"<th>last request cpu</th>"
280 #endif
281 						"<th>last request memory</th>"
282 					"</tr>\n";
283 
284 				full_syntax =
285 					"<tr>"
286 						"<td>%d</td>"
287 						"<td>%s</td>"
288 						"<td>%s</td>"
289 						"<td>%lu</td>"
290 						"<td>%lu</td>"
291 						"<td>%lu</td>"
292 						"<td>%s</td>"
293 						"<td>%s%s%s</td>"
294 						"<td>%zu</td>"
295 						"<td>%s</td>"
296 						"<td>%s</td>"
297 #ifdef HAVE_FPM_LQ
298 						"<td>%.2f</td>"
299 #endif
300 						"<td>%zu</td>"
301 					"</tr>\n";
302 
303 				full_post = "</table></body></html>";
304 			}
305 
306 		/* XML */
307 		} else if (fpm_php_get_string_from_table(_GET_str, "xml")) {
308 			sapi_add_header_ex(ZEND_STRL("Content-Type: text/xml"), 1, 1);
309 			time_format = "%s";
310 			encode = 1;
311 
312 			short_syntax =
313 				"<?xml version=\"1.0\" ?>\n"
314 				"<status>\n"
315 				"<pool>%s</pool>\n"
316 				"<process-manager>%s</process-manager>\n"
317 				"<start-time>%s</start-time>\n"
318 				"<start-since>%lu</start-since>\n"
319 				"<accepted-conn>%lu</accepted-conn>\n"
320 #ifdef HAVE_FPM_LQ
321 				"<listen-queue>%d</listen-queue>\n"
322 				"<max-listen-queue>%d</max-listen-queue>\n"
323 				"<listen-queue-len>%u</listen-queue-len>\n"
324 #endif
325 				"<idle-processes>%d</idle-processes>\n"
326 				"<active-processes>%d</active-processes>\n"
327 				"<total-processes>%d</total-processes>\n"
328 				"<max-active-processes>%d</max-active-processes>\n"
329 				"<max-children-reached>%u</max-children-reached>\n"
330 				"<slow-requests>%lu</slow-requests>\n";
331 
332 				if (!full) {
333 					short_post = "</status>";
334 				} else {
335 					full_pre = "<processes>\n";
336 					full_syntax =
337 						"<process>"
338 							"<pid>%d</pid>"
339 							"<state>%s</state>"
340 							"<start-time>%s</start-time>"
341 							"<start-since>%lu</start-since>"
342 							"<requests>%lu</requests>"
343 							"<request-duration>%lu</request-duration>"
344 							"<request-method>%s</request-method>"
345 							"<request-uri>%s%s%s</request-uri>"
346 							"<content-length>%zu</content-length>"
347 							"<user>%s</user>"
348 							"<script>%s</script>"
349 #ifdef HAVE_FPM_LQ
350 							"<last-request-cpu>%.2f</last-request-cpu>"
351 #endif
352 							"<last-request-memory>%zu</last-request-memory>"
353 						"</process>\n"
354 					;
355 					full_post = "</processes>\n</status>";
356 				}
357 
358 			/* JSON */
359 		} else if (fpm_php_get_string_from_table(_GET_str, "json")) {
360 			sapi_add_header_ex(ZEND_STRL("Content-Type: application/json"), 1, 1);
361 			time_format = "%s";
362 
363 			short_syntax =
364 				"{"
365 				"\"pool\":\"%s\","
366 				"\"process manager\":\"%s\","
367 				"\"start time\":%s,"
368 				"\"start since\":%lu,"
369 				"\"accepted conn\":%lu,"
370 #ifdef HAVE_FPM_LQ
371 				"\"listen queue\":%d,"
372 				"\"max listen queue\":%d,"
373 				"\"listen queue len\":%u,"
374 #endif
375 				"\"idle processes\":%d,"
376 				"\"active processes\":%d,"
377 				"\"total processes\":%d,"
378 				"\"max active processes\":%d,"
379 				"\"max children reached\":%u,"
380 				"\"slow requests\":%lu";
381 
382 			if (!full) {
383 				short_post = "}";
384 			} else {
385 				full_separator = ",";
386 				full_pre = ", \"processes\":[";
387 
388 				full_syntax = "{"
389 					"\"pid\":%d,"
390 					"\"state\":\"%s\","
391 					"\"start time\":%s,"
392 					"\"start since\":%lu,"
393 					"\"requests\":%lu,"
394 					"\"request duration\":%lu,"
395 					"\"request method\":\"%s\","
396 					"\"request uri\":\"%s%s%s\","
397 					"\"content length\":%zu,"
398 					"\"user\":\"%s\","
399 					"\"script\":\"%s\","
400 #ifdef HAVE_FPM_LQ
401 					"\"last request cpu\":%.2f,"
402 #endif
403 					"\"last request memory\":%zu"
404 					"}";
405 
406 				full_post = "]}";
407 			}
408 
409 		/* TEXT */
410 		} else {
411 			sapi_add_header_ex(ZEND_STRL("Content-Type: text/plain"), 1, 1);
412 			time_format = "%d/%b/%Y:%H:%M:%S %z";
413 
414 			short_syntax =
415 				"pool:                 %s\n"
416 				"process manager:      %s\n"
417 				"start time:           %s\n"
418 				"start since:          %lu\n"
419 				"accepted conn:        %lu\n"
420 #ifdef HAVE_FPM_LQ
421 				"listen queue:         %d\n"
422 				"max listen queue:     %d\n"
423 				"listen queue len:     %u\n"
424 #endif
425 				"idle processes:       %d\n"
426 				"active processes:     %d\n"
427 				"total processes:      %d\n"
428 				"max active processes: %d\n"
429 				"max children reached: %u\n"
430 				"slow requests:        %lu\n";
431 
432 				if (full) {
433 					full_syntax =
434 						"\n"
435 						"************************\n"
436 						"pid:                  %d\n"
437 						"state:                %s\n"
438 						"start time:           %s\n"
439 						"start since:          %lu\n"
440 						"requests:             %lu\n"
441 						"request duration:     %lu\n"
442 						"request method:       %s\n"
443 						"request URI:          %s%s%s\n"
444 						"content length:       %zu\n"
445 						"user:                 %s\n"
446 						"script:               %s\n"
447 #ifdef HAVE_FPM_LQ
448 						"last request cpu:     %.2f\n"
449 #endif
450 						"last request memory:  %zu\n";
451 				}
452 		}
453 
454 		strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&scoreboard.start_epoch));
455 		now_epoch = time(NULL);
456 		spprintf(&buffer, 0, short_syntax,
457 				scoreboard.pool,
458 				PM2STR(scoreboard.pm),
459 				time_buffer,
460 				(unsigned long) (now_epoch - scoreboard.start_epoch),
461 				scoreboard.requests,
462 #ifdef HAVE_FPM_LQ
463 				scoreboard.lq,
464 				scoreboard.lq_max,
465 				scoreboard.lq_len,
466 #endif
467 				scoreboard.idle,
468 				scoreboard.active,
469 				scoreboard.idle + scoreboard.active,
470 				scoreboard.active_max,
471 				scoreboard.max_children_reached,
472 				scoreboard.slow_rq);
473 
474 		PUTS(buffer);
475 		efree(buffer);
476 		zend_string_release_ex(_GET_str, 0);
477 
478 		if (short_post) {
479 			PUTS(short_post);
480 		}
481 
482 		/* no need to test the var 'full' */
483 		if (full_syntax) {
484 			unsigned int i;
485 			int first;
486 			zend_string *tmp_query_string;
487 			char *query_string;
488 			struct timeval duration, now;
489 #ifdef HAVE_FPM_LQ
490 			float cpu;
491 #endif
492 
493 			fpm_clock_get(&now);
494 
495 			if (full_pre) {
496 				PUTS(full_pre);
497 			}
498 
499 			first = 1;
500 			for (i=0; i<scoreboard_p->nprocs; i++) {
501 				if (!scoreboard_p->procs[i].used) {
502 					continue;
503 				}
504 				proc = scoreboard_p->procs[i];
505 
506 				if (first) {
507 					first = 0;
508 				} else {
509 					if (full_separator) {
510 						PUTS(full_separator);
511 					}
512 				}
513 
514 				query_string = NULL;
515 				tmp_query_string = NULL;
516 				if (proc.query_string[0] != '\0') {
517 					if (!encode) {
518 						query_string = proc.query_string;
519 					} else {
520 						tmp_query_string = php_escape_html_entities_ex((unsigned char *)proc.query_string, strlen(proc.query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, 1);
521 						query_string = ZSTR_VAL(tmp_query_string);
522 					}
523 				}
524 
525 #ifdef HAVE_FPM_LQ
526 				/* prevent NaN */
527 				if (proc.cpu_duration.tv_sec == 0 && proc.cpu_duration.tv_usec == 0) {
528 					cpu = 0.;
529 				} else {
530 					cpu = (proc.last_request_cpu.tms_utime + proc.last_request_cpu.tms_stime + proc.last_request_cpu.tms_cutime + proc.last_request_cpu.tms_cstime) / fpm_scoreboard_get_tick() / (proc.cpu_duration.tv_sec + proc.cpu_duration.tv_usec / 1000000.) * 100.;
531 				}
532 #endif
533 
534 				if (proc.request_stage == FPM_REQUEST_ACCEPTING) {
535 					duration = proc.duration;
536 				} else {
537 					timersub(&now, &proc.accepted, &duration);
538 				}
539 				strftime(time_buffer, sizeof(time_buffer) - 1, time_format, localtime(&proc.start_epoch));
540 				spprintf(&buffer, 0, full_syntax,
541 					(int) proc.pid,
542 					fpm_request_get_stage_name(proc.request_stage),
543 					time_buffer,
544 					(unsigned long) (now_epoch - proc.start_epoch),
545 					proc.requests,
546 					duration.tv_sec * 1000000UL + duration.tv_usec,
547 					proc.request_method[0] != '\0' ? proc.request_method : "-",
548 					proc.request_uri[0] != '\0' ? proc.request_uri : "-",
549 					query_string ? "?" : "",
550 					query_string ? query_string : "",
551 					proc.content_length,
552 					proc.auth_user[0] != '\0' ? proc.auth_user : "-",
553 					proc.script_filename[0] != '\0' ? proc.script_filename : "-",
554 #ifdef HAVE_FPM_LQ
555 					proc.request_stage == FPM_REQUEST_ACCEPTING ? cpu : 0.,
556 #endif
557 					proc.request_stage == FPM_REQUEST_ACCEPTING ? proc.memory : 0);
558 				PUTS(buffer);
559 				efree(buffer);
560 
561 				if (tmp_query_string) {
562 					zend_string_free(tmp_query_string);
563 				}
564 			}
565 
566 			if (full_post) {
567 				PUTS(full_post);
568 			}
569 		}
570 
571 		return 1;
572 	}
573 
574 	return 0;
575 }
576 /* }}} */
577