Hi guys, I was looking at bugs #51118 and #52052. Both are related to syslog (one from a user PHP script and the other within FPM).
I think syslog is not handled correctely by PHP. Let me explain: There is basically 3 functions provided by the syslog library: void openlog(const char *ident, int option, int facility); void syslog(int priority, const char *format, ...); void closelog(void); If syslog(...) is only used, messages are logged with default facility, ident and option. If openlog(...) is called before syslog(...), default facility, ident and option are replaced. closelog() restores default facility, ident and option. These 3 options (facility, ident and option) visibility is global to a process. So if independent parts of a program are calling openlog(), syslog() and closelog() on their sides, it will affect others. This typically happens in PHP. here is an example running with php-cli (in order not to think with forks and threads): <?php trigger_error("PHP error #1 (logged by PHP core) ".getmypid()); openlog("custom ident", LOG_PID, LOG_LOCAL0); syslog(LOG_ALERT, "message from PHP script ".getmypid()); trigger_error("PHP error #2 (logged by PHP core) ".getmypid()); ?> I've added the 2 following lines to my /etc/syslog.conf in order to send LOG_USER and LOG_LOCAL0 to different files: local0.* /var/log/local0.log user.* /var/log/loguser.log I ran ./sapi/cli/php -d error_reporting=E_ALL -d log_errors=On -d error_log=syslog test.php and the results: ==> /var/log/loguser.log <== Jan 29 16:56:16 wild php: PHP Notice: PHP error #1 (logged by PHP core) 28503 in /LIBRE/dev/php-src/trunk/test.php on line 2 ==> /var/log/local0.log <== Jan 29 16:56:16 wild custom ident[28503]: message from PHP script 28503 Jan 29 16:56:16 wild custom ident[28503]: PHP Notice: PHP error #2 (logged by PHP core) 28503 in /LIBRE/dev/php-src/trunk/test.php on line 5 The first trigger_error is sent correctely with facility LOG_USER (the default one, as php core does not call openlog) and the name of the process for the ident. The syslog() calls from my php script, is sent correctely to LOG_LOCAL0 (as set with the previous openlog() call) But the last trigger_error is also sent to LOG_LOCAL0 which is wrong as it should have been sent to LOCAL_USER Now, we can imagine the switching errors it can cause on a multiple vhost shared prefork apache . I've been working the following patch (attached in bug #51118) http://bugs.php.net/patch-display.php?bug_id=51118&patch=php-syslog.patch&revision=1296394262&download=1 What's been done : - add error_log_facility and error_log_ident variables to php.ini - add main/php_syslog.c file with : - php_openlog: save ident, facility and option in its global context before calling openlog - php_closelog: clear global context before calling closelog - php_syslog_get_ident: returns the ident global context - php_syslog_get_facility: returns the facility global context - php_syslog_get_option: returns the option global context - php_syslog2() is quite the same as php_syslog with ident/facility/option arguments added. Thoses are compared to the syslog global context, and openlog is called if they don't match. - php_syslog remains #defined to syslog - in main/main.c: - if error_log is set to "syslog", call php_syslog2() with error_log_ident/facility instead of php_syslog() - in ext/standard/syslog.c - now openlog() returns a ressource which contains ident/option/facility - now syslog() and closelog() takes an optional ressource parameter (returned from openlog) - use php_syslog2,php_openlog and php_closelog - in sapi/milter/php_milter.c - use php_syslog2 in place of previous openlog/syslog what guys do you think ? ++ Jerome -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php