fat                                      Tue, 05 Jul 2011 19:22:45 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=312950

Log:
- FR #52052: Added partial syslog support (on error_log only)

Bug: https://bugs.php.net/52052 (Assigned) add syslog support to FPM
      
Changed paths:
    U   php/php-src/branches/PHP_5_4/NEWS
    U   php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_conf.c
    U   php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_conf.h
    U   php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_stdio.c
    U   php/php-src/branches/PHP_5_4/sapi/fpm/fpm/zlog.c
    U   php/php-src/branches/PHP_5_4/sapi/fpm/fpm/zlog.h
    U   php/php-src/branches/PHP_5_4/sapi/fpm/php-fpm.conf.in
    U   php/php-src/trunk/sapi/fpm/fpm/fpm_conf.c
    U   php/php-src/trunk/sapi/fpm/fpm/fpm_conf.h
    U   php/php-src/trunk/sapi/fpm/fpm/fpm_stdio.c
    U   php/php-src/trunk/sapi/fpm/fpm/zlog.c
    U   php/php-src/trunk/sapi/fpm/fpm/zlog.h
    U   php/php-src/trunk/sapi/fpm/php-fpm.conf.in

Modified: php/php-src/branches/PHP_5_4/NEWS
===================================================================
--- php/php-src/branches/PHP_5_4/NEWS	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/branches/PHP_5_4/NEWS	2011-07-05 19:22:45 UTC (rev 312950)
@@ -132,6 +132,9 @@
     getallheaders(), apache_request_headers() and apache_response_headers()
   . Improved performance of FastCGI request parsing.

+- Improved PHP-FPM SAPI:
+  . Added partial syslog support (on error_log only). FR #52052. (fat)
+
 - Improved core functions:
   . number_format() no longer truncates multibyte decimal points and thousand
     separators to the first byte. FR #53457. (Adam)

Modified: php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_conf.c
===================================================================
--- php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_conf.c	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_conf.c	2011-07-05 19:22:45 UTC (rev 312950)
@@ -31,6 +31,7 @@
 #include "zend_ini_scanner.h"
 #include "zend_globals.h"
 #include "zend_stream.h"
+#include "php_syslog.h"

 #include "fpm.h"
 #include "fpm_conf.h"
@@ -58,8 +59,16 @@
 static char *fpm_conf_set_log_level(zval *value, void **config, intptr_t offset);
 static char *fpm_conf_set_rlimit_core(zval *value, void **config, intptr_t offset);
 static char *fpm_conf_set_pm(zval *value, void **config, intptr_t offset);
+#ifdef HAVE_SYSLOG_H
+static char *fpm_conf_set_syslog_facility(zval *value, void **config, intptr_t offset);
+#endif

-struct fpm_global_config_s fpm_global_config = { .daemonize = 1 };
+struct fpm_global_config_s fpm_global_config = {
+	.daemonize = 1,
+#ifdef HAVE_SYSLOG_H
+	.syslog_facility = -1
+#endif
+};
 static struct fpm_worker_pool_s *current_wp = NULL;
 static int ini_recursion = 0;
 static char *ini_filename = NULL;
@@ -67,15 +76,19 @@
 static char *ini_include = NULL;

 static struct ini_value_parser_s ini_fpm_global_options[] = {
-	{ "emergency_restart_threshold", &fpm_conf_set_integer,     GO(emergency_restart_threshold) },
-	{ "emergency_restart_interval",  &fpm_conf_set_time,        GO(emergency_restart_interval) },
-	{ "process_control_timeout",     &fpm_conf_set_time,        GO(process_control_timeout) },
-	{ "daemonize",                   &fpm_conf_set_boolean,     GO(daemonize) },
-	{ "pid",                         &fpm_conf_set_string,      GO(pid_file) },
-	{ "error_log",                   &fpm_conf_set_string,      GO(error_log) },
-	{ "log_level",                   &fpm_conf_set_log_level,   0 },
-	{ "rlimit_files",                &fpm_conf_set_integer,     GO(rlimit_files) },
-	{ "rlimit_core",                 &fpm_conf_set_rlimit_core, GO(rlimit_core) },
+	{ "emergency_restart_threshold", &fpm_conf_set_integer,         GO(emergency_restart_threshold) },
+	{ "emergency_restart_interval",  &fpm_conf_set_time,            GO(emergency_restart_interval) },
+	{ "process_control_timeout",     &fpm_conf_set_time,            GO(process_control_timeout) },
+	{ "daemonize",                   &fpm_conf_set_boolean,         GO(daemonize) },
+	{ "pid",                         &fpm_conf_set_string,          GO(pid_file) },
+	{ "error_log",                   &fpm_conf_set_string,          GO(error_log) },
+	{ "log_level",                   &fpm_conf_set_log_level,       GO(log_level) },
+#ifdef HAVE_SYSLOG_H
+	{ "syslog.ident",                &fpm_conf_set_string,          GO(syslog_ident) },
+	{ "syslog.facility",             &fpm_conf_set_syslog_facility, GO(syslog_facility) },
+#endif
+	{ "rlimit_files",                &fpm_conf_set_integer,         GO(rlimit_files) },
+	{ "rlimit_core",                 &fpm_conf_set_rlimit_core,     GO(rlimit_core) },
 	{ 0, 0, 0 }
 };

@@ -252,25 +265,178 @@
 static char *fpm_conf_set_log_level(zval *value, void **config, intptr_t offset) /* {{{ */
 {
 	char *val = Z_STRVAL_P(value);
+	int log_level;

 	if (!strcasecmp(val, "debug")) {
-		fpm_globals.log_level = ZLOG_DEBUG;
+		log_level = ZLOG_DEBUG;
 	} else if (!strcasecmp(val, "notice")) {
-		fpm_globals.log_level = ZLOG_NOTICE;
+		log_level = ZLOG_NOTICE;
 	} else if (!strcasecmp(val, "warning") || !strcasecmp(val, "warn")) {
-		fpm_globals.log_level = ZLOG_WARNING;
+		log_level = ZLOG_WARNING;
 	} else if (!strcasecmp(val, "error")) {
-		fpm_globals.log_level = ZLOG_ERROR;
+		log_level = ZLOG_ERROR;
 	} else if (!strcasecmp(val, "alert")) {
-		fpm_globals.log_level = ZLOG_ALERT;
+		log_level = ZLOG_ALERT;
 	} else {
 		return "invalid value for 'log_level'";
 	}

+	* (int *) ((char *) *config + offset) = log_level;
 	return NULL;
 }
 /* }}} */

+#ifdef HAVE_SYSLOG_H
+static char *fpm_conf_set_syslog_facility(zval *value, void **config, intptr_t offset) /* {{{ */
+{
+	char *val = Z_STRVAL_P(value);
+	int *conf = (int *) ((char *) *config + offset);
+
+#ifdef LOG_AUTH
+	if (!strcasecmp(val, "AUTH")) {
+		*conf = LOG_AUTH;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_AUTHPRIV
+	if (!strcasecmp(val, "AUTHPRIV")) {
+		*conf = LOG_AUTHPRIV;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_CRON
+	if (!strcasecmp(val, "CRON")) {
+		*conf = LOG_CRON;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_DAEMON
+	if (!strcasecmp(val, "DAEMON")) {
+		*conf = LOG_DAEMON;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_FTP
+	if (!strcasecmp(val, "FTP")) {
+		*conf = LOG_FTP;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_KERN
+	if (!strcasecmp(val, "KERN")) {
+		*conf = LOG_KERN;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LPR
+	if (!strcasecmp(val, "LPR")) {
+		*conf = LOG_LPR;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_MAIL
+	if (!strcasecmp(val, "MAIL")) {
+		*conf = LOG_MAIL;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_NEWS
+	if (!strcasecmp(val, "NEWS")) {
+		*conf = LOG_NEWS;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_SYSLOG
+	if (!strcasecmp(val, "SYSLOG")) {
+		*conf = LOG_SYSLOG;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_USER
+	if (!strcasecmp(val, "USER")) {
+		*conf = LOG_USER;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_UUCP
+	if (!strcasecmp(val, "UUCP")) {
+		*conf = LOG_UUCP;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL0
+	if (!strcasecmp(val, "LOCAL0")) {
+		*conf = LOG_LOCAL0;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL1
+	if (!strcasecmp(val, "LOCAL1")) {
+		*conf = LOG_LOCAL1;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL2
+	if (!strcasecmp(val, "LOCAL2")) {
+		*conf = LOG_LOCAL2;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL3
+	if (!strcasecmp(val, "LOCAL3")) {
+		*conf = LOG_LOCAL3;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL4
+	if (!strcasecmp(val, "LOCAL4")) {
+		*conf = LOG_LOCAL4;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL5
+	if (!strcasecmp(val, "LOCAL5")) {
+		*conf = LOG_LOCAL5;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL6
+	if (!strcasecmp(val, "LOCAL6")) {
+		*conf = LOG_LOCAL6;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL7
+	if (!strcasecmp(val, "LOCAL7")) {
+		*conf = LOG_LOCAL7;
+		return NULL;
+	}
+#endif
+
+	return "invalid value";
+}
+/* }}} */
+#endif
+
 static char *fpm_conf_set_rlimit_core(zval *value, void **config, intptr_t offset) /* {{{ */
 {
 	char *val = Z_STRVAL_P(value);
@@ -794,12 +960,27 @@
 		fpm_evaluate_full_path(&fpm_global_config.pid_file, NULL, PHP_LOCALSTATEDIR, 0);
 	}

+	fpm_globals.log_level = fpm_global_config.log_level;
+
 	if (!fpm_global_config.error_log) {
 		fpm_global_config.error_log = strdup("log/php-fpm.log");
 	}

-	fpm_evaluate_full_path(&fpm_global_config.error_log, NULL, PHP_LOCALSTATEDIR, 0);
+#ifdef HAVE_SYSLOG_H
+	if (!fpm_global_config.syslog_ident) {
+		fpm_global_config.syslog_ident = strdup("php-fpm");
+	}

+	if (fpm_global_config.syslog_facility < 0) {
+		fpm_global_config.syslog_facility = LOG_DAEMON;
+	}
+
+	if (strcasecmp(fpm_global_config.error_log, "syslog") != 0)
+#endif
+	{
+		fpm_evaluate_full_path(&fpm_global_config.error_log, NULL, PHP_LOCALSTATEDIR, 0);
+	}
+
 	if (0 > fpm_stdio_open_error_log(0)) {
 		return -1;
 	}
@@ -832,6 +1013,10 @@
 	free(fpm_global_config.error_log);
 	fpm_global_config.pid_file = 0;
 	fpm_global_config.error_log = 0;
+#ifdef HAVE_SYSLOG_H
+	free(fpm_global_config.syslog_ident);
+	fpm_global_config.syslog_ident = 0;
+#endif
 	free(fpm_globals.config);
 }
 /* }}} */
@@ -1152,6 +1337,10 @@
 	zlog(ZLOG_NOTICE, "\tdaemonize = %s",                   BOOL2STR(fpm_global_config.daemonize));
 	zlog(ZLOG_NOTICE, "\terror_log = %s",                   STR2STR(fpm_global_config.error_log));
 	zlog(ZLOG_NOTICE, "\tlog_level = %s",                   zlog_get_level_name(fpm_globals.log_level));
+#ifdef HAVE_SYSLOG_H
+	zlog(ZLOG_NOTICE, "\tsyslog.ident = %s",                STR2STR(fpm_global_config.syslog_ident));
+	zlog(ZLOG_NOTICE, "\tsyslog.facility = %d",             fpm_global_config.syslog_facility); /* FIXME: convert to string */
+#endif
 	zlog(ZLOG_NOTICE, "\tprocess_control_timeout = %ds",    fpm_global_config.process_control_timeout);
 	zlog(ZLOG_NOTICE, "\temergency_restart_interval = %ds", fpm_global_config.emergency_restart_interval);
 	zlog(ZLOG_NOTICE, "\temergency_restart_threshold = %d", fpm_global_config.emergency_restart_threshold);

Modified: php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_conf.h
===================================================================
--- php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_conf.h	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_conf.h	2011-07-05 19:22:45 UTC (rev 312950)
@@ -25,6 +25,11 @@
 	int daemonize;
 	char *pid_file;
 	char *error_log;
+	int log_level;
+#ifdef HAVE_SYSLOG_H
+	char *syslog_ident;
+	int syslog_facility;
+#endif
 	int rlimit_files;
 	int rlimit_core;
 };

Modified: php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_stdio.c
===================================================================
--- php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_stdio.c	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/branches/PHP_5_4/sapi/fpm/fpm/fpm_stdio.c	2011-07-05 19:22:45 UTC (rev 312950)
@@ -11,6 +11,8 @@
 #include <unistd.h>
 #include <errno.h>

+#include "php_syslog.h"
+
 #include "fpm.h"
 #include "fpm_children.h"
 #include "fpm_events.h"
@@ -42,8 +44,10 @@
 int fpm_stdio_init_final() /* {{{ */
 {
 	if (fpm_global_config.daemonize) {
-		if (fpm_globals.error_log_fd != STDERR_FILENO) {
-			/* there might be messages to stderr from libevent, we need to log them all */
+		/* prevent duping if logging to syslog */
+		if (fpm_globals.error_log_fd > 0 && fpm_globals.error_log_fd != STDERR_FILENO) {
+
+			/* there might be messages to stderr from other parts of the code, we need to log them all */
 			if (0 > dup2(fpm_globals.error_log_fd, STDERR_FILENO)) {
 				zlog(ZLOG_SYSERROR, "dup2() failed");
 				return -1;
@@ -57,7 +61,14 @@

 int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
 {
-	close(fpm_globals.error_log_fd);
+#ifdef HAVE_SYSLOG_H
+	if (fpm_globals.error_log_fd == ZLOG_SYSLOG) {
+		closelog(); /* ensure to close syslog not to interrupt with PHP syslog code */
+	} else
+#endif
+	if (fpm_globals.error_log_fd > 0) {
+		close(fpm_globals.error_log_fd);
+	}
 	fpm_globals.error_log_fd = -1;
 	zlog_set_fd(-1);

@@ -249,6 +260,17 @@
 {
 	int fd;

+#ifdef HAVE_SYSLOG_H
+	if (!strcasecmp(fpm_global_config.error_log, "syslog")) {
+		openlog(fpm_global_config.syslog_ident, LOG_PID | LOG_CONS, fpm_global_config.syslog_facility);
+		fpm_globals.error_log_fd = ZLOG_SYSLOG;
+		if (fpm_global_config.daemonize) {
+			zlog_set_fd(fpm_globals.error_log_fd);
+		}
+		return 0;
+	}
+#endif
+
 	fd = open(fpm_global_config.error_log, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
 	if (0 > fd) {
 		zlog(ZLOG_SYSERROR, "open(\"%s\") failed", fpm_global_config.error_log);

Modified: php/php-src/branches/PHP_5_4/sapi/fpm/fpm/zlog.c
===================================================================
--- php/php-src/branches/PHP_5_4/sapi/fpm/fpm/zlog.c	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/branches/PHP_5_4/sapi/fpm/fpm/zlog.c	2011-07-05 19:22:45 UTC (rev 312950)
@@ -12,6 +12,8 @@
 #include <sys/time.h>
 #include <errno.h>

+#include "php_syslog.h"
+
 #include "zlog.h"
 #include "fpm.h"

@@ -22,13 +24,23 @@
 static int launched = 0;

 static const char *level_names[] = {
-	[ZLOG_DEBUG]		= "DEBUG",
-	[ZLOG_NOTICE]		= "NOTICE",
-	[ZLOG_WARNING]		= "WARNING",
-	[ZLOG_ERROR]		= "ERROR",
-	[ZLOG_ALERT]		= "ALERT",
+	[ZLOG_DEBUG]   = "DEBUG",
+	[ZLOG_NOTICE]  = "NOTICE",
+	[ZLOG_WARNING] = "WARNING",
+	[ZLOG_ERROR]   = "ERROR",
+	[ZLOG_ALERT]   = "ALERT",
 };

+#ifdef HAVE_SYSLOG_H
+const int syslog_priorities[] = {
+	[ZLOG_DEBUG]   = LOG_DEBUG,
+	[ZLOG_NOTICE]  = LOG_NOTICE,
+	[ZLOG_WARNING] = LOG_WARNING,
+	[ZLOG_ERROR]   = LOG_ERR,
+	[ZLOG_ALERT]   = LOG_ALERT,
+};
+#endif
+
 const char *zlog_get_level_name(int log_level) /* {{{ */
 {
 	if (log_level < 0) {
@@ -94,18 +106,30 @@
 	}

 	saved_errno = errno;
-	if (!fpm_globals.is_child) {
-		gettimeofday(&tv, 0);
-		len = zlog_print_time(&tv, buf, buf_size);
-	}
-	if (zlog_level == ZLOG_DEBUG) {
+#ifdef HAVE_SYSLOG_H
+	if (zlog_fd == ZLOG_SYSLOG /* && !fpm_globals.is_child */) {
+		len = 0;
+		if (zlog_level == ZLOG_DEBUG) {
+			len += snprintf(buf, buf_size, "[%s] %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], function, line);
+		} else {
+			len += snprintf(buf, buf_size, "[%s] ", level_names[flags & ZLOG_LEVEL_MASK]);
+		}
+	} else
+#endif
+	{
 		if (!fpm_globals.is_child) {
-			len += snprintf(buf + len, buf_size - len, "%s: pid %d, %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], getpid(), function, line);
+			gettimeofday(&tv, 0);
+			len = zlog_print_time(&tv, buf, buf_size);
+		}
+		if (zlog_level == ZLOG_DEBUG) {
+			if (!fpm_globals.is_child) {
+				len += snprintf(buf + len, buf_size - len, "%s: pid %d, %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], getpid(), function, line);
+			} else {
+				len += snprintf(buf + len, buf_size - len, "%s: %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], function, line);
+			}
 		} else {
-			len += snprintf(buf + len, buf_size - len, "%s: %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], function, line);
+			len += snprintf(buf + len, buf_size - len, "%s: ", level_names[flags & ZLOG_LEVEL_MASK]);
 		}
-	} else {
-		len += snprintf(buf + len, buf_size - len, "%s: ", level_names[flags & ZLOG_LEVEL_MASK]);
 	}

 	if (len > buf_size - 1) {
@@ -135,9 +159,19 @@
 		len = buf_size - 1;
 	}

-	buf[len++] = '\n';
-	write(zlog_fd > -1 ? zlog_fd : STDERR_FILENO, buf, len);
-	if (zlog_fd != STDERR_FILENO && zlog_fd > -1 && !launched && (flags & ZLOG_LEVEL_MASK) >= ZLOG_NOTICE) {
+#ifdef HAVE_SYSLOG_H
+	if (zlog_fd == ZLOG_SYSLOG) {
+		buf[len] = '\0';
+		php_syslog(syslog_priorities[zlog_level], "%s", buf);
+		buf[len++] = '\n';
+	} else
+#endif
+	{
+		buf[len++] = '\n';
+		write(zlog_fd > -1 ? zlog_fd : STDERR_FILENO, buf, len);
+	}
+
+	if (zlog_fd != STDERR_FILENO && zlog_fd != -1 && !launched && (flags & ZLOG_LEVEL_MASK) >= ZLOG_NOTICE) {
 		write(STDERR_FILENO, buf, len);
 	}
 }

Modified: php/php-src/branches/PHP_5_4/sapi/fpm/fpm/zlog.h
===================================================================
--- php/php-src/branches/PHP_5_4/sapi/fpm/fpm/zlog.h	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/branches/PHP_5_4/sapi/fpm/fpm/zlog.h	2011-07-05 19:22:45 UTC (rev 312950)
@@ -19,6 +19,10 @@
 void zlog_ex(const char *function, int line, int flags, const char *fmt, ...)
 		__attribute__ ((format(printf,4,5)));

+#ifdef HAVE_SYSLOG_H
+extern const int syslog_priorities[];
+#endif
+
 enum {
 	ZLOG_DEBUG			= 1,
 	ZLOG_NOTICE			= 2,
@@ -33,4 +37,8 @@

 #define ZLOG_SYSERROR (ZLOG_ERROR | ZLOG_HAVE_ERRNO)

+#ifdef HAVE_SYSLOG_H
+#define ZLOG_SYSLOG -2
 #endif
+
+#endif

Modified: php/php-src/branches/PHP_5_4/sapi/fpm/php-fpm.conf.in
===================================================================
--- php/php-src/branches/PHP_5_4/sapi/fpm/php-fpm.conf.in	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/branches/PHP_5_4/sapi/fpm/php-fpm.conf.in	2011-07-05 19:22:45 UTC (rev 312950)
@@ -25,10 +25,25 @@
 ;pid = run/php-fpm.pid

 ; Error log file
+; If it's set to "syslog", log is sent to syslogd instead of being written
+; in a local file.
 ; Note: the default prefix is @EXPANDED_LOCALSTATEDIR@
 ; Default Value: log/php-fpm.log
 ;error_log = log/php-fpm.log

+; syslog_facility is used to specify what type of program is logging the
+; message. This lets syslogd specify that messages from different facilities
+; will be handled differently.
+; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
+; Default Value: daemon
+;syslog.facility = daemon
+
+; syslog_ident is prepended to every message. If you have multiple FPM
+; instances running on the same server, you can change the default value
+; which must suit common needs.
+; Default Value: php-fpm
+;syslog.ident = php-fpm
+
 ; Log level
 ; Possible Values: alert, error, warning, notice, debug
 ; Default Value: notice

Modified: php/php-src/trunk/sapi/fpm/fpm/fpm_conf.c
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/fpm_conf.c	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/trunk/sapi/fpm/fpm/fpm_conf.c	2011-07-05 19:22:45 UTC (rev 312950)
@@ -31,6 +31,7 @@
 #include "zend_ini_scanner.h"
 #include "zend_globals.h"
 #include "zend_stream.h"
+#include "php_syslog.h"

 #include "fpm.h"
 #include "fpm_conf.h"
@@ -58,8 +59,16 @@
 static char *fpm_conf_set_log_level(zval *value, void **config, intptr_t offset);
 static char *fpm_conf_set_rlimit_core(zval *value, void **config, intptr_t offset);
 static char *fpm_conf_set_pm(zval *value, void **config, intptr_t offset);
+#ifdef HAVE_SYSLOG_H
+static char *fpm_conf_set_syslog_facility(zval *value, void **config, intptr_t offset);
+#endif

-struct fpm_global_config_s fpm_global_config = { .daemonize = 1 };
+struct fpm_global_config_s fpm_global_config = {
+	.daemonize = 1,
+#ifdef HAVE_SYSLOG_H
+	.syslog_facility = -1
+#endif
+};
 static struct fpm_worker_pool_s *current_wp = NULL;
 static int ini_recursion = 0;
 static char *ini_filename = NULL;
@@ -67,15 +76,19 @@
 static char *ini_include = NULL;

 static struct ini_value_parser_s ini_fpm_global_options[] = {
-	{ "emergency_restart_threshold", &fpm_conf_set_integer,     GO(emergency_restart_threshold) },
-	{ "emergency_restart_interval",  &fpm_conf_set_time,        GO(emergency_restart_interval) },
-	{ "process_control_timeout",     &fpm_conf_set_time,        GO(process_control_timeout) },
-	{ "daemonize",                   &fpm_conf_set_boolean,     GO(daemonize) },
-	{ "pid",                         &fpm_conf_set_string,      GO(pid_file) },
-	{ "error_log",                   &fpm_conf_set_string,      GO(error_log) },
-	{ "log_level",                   &fpm_conf_set_log_level,   0 },
-	{ "rlimit_files",                &fpm_conf_set_integer,     GO(rlimit_files) },
-	{ "rlimit_core",                 &fpm_conf_set_rlimit_core, GO(rlimit_core) },
+	{ "emergency_restart_threshold", &fpm_conf_set_integer,         GO(emergency_restart_threshold) },
+	{ "emergency_restart_interval",  &fpm_conf_set_time,            GO(emergency_restart_interval) },
+	{ "process_control_timeout",     &fpm_conf_set_time,            GO(process_control_timeout) },
+	{ "daemonize",                   &fpm_conf_set_boolean,         GO(daemonize) },
+	{ "pid",                         &fpm_conf_set_string,          GO(pid_file) },
+	{ "error_log",                   &fpm_conf_set_string,          GO(error_log) },
+	{ "log_level",                   &fpm_conf_set_log_level,       GO(log_level) },
+#ifdef HAVE_SYSLOG_H
+	{ "syslog.ident",                &fpm_conf_set_string,          GO(syslog_ident) },
+	{ "syslog.facility",             &fpm_conf_set_syslog_facility, GO(syslog_facility) },
+#endif
+	{ "rlimit_files",                &fpm_conf_set_integer,         GO(rlimit_files) },
+	{ "rlimit_core",                 &fpm_conf_set_rlimit_core,     GO(rlimit_core) },
 	{ 0, 0, 0 }
 };

@@ -252,25 +265,178 @@
 static char *fpm_conf_set_log_level(zval *value, void **config, intptr_t offset) /* {{{ */
 {
 	char *val = Z_STRVAL_P(value);
+	int log_level;

 	if (!strcasecmp(val, "debug")) {
-		fpm_globals.log_level = ZLOG_DEBUG;
+		log_level = ZLOG_DEBUG;
 	} else if (!strcasecmp(val, "notice")) {
-		fpm_globals.log_level = ZLOG_NOTICE;
+		log_level = ZLOG_NOTICE;
 	} else if (!strcasecmp(val, "warning") || !strcasecmp(val, "warn")) {
-		fpm_globals.log_level = ZLOG_WARNING;
+		log_level = ZLOG_WARNING;
 	} else if (!strcasecmp(val, "error")) {
-		fpm_globals.log_level = ZLOG_ERROR;
+		log_level = ZLOG_ERROR;
 	} else if (!strcasecmp(val, "alert")) {
-		fpm_globals.log_level = ZLOG_ALERT;
+		log_level = ZLOG_ALERT;
 	} else {
 		return "invalid value for 'log_level'";
 	}

+	* (int *) ((char *) *config + offset) = log_level;
 	return NULL;
 }
 /* }}} */

+#ifdef HAVE_SYSLOG_H
+static char *fpm_conf_set_syslog_facility(zval *value, void **config, intptr_t offset) /* {{{ */
+{
+	char *val = Z_STRVAL_P(value);
+	int *conf = (int *) ((char *) *config + offset);
+
+#ifdef LOG_AUTH
+	if (!strcasecmp(val, "AUTH")) {
+		*conf = LOG_AUTH;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_AUTHPRIV
+	if (!strcasecmp(val, "AUTHPRIV")) {
+		*conf = LOG_AUTHPRIV;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_CRON
+	if (!strcasecmp(val, "CRON")) {
+		*conf = LOG_CRON;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_DAEMON
+	if (!strcasecmp(val, "DAEMON")) {
+		*conf = LOG_DAEMON;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_FTP
+	if (!strcasecmp(val, "FTP")) {
+		*conf = LOG_FTP;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_KERN
+	if (!strcasecmp(val, "KERN")) {
+		*conf = LOG_KERN;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LPR
+	if (!strcasecmp(val, "LPR")) {
+		*conf = LOG_LPR;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_MAIL
+	if (!strcasecmp(val, "MAIL")) {
+		*conf = LOG_MAIL;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_NEWS
+	if (!strcasecmp(val, "NEWS")) {
+		*conf = LOG_NEWS;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_SYSLOG
+	if (!strcasecmp(val, "SYSLOG")) {
+		*conf = LOG_SYSLOG;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_USER
+	if (!strcasecmp(val, "USER")) {
+		*conf = LOG_USER;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_UUCP
+	if (!strcasecmp(val, "UUCP")) {
+		*conf = LOG_UUCP;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL0
+	if (!strcasecmp(val, "LOCAL0")) {
+		*conf = LOG_LOCAL0;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL1
+	if (!strcasecmp(val, "LOCAL1")) {
+		*conf = LOG_LOCAL1;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL2
+	if (!strcasecmp(val, "LOCAL2")) {
+		*conf = LOG_LOCAL2;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL3
+	if (!strcasecmp(val, "LOCAL3")) {
+		*conf = LOG_LOCAL3;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL4
+	if (!strcasecmp(val, "LOCAL4")) {
+		*conf = LOG_LOCAL4;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL5
+	if (!strcasecmp(val, "LOCAL5")) {
+		*conf = LOG_LOCAL5;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL6
+	if (!strcasecmp(val, "LOCAL6")) {
+		*conf = LOG_LOCAL6;
+		return NULL;
+	}
+#endif
+
+#ifdef LOG_LOCAL7
+	if (!strcasecmp(val, "LOCAL7")) {
+		*conf = LOG_LOCAL7;
+		return NULL;
+	}
+#endif
+
+	return "invalid value";
+}
+/* }}} */
+#endif
+
 static char *fpm_conf_set_rlimit_core(zval *value, void **config, intptr_t offset) /* {{{ */
 {
 	char *val = Z_STRVAL_P(value);
@@ -794,12 +960,27 @@
 		fpm_evaluate_full_path(&fpm_global_config.pid_file, NULL, PHP_LOCALSTATEDIR, 0);
 	}

+	fpm_globals.log_level = fpm_global_config.log_level;
+
 	if (!fpm_global_config.error_log) {
 		fpm_global_config.error_log = strdup("log/php-fpm.log");
 	}

-	fpm_evaluate_full_path(&fpm_global_config.error_log, NULL, PHP_LOCALSTATEDIR, 0);
+#ifdef HAVE_SYSLOG_H
+	if (!fpm_global_config.syslog_ident) {
+		fpm_global_config.syslog_ident = strdup("php-fpm");
+	}

+	if (fpm_global_config.syslog_facility < 0) {
+		fpm_global_config.syslog_facility = LOG_DAEMON;
+	}
+
+	if (strcasecmp(fpm_global_config.error_log, "syslog") != 0)
+#endif
+	{
+		fpm_evaluate_full_path(&fpm_global_config.error_log, NULL, PHP_LOCALSTATEDIR, 0);
+	}
+
 	if (0 > fpm_stdio_open_error_log(0)) {
 		return -1;
 	}
@@ -832,6 +1013,10 @@
 	free(fpm_global_config.error_log);
 	fpm_global_config.pid_file = 0;
 	fpm_global_config.error_log = 0;
+#ifdef HAVE_SYSLOG_H
+	free(fpm_global_config.syslog_ident);
+	fpm_global_config.syslog_ident = 0;
+#endif
 	free(fpm_globals.config);
 }
 /* }}} */
@@ -1152,6 +1337,10 @@
 	zlog(ZLOG_NOTICE, "\tdaemonize = %s",                   BOOL2STR(fpm_global_config.daemonize));
 	zlog(ZLOG_NOTICE, "\terror_log = %s",                   STR2STR(fpm_global_config.error_log));
 	zlog(ZLOG_NOTICE, "\tlog_level = %s",                   zlog_get_level_name(fpm_globals.log_level));
+#ifdef HAVE_SYSLOG_H
+	zlog(ZLOG_NOTICE, "\tsyslog.ident = %s",                STR2STR(fpm_global_config.syslog_ident));
+	zlog(ZLOG_NOTICE, "\tsyslog.facility = %d",             fpm_global_config.syslog_facility); /* FIXME: convert to string */
+#endif
 	zlog(ZLOG_NOTICE, "\tprocess_control_timeout = %ds",    fpm_global_config.process_control_timeout);
 	zlog(ZLOG_NOTICE, "\temergency_restart_interval = %ds", fpm_global_config.emergency_restart_interval);
 	zlog(ZLOG_NOTICE, "\temergency_restart_threshold = %d", fpm_global_config.emergency_restart_threshold);

Modified: php/php-src/trunk/sapi/fpm/fpm/fpm_conf.h
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/fpm_conf.h	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/trunk/sapi/fpm/fpm/fpm_conf.h	2011-07-05 19:22:45 UTC (rev 312950)
@@ -25,6 +25,11 @@
 	int daemonize;
 	char *pid_file;
 	char *error_log;
+	int log_level;
+#ifdef HAVE_SYSLOG_H
+	char *syslog_ident;
+	int syslog_facility;
+#endif
 	int rlimit_files;
 	int rlimit_core;
 };

Modified: php/php-src/trunk/sapi/fpm/fpm/fpm_stdio.c
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/fpm_stdio.c	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/trunk/sapi/fpm/fpm/fpm_stdio.c	2011-07-05 19:22:45 UTC (rev 312950)
@@ -11,6 +11,8 @@
 #include <unistd.h>
 #include <errno.h>

+#include "php_syslog.h"
+
 #include "fpm.h"
 #include "fpm_children.h"
 #include "fpm_events.h"
@@ -42,8 +44,10 @@
 int fpm_stdio_init_final() /* {{{ */
 {
 	if (fpm_global_config.daemonize) {
-		if (fpm_globals.error_log_fd != STDERR_FILENO) {
-			/* there might be messages to stderr from libevent, we need to log them all */
+		/* prevent duping if logging to syslog */
+		if (fpm_globals.error_log_fd > 0 && fpm_globals.error_log_fd != STDERR_FILENO) {
+
+			/* there might be messages to stderr from other parts of the code, we need to log them all */
 			if (0 > dup2(fpm_globals.error_log_fd, STDERR_FILENO)) {
 				zlog(ZLOG_SYSERROR, "dup2() failed");
 				return -1;
@@ -57,7 +61,14 @@

 int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
 {
-	close(fpm_globals.error_log_fd);
+#ifdef HAVE_SYSLOG_H
+	if (fpm_globals.error_log_fd == ZLOG_SYSLOG) {
+		closelog(); /* ensure to close syslog not to interrupt with PHP syslog code */
+	} else
+#endif
+	if (fpm_globals.error_log_fd > 0) {
+		close(fpm_globals.error_log_fd);
+	}
 	fpm_globals.error_log_fd = -1;
 	zlog_set_fd(-1);

@@ -249,6 +260,17 @@
 {
 	int fd;

+#ifdef HAVE_SYSLOG_H
+	if (!strcasecmp(fpm_global_config.error_log, "syslog")) {
+		openlog(fpm_global_config.syslog_ident, LOG_PID | LOG_CONS, fpm_global_config.syslog_facility);
+		fpm_globals.error_log_fd = ZLOG_SYSLOG;
+		if (fpm_global_config.daemonize) {
+			zlog_set_fd(fpm_globals.error_log_fd);
+		}
+		return 0;
+	}
+#endif
+
 	fd = open(fpm_global_config.error_log, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
 	if (0 > fd) {
 		zlog(ZLOG_SYSERROR, "open(\"%s\") failed", fpm_global_config.error_log);

Modified: php/php-src/trunk/sapi/fpm/fpm/zlog.c
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/zlog.c	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/trunk/sapi/fpm/fpm/zlog.c	2011-07-05 19:22:45 UTC (rev 312950)
@@ -12,6 +12,8 @@
 #include <sys/time.h>
 #include <errno.h>

+#include "php_syslog.h"
+
 #include "zlog.h"
 #include "fpm.h"

@@ -22,13 +24,23 @@
 static int launched = 0;

 static const char *level_names[] = {
-	[ZLOG_DEBUG]		= "DEBUG",
-	[ZLOG_NOTICE]		= "NOTICE",
-	[ZLOG_WARNING]		= "WARNING",
-	[ZLOG_ERROR]		= "ERROR",
-	[ZLOG_ALERT]		= "ALERT",
+	[ZLOG_DEBUG]   = "DEBUG",
+	[ZLOG_NOTICE]  = "NOTICE",
+	[ZLOG_WARNING] = "WARNING",
+	[ZLOG_ERROR]   = "ERROR",
+	[ZLOG_ALERT]   = "ALERT",
 };

+#ifdef HAVE_SYSLOG_H
+const int syslog_priorities[] = {
+	[ZLOG_DEBUG]   = LOG_DEBUG,
+	[ZLOG_NOTICE]  = LOG_NOTICE,
+	[ZLOG_WARNING] = LOG_WARNING,
+	[ZLOG_ERROR]   = LOG_ERR,
+	[ZLOG_ALERT]   = LOG_ALERT,
+};
+#endif
+
 const char *zlog_get_level_name(int log_level) /* {{{ */
 {
 	if (log_level < 0) {
@@ -94,18 +106,30 @@
 	}

 	saved_errno = errno;
-	if (!fpm_globals.is_child) {
-		gettimeofday(&tv, 0);
-		len = zlog_print_time(&tv, buf, buf_size);
-	}
-	if (zlog_level == ZLOG_DEBUG) {
+#ifdef HAVE_SYSLOG_H
+	if (zlog_fd == ZLOG_SYSLOG /* && !fpm_globals.is_child */) {
+		len = 0;
+		if (zlog_level == ZLOG_DEBUG) {
+			len += snprintf(buf, buf_size, "[%s] %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], function, line);
+		} else {
+			len += snprintf(buf, buf_size, "[%s] ", level_names[flags & ZLOG_LEVEL_MASK]);
+		}
+	} else
+#endif
+	{
 		if (!fpm_globals.is_child) {
-			len += snprintf(buf + len, buf_size - len, "%s: pid %d, %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], getpid(), function, line);
+			gettimeofday(&tv, 0);
+			len = zlog_print_time(&tv, buf, buf_size);
+		}
+		if (zlog_level == ZLOG_DEBUG) {
+			if (!fpm_globals.is_child) {
+				len += snprintf(buf + len, buf_size - len, "%s: pid %d, %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], getpid(), function, line);
+			} else {
+				len += snprintf(buf + len, buf_size - len, "%s: %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], function, line);
+			}
 		} else {
-			len += snprintf(buf + len, buf_size - len, "%s: %s(), line %d: ", level_names[flags & ZLOG_LEVEL_MASK], function, line);
+			len += snprintf(buf + len, buf_size - len, "%s: ", level_names[flags & ZLOG_LEVEL_MASK]);
 		}
-	} else {
-		len += snprintf(buf + len, buf_size - len, "%s: ", level_names[flags & ZLOG_LEVEL_MASK]);
 	}

 	if (len > buf_size - 1) {
@@ -135,9 +159,19 @@
 		len = buf_size - 1;
 	}

-	buf[len++] = '\n';
-	write(zlog_fd > -1 ? zlog_fd : STDERR_FILENO, buf, len);
-	if (zlog_fd != STDERR_FILENO && zlog_fd > -1 && !launched && (flags & ZLOG_LEVEL_MASK) >= ZLOG_NOTICE) {
+#ifdef HAVE_SYSLOG_H
+	if (zlog_fd == ZLOG_SYSLOG) {
+		buf[len] = '\0';
+		php_syslog(syslog_priorities[zlog_level], "%s", buf);
+		buf[len++] = '\n';
+	} else
+#endif
+	{
+		buf[len++] = '\n';
+		write(zlog_fd > -1 ? zlog_fd : STDERR_FILENO, buf, len);
+	}
+
+	if (zlog_fd != STDERR_FILENO && zlog_fd != -1 && !launched && (flags & ZLOG_LEVEL_MASK) >= ZLOG_NOTICE) {
 		write(STDERR_FILENO, buf, len);
 	}
 }

Modified: php/php-src/trunk/sapi/fpm/fpm/zlog.h
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/zlog.h	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/trunk/sapi/fpm/fpm/zlog.h	2011-07-05 19:22:45 UTC (rev 312950)
@@ -19,6 +19,10 @@
 void zlog_ex(const char *function, int line, int flags, const char *fmt, ...)
 		__attribute__ ((format(printf,4,5)));

+#ifdef HAVE_SYSLOG_H
+extern const int syslog_priorities[];
+#endif
+
 enum {
 	ZLOG_DEBUG			= 1,
 	ZLOG_NOTICE			= 2,
@@ -33,4 +37,8 @@

 #define ZLOG_SYSERROR (ZLOG_ERROR | ZLOG_HAVE_ERRNO)

+#ifdef HAVE_SYSLOG_H
+#define ZLOG_SYSLOG -2
 #endif
+
+#endif

Modified: php/php-src/trunk/sapi/fpm/php-fpm.conf.in
===================================================================
--- php/php-src/trunk/sapi/fpm/php-fpm.conf.in	2011-07-05 19:13:19 UTC (rev 312949)
+++ php/php-src/trunk/sapi/fpm/php-fpm.conf.in	2011-07-05 19:22:45 UTC (rev 312950)
@@ -25,10 +25,25 @@
 ;pid = run/php-fpm.pid

 ; Error log file
+; If it's set to "syslog", log is sent to syslogd instead of being written
+; in a local file.
 ; Note: the default prefix is @EXPANDED_LOCALSTATEDIR@
 ; Default Value: log/php-fpm.log
 ;error_log = log/php-fpm.log

+; syslog_facility is used to specify what type of program is logging the
+; message. This lets syslogd specify that messages from different facilities
+; will be handled differently.
+; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
+; Default Value: daemon
+;syslog.facility = daemon
+
+; syslog_ident is prepended to every message. If you have multiple FPM
+; instances running on the same server, you can change the default value
+; which must suit common needs.
+; Default Value: php-fpm
+;syslog.ident = php-fpm
+
 ; Log level
 ; Possible Values: alert, error, warning, notice, debug
 ; Default Value: notice
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to