From 07dcb07fd205294d6cedb0972a60db48f0ffbf76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Tue, 16 Oct 2012 02:01:37 +0200 Subject: [PATCH 1/7] Created a modular syslog handler system I've split all log handlers into classes so that people can make new log handler systems without making changes to the core. Also, now every log handler can handle how and what will be logged. --- htdocs/admin/syslog.php | 268 ++++++++++-------- htdocs/core/lib/functions.lib.php | 187 ++++-------- htdocs/core/modules/syslog/logHandler.php | 57 ++++ .../modules/syslog/logHandlerInterface.php | 12 + .../modules/syslog/mod_syslog_chromephp.php | 122 ++++++++ .../core/modules/syslog/mod_syslog_file.php | 121 ++++++++ .../modules/syslog/mod_syslog_firephp.php | 124 ++++++++ .../core/modules/syslog/mod_syslog_syslog.php | 109 +++++++ 8 files changed, 754 insertions(+), 246 deletions(-) create mode 100644 htdocs/core/modules/syslog/logHandler.php create mode 100644 htdocs/core/modules/syslog/logHandlerInterface.php create mode 100644 htdocs/core/modules/syslog/mod_syslog_chromephp.php create mode 100644 htdocs/core/modules/syslog/mod_syslog_file.php create mode 100644 htdocs/core/modules/syslog/mod_syslog_firephp.php create mode 100644 htdocs/core/modules/syslog/mod_syslog_syslog.php diff --git a/htdocs/admin/syslog.php b/htdocs/admin/syslog.php index 5a2b34772a1..4038418061c 100644 --- a/htdocs/admin/syslog.php +++ b/htdocs/admin/syslog.php @@ -33,10 +33,42 @@ $langs->load("other"); $error=0; $mesg=''; $action = GETPOST("action"); -$syslog_file_on=(defined('SYSLOG_FILE_ON') && constant('SYSLOG_FILE_ON'))?1:0; -$syslog_syslog_on=(defined('SYSLOG_SYSLOG_ON') && constant('SYSLOG_SYSLOG_ON'))?1:0; -$syslog_firephp_on=(defined('SYSLOG_FIREPHP_ON') && constant('SYSLOG_FIREPHP_ON'))?1:0; -$syslog_chromephp_on=(defined('SYSLOG_CHROMEPHP_ON') && constant('SYSLOG_CHROMEPHP_ON'))?1:0; + +$syslogModules = array(); +$activeModules = array(); + +if (defined('SYSLOG_HANDLERS')) $activeModules = unserialize(SYSLOG_HANDLERS); + +$dir = dol_buildpath('/core/modules/syslog/'); + +if (is_dir($dir)) +{ + $handle = opendir($dir); + + if (is_resource($handle)) + { + $var=true; + + while (($file = readdir($handle))!==false) + { + if (substr($file, 0, 11) == 'mod_syslog_' && substr($file, dol_strlen($file)-3, 3) == 'php') + { + $file = substr($file, 0, dol_strlen($file)-4); + + require_once $dir.$file.'.php'; + + $module = new $file; + + // Show modules according to features level + if ($module->getVersion() == $module::DEVELOPMENT && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->getVersion() == $module::EXPERIMENTAL && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + $syslogModules[] = $file; + } + } + closedir($handle); + } +} /* @@ -48,71 +80,32 @@ if ($action == 'set') { $db->begin(); - $res = dolibarr_del_const($db,"SYSLOG_FILE_ON",0); - $res = dolibarr_del_const($db,"SYSLOG_SYSLOG_ON",0); - $res = dolibarr_del_const($db,"SYSLOG_FIREPHP_ON",0); - $res = dolibarr_del_const($db,"SYSLOG_CHROMEPHP_ON",0); + $activeModules = array(); + $selectedModules = (isset($_POST['SYSLOG_HANDLERS']) ? $_POST['SYSLOG_HANDLERS'] : array()); - $syslog_file_on=0; - $syslog_syslog_on=0; - $syslog_firephp_on=0; - $syslog_chromephp_on=0; - - if (! $error && GETPOST("filename")) + foreach ($selectedModules as $syslogHandler) { - $filename=GETPOST("filename"); - $filelog=GETPOST("filename"); - $filelog=preg_replace('/DOL_DATA_ROOT/i',DOL_DATA_ROOT,$filelog); - $file=@fopen($filelog,"a+"); - if ($file) + if (in_array($syslogHandler, $syslogModules)) { - fclose($file); + $module = new $syslogHandler; - dol_syslog("admin/syslog: file ".$filename); - $res = dolibarr_set_const($db,"SYSLOG_FILE",$filename,'chaine',0,'',0); - if (! $res > 0) $error++; - $syslog_file_on=GETPOST('SYSLOG_FILE_ON'); - if (! $error) $res = dolibarr_set_const($db,"SYSLOG_FILE_ON",$syslog_file_on,'chaine',0,'',0); - } - else - { - $error++; - $mesg = "".$langs->trans("ErrorFailedToOpenFile",$filename).""; + if ($module->isActive()) + { + $activeModules[] = $syslogHandler; + + foreach ($module->configure() as $option) + { + if ($_POST[$option['constant']]) + { + dolibarr_del_const($db, $option['constant'], 0); + dolibarr_set_const($db, $option['constant'], $_POST[$option['constant']], 'chaine'); + } + } + } } } - if (! $error && GETPOST("facility")) - { - $facility=GETPOST("facility"); - if (defined($_POST["facility"])) - { - // Only LOG_USER supported on Windows - if (! empty($_SERVER["WINDIR"])) $facility='LOG_USER'; - - dol_syslog("admin/syslog: facility ".$facility); - $res = dolibarr_set_const($db,"SYSLOG_FACILITY",$facility,'chaine',0,'',0); - if (! $res > 0) $error++; - $syslog_syslog_on=GETPOST('SYSLOG_SYSLOG_ON'); - if (! $error) $res = dolibarr_set_const($db,"SYSLOG_SYSLOG_ON",$syslog_syslog_on,'chaine',0,'',0); - } - else - { - $error++; - $mesg = "".$langs->trans("ErrorUnknownSyslogConstant",$facility).""; - } - } - - if (! $error && isset($_POST['SYSLOG_FIREPHP_ON'])) // If firephp no available, post is not present. We must keep isset here. - { - $syslog_firephp_on=GETPOST('SYSLOG_FIREPHP_ON'); - if (! $error) $res = dolibarr_set_const($db,"SYSLOG_FIREPHP_ON",$syslog_firephp_on,'chaine',0,'',0); - } - - if (! $error && isset($_POST['SYSLOG_CHROMEPHP_ON'])) // If chromephp no available, post is not present. We must keep isset here. - { - $syslog_chromephp_on=GETPOST('SYSLOG_CHROMEPHP_ON'); - if (! $error) $res = dolibarr_set_const($db,"SYSLOG_CHROMEPHP_ON",$syslog_chromephp_on,'chaine',0,'',0); - } + dolibarr_set_const($db, 'SYSLOG_HANDLERS', serialize($activeModules), 'chaine'); if (! $error) { @@ -185,71 +178,102 @@ print '\n"; $var=true; -// Output to file -$var=!$var; -print ' '.$langs->trans("SyslogSimpleFile").''; -print ''.$langs->trans("SyslogFilename").': '; -print ''; -print "".$form->textwithpicto('',$langs->trans("YouCanUseDOL_DATA_ROOT")); -print ''; - -// Output to syslog -$var=!$var; -print ' '.$langs->trans("SyslogSyslog").''; -print ''.$langs->trans("SyslogFacility").': '; -print ''; -print "".$form->textwithpicto('', $langs->trans('OnlyWindowsLOG_USER')); -print ''; - -// Output to Firebug -try +foreach ($syslogModules as $moduleName) { - set_include_path('/usr/share/php/'); - $res=@include_once 'FirePHPCore/FirePHP.class.php'; - restore_include_path(); - if ($res) - { - $var=!$var; - print ' '.$langs->trans("FirePHP").''; - print ''; - print ''; - print "".$form->textwithpicto('','FirePHP must be installed onto PHP and FirePHP plugin for Firefox must also be installed'); - print ''; - } -} -catch(Exception $e) -{ - // Do nothing - print ''."\n"; -} + $module = new $moduleName; -// Output to Chrome -try -{ - set_include_path('/usr/share/php/'); - $res=@include_once 'ChromePhp.php'; - restore_include_path(); - if ($res) + $var=!$var; + print ''; + print 'isActive() ? 'disabled="disabled"' : '').'> '; + print $module->getName().''; + + print ''; + if ($module->configure()) { - $var=!$var; - print ' '.$langs->trans("ChromePHP").''; - print ''; - print ''; - print "".$form->textwithpicto('','ChromePHP must be installed onto PHP path and ChromePHP plugin for Chrome must also be installed'); - print ''; + foreach ($module->configure() as $option) + { + if (defined($option['constant'])) $value = constant($option['constant']); + else $value = (isset($option['default']) ? $option['default'] : ''); + + print $option['name'].': '; + } } + print ''; + + print ''; + if ($module->getInfo()) + { + print $form->textwithpicto('', $module->getInfo()); + } + print ''; + print "\n"; } -catch(Exception $e) -{ - // Do nothing - print ''."\n"; -} + +// // Output to file +// $var=!$var; +// print ' '.$langs->trans("SyslogSimpleFile").''; +// print ''.$langs->trans("SyslogFilename").': '; +// print ''; +// print "".$form->textwithpicto('',$langs->trans("YouCanUseDOL_DATA_ROOT")); +// print ''; + +// // Output to syslog +// $var=!$var; +// print ' '.$langs->trans("SyslogSyslog").''; +// print ''.$langs->trans("SyslogFacility").': '; +// print ''; +// print "".$form->textwithpicto('', $langs->trans('OnlyWindowsLOG_USER')); +// print ''; + +// // Output to Firebug +// try +// { +// set_include_path('/usr/share/php/'); +// $res=@include_once 'FirePHPCore/FirePHP.class.php'; +// restore_include_path(); +// if ($res) +// { +// $var=!$var; +// print ' '.$langs->trans("FirePHP").''; +// print ''; +// print ''; +// print "".$form->textwithpicto('','FirePHP must be installed onto PHP and FirePHP plugin for Firefox must also be installed'); +// print ''; +// } +// } +// catch(Exception $e) +// { +// // Do nothing +// print ''."\n"; +// } + +// // Output to Chrome +// try +// { +// set_include_path('/usr/share/php/'); +// $res=@include_once 'ChromePhp.php'; +// restore_include_path(); +// if ($res) +// { +// $var=!$var; +// print ' '.$langs->trans("ChromePHP").''; +// print ''; +// print ''; +// print "".$form->textwithpicto('','ChromePHP must be installed onto PHP path and ChromePHP plugin for Chrome must also be installed'); +// print ''; +// } +// } +// catch(Exception $e) +// { +// // Do nothing +// print ''."\n"; +// } print "\n"; print "\n"; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c4473d06f7c..150c7c5948d 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -463,147 +463,86 @@ function dol_escape_htmltag($stringtoescape,$keepb=0) * On Linux LOG_ERR=3, LOG_WARNING=4, LOG_INFO=6, LOG_DEBUG=7 * @return void */ -function dol_syslog($message, $level=LOG_INFO) +function dol_syslog($message, $level = LOG_INFO) { - global $conf,$user,$langs,$_REQUEST; + global $conf, $user, $langs; + + // If syslog module enabled + if (empty($conf->syslog->enabled)) return false; + + if (!defined('SYSLOG_HANDLERS') || !constant('SYSLOG_HANDLERS')) return false; + + $logLevels = array( + LOG_EMERG, + LOG_ALERT, + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG + ); + + if (!in_array($level, $logLevels)) + { + throw new Exception('Incorrect log level'); + } + + if ($level > $conf->global->SYSLOG_LEVEL) return false; // If adding log inside HTML page is required if (! empty($_REQUEST['logtohtml']) && ! empty($conf->global->MAIN_LOGTOHTML)) { - $conf->logbuffer[]=dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".$message; + $conf->logbuffer[] = dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".$message; } - // If syslog module enabled - if (! empty($conf->syslog->enabled)) + // If enable html log tag enabled and url parameter log defined, we show output log on HTML comments + if (! empty($conf->global->MAIN_ENABLE_LOG_HTML) && ! empty($_GET["log"])) { - //print $level.' - '.$conf->global->SYSLOG_LEVEL.' - '.$conf->syslog->enabled." \n"; - if ($level > $conf->global->SYSLOG_LEVEL) return; + print "\n\n\n"; + } - // Translate error message if this is an error message (rare) and langs is loaded - if ($level == LOG_ERR) + $data = array( + 'message' => $message, + 'script' => (isset($_SERVER['PHP_SELF'])? basename($_SERVER['PHP_SELF'],'.php') : false), + 'level' => $level, + 'user' => ((is_object($user) && $user->id) ? $user->login : false), + 'ip' => false + ); + + if (! empty($_SERVER["REMOTE_ADDR"])) $data['ip'] = $_SERVER['REMOTE_ADDR']; + // This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache) + else if (! empty($_SERVER['SERVER_ADDR'])) $data['ip'] = $_SERVER['SERVER_ADDR']; + // This is when PHP session is ran outside a web server, like from Windows command line (Not always defined, but useful if OS defined it). + else if (! empty($_SERVER['COMPUTERNAME'])) $data['ip'] = $_SERVER['COMPUTERNAME'].(empty($_SERVER['USERNAME'])?'':'@'.$_SERVER['USERNAME']); + // This is when PHP session is ran outside a web server, like from Linux command line (Not always defined, but usefull if OS defined it). + else if (! empty($_SERVER['LOGNAME'])) $data['ip'] = '???@'.$_SERVER['LOGNAME']; + + //We load SYSLOG handlers + if (defined('SYSLOG_HANDLERS')) $handlers = unserialize(SYSLOG_HANDLERS); + else $handlers = array(); + + foreach ($handlers as $handler) + { + $file = DOL_DOCUMENT_ROOT.'/core/modules/syslog/'.$handler.'.php'; + + if (!file_exists($file)) { - if (is_object($langs)) - { - $langs->load("errors"); - if ($message != $langs->trans($message)) $message = $langs->trans($message); - } + throw new Exception('Missing log handler'); } - // Add page/script name to log message - $script=isset($_SERVER['PHP_SELF'])?basename($_SERVER['PHP_SELF'],'.php').' ':''; - $message=$script.$message; + require_once $file; - // Add user to log message - $login='nologin'; - if (is_object($user) && $user->id) $login=$user->login; - $message=sprintf("%-8s",$login)." ".$message; + $class = new $handler(); - // Check if log is to a file (SYSLOG_FILE_ON defined) - if (defined("SYSLOG_FILE_ON") && constant("SYSLOG_FILE_ON")) + if (!$class instanceof LogHandlerInterface) { - $filelog=SYSLOG_FILE; - $filelog=preg_replace('/DOL_DATA_ROOT/i',DOL_DATA_ROOT,$filelog); - //print "filelog=".$filelog."\n"; - if (defined("SYSLOG_FILE_NO_ERROR")) $file=@fopen($filelog,"a+"); - else $file=fopen($filelog,"a+"); - - if ($file) - { - $ip='???'; // $ip contains information to identify computer that run the code - if (! empty($_SERVER["REMOTE_ADDR"])) $ip=$_SERVER["REMOTE_ADDR"]; // In most cases. - else if (! empty($_SERVER['SERVER_ADDR'])) $ip=$_SERVER['SERVER_ADDR']; // This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache) - else if (! empty($_SERVER['COMPUTERNAME'])) $ip=$_SERVER['COMPUTERNAME'].(empty($_SERVER['USERNAME'])?'':'@'.$_SERVER['USERNAME']); // This is when PHP session is ran outside a web server, like from Windows command line (Not always defined, but usefull if OS defined it). - else if (! empty($_SERVER['LOGNAME'])) $ip='???@'.$_SERVER['LOGNAME']; // This is when PHP session is ran outside a web server, like from Linux command line (Not always defined, but usefull if OS defined it). - - $liblevelarray=array(LOG_ERR=>'ERROR',LOG_WARNING=>'WARN',LOG_INFO=>'INFO',LOG_DEBUG=>'DEBUG'); - $liblevel=$liblevelarray[$level]; - if (! $liblevel) $liblevel='UNDEF'; - - $message=dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".sprintf("%-5s",$liblevel)." ".sprintf("%-15s",$ip)." ".$message; - - fwrite($file,$message."\n"); - fclose($file); - // This is for log file, we do not change permissions - - // If enable html log tag enabled and url parameter log defined, we show output log on HTML comments - if (! empty($conf->global->MAIN_ENABLE_LOG_HTML) && ! empty($_GET["log"])) - { - print "\n\n\n"; - } - } - elseif (! defined("SYSLOG_FILE_NO_ERROR")) - { - // Do not use here a call to functions that make call to dol_syslog so making call to langs. A simple print is enough. - print "Error, failed to open file ".$filelog."\n"; - } + throw new Exception('Log handler does not extend LogHandlerInterface'); } - // Check if log is to syslog (SYSLOG_SYSLOG_ON defined) - if (defined("SYSLOG_SYSLOG_ON") && constant("SYSLOG_SYSLOG_ON")) - { - if (function_exists('openlog')) // This function does not exists on some ISP (Ex: Free in France) - { - $facility = LOG_USER; - if (defined("SYSLOG_FACILITY") && constant("SYSLOG_FACILITY")) - { - // Exemple: SYSLOG_FACILITY vaut LOG_USER qui vaut 8. On a besoin de 8 dans $facility. - $facility = constant("SYSLOG_FACILITY"); - } - - openlog("dolibarr", LOG_PID | LOG_PERROR, (int) $facility); // (int) is required to avoid error parameter 3 expected to be long - if (! $level) syslog(LOG_ERR, $message); - else syslog($level, $message); - closelog(); - } - } - - // Check if log is to syslog (SYSLOG_FIREPHP_ON defined) - if (defined("SYSLOG_FIREPHP_ON") && constant("SYSLOG_FIREPHP_ON") && ! empty($_SERVER["SERVER_NAME"])) //! empty($_SERVER["SERVER_NAME"]) to be sure to enable this in Web mode only - { - try - { - // Warning FirePHPCore must be into PHP include path. It is not possible to use into require_once() a constant from - // database or config file because we must be able to log data before database or config file read. - $oldinclude=get_include_path(); - set_include_path('/usr/share/php/'); - include_once 'FirePHPCore/FirePHP.class.php'; - set_include_path($oldinclude); - ob_start(); // To be sure headers are not flushed until all page is completely processed - $firephp = FirePHP::getInstance(true); - if ($level == LOG_ERR) $firephp->error($message); - elseif ($level == LOG_WARNING) $firephp->warn($message); - elseif ($level == LOG_INFO) $firephp->log($message); - else $firephp->log($message); - } - catch(Exception $e) - { - // Do not use dol_syslog here to avoid infinite loop - } - } - // Check if log is to syslog (SYSLOG_FIREPHP_ON defined) - if (defined("SYSLOG_CHROMEPHP_ON") && constant("SYSLOG_CHROMEPHP_ON") && ! empty($_SERVER["SERVER_NAME"])) //! empty($_SERVER["SERVER_NAME"]) to be sure to enable this in Web mode only - { - try - { - // Warning ChromePHP must be into PHP include path. It is not possible to use into require_once() a constant from - // database or config file because we must be able to log data before database or config file read. - $oldinclude=get_include_path(); - set_include_path('/usr/share/php/'); - include_once 'ChromePhp.php'; - set_include_path($oldinclude); - ob_start(); // To be sure headers are not flushed until all page is completely processed - if ($level == LOG_ERR) ChromePhp::error($message); - elseif ($level == LOG_WARNING) ChromePhp::warn($message); - elseif ($level == LOG_INFO) ChromePhp::log($message); - else ChromePhp::log($message); - } - catch(Exception $e) - { - // Do not use dol_syslog here to avoid infinite loop - } - } + $class->export($data); } } diff --git a/htdocs/core/modules/syslog/logHandler.php b/htdocs/core/modules/syslog/logHandler.php new file mode 100644 index 00000000000..8825e26bb68 --- /dev/null +++ b/htdocs/core/modules/syslog/logHandler.php @@ -0,0 +1,57 @@ +trans('ChromePHPIncludePathWarning'); + } + + /** + * {@inheritDoc} + */ + public function isActive() + { + try + { + set_include_path('/usr/share/php/'); + $res = @include_once 'ChromePhp.class.php'; + restore_include_path(); + if ($res) + { + return true; + } + } + catch(Exception $e) + { + print ''."\n"; + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function configure() + { + global $langs; + + return array( + array( + 'name' => $langs->trans('IncludePath'), + 'constant' => 'SYSLOG_CHROMEPHP_INCLUDEPATH', + 'default' => '/usr/share/php', + 'attr' => 'size="40"' + ) + ); + } + + /** + * {@inheritDoc} + */ + public function checkConfiguration() + { + global $langs; + + $errors = array(); + + $oldinclude = get_include_path(); + set_include_path(SYSLOG_CHROMEPHP_INCLUDEPATH); + + if (!file_exists('ChromePhp.php')) + { + $errors[] = $langs->trans("ErrorFailedToOpenFile", 'ChromePhp.php'); + } + + set_include_path($oldinclude); + + return $errors; + } + + /** + * {@inheritDoc} + */ + public function export($content) + { + //We check the configuration to avoid showing PHP warnings + if (count($this->checkConfiguration())) return false; + + try + { + // Warning ChromePHP must be into PHP include path. It is not possible to use into require_once() a constant from + // database or config file because we must be able to log data before database or config file read. + $oldinclude=get_include_path(); + set_include_path(SYSLOG_CHROMEPHP_INCLUDEPATH); + include_once 'ChromePhp.php'; + set_include_path($oldinclude); + ob_start(); // To be sure headers are not flushed until all page is completely processed + if ($level == LOG_ERR) ChromePhp::error($message); + elseif ($level == LOG_WARNING) ChromePhp::warn($message); + elseif ($level == LOG_INFO) ChromePhp::log($message); + else ChromePhp::log($message); + } + catch (Exception $e) + { + // Do not use dol_syslog here to avoid infinite loop + } + } +} \ No newline at end of file diff --git a/htdocs/core/modules/syslog/mod_syslog_file.php b/htdocs/core/modules/syslog/mod_syslog_file.php new file mode 100644 index 00000000000..1d541dfb195 --- /dev/null +++ b/htdocs/core/modules/syslog/mod_syslog_file.php @@ -0,0 +1,121 @@ +trans('File'); + } + + /** + * {@inheritDoc} + */ + public function getVersion() + { + return self::STABLE; + } + + /** + * {@inheritDoc} + */ + public function getInfo() + { + global $langs; + + return $langs->trans('YouCanUseDOL_DATA_ROOT'); + } + + /** + * {@inheritDoc} + */ + public function isActive() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function configure() + { + global $langs; + + return array( + array( + 'name' => $langs->trans('SyslogFilename'), + 'constant' => 'SYSLOG_FILE', + 'default' => 'DOL_DATA_ROOT/dolibarr.log', + 'attr' => 'size="60"' + ) + ); + } + + /** + * {@inheritDoc} + */ + public function checkConfiguration() + { + global $langs; + + $errors = array(); + + $filename = $this->getFilename(); + + if (file_exists($filename) && is_writable($filename)) + { + dol_syslog('admin/syslog: file '.$filename); + } + else $errors[] = $langs->trans("ErrorFailedToOpenFile", $filename); + + return $errors; + } + + /** + * Return the parsed logfile path + * @return string + */ + private function getFilename() + { + return str_replace('DOL_DATA_ROOT', DOL_DATA_ROOT, SYSLOG_FILE); + } + + /** + * Export the message + * @param array $content Array containing the info about the message + */ + public function export($content) + { + $logfile = $this->getFilename(); + + if (defined("SYSLOG_FILE_NO_ERROR")) $filefd = @fopen($logfile, 'a+'); + else $filefd = fopen($logfile, 'a+'); + + if (!$filefd && ! defined("SYSLOG_FILE_NO_ERROR")) + { + throw new Exception('Failed to open log file '.$logfile); + } + + $logLevels = array( + LOG_EMERG => 'EMERG', + LOG_ALERT => 'ALERT', + LOG_CRIT => 'CRIT', + LOG_ERR => 'ERR', + LOG_WARNING => 'WARNING', + LOG_NOTICE => 'NOTICE', + LOG_INFO => 'INFO', + LOG_DEBUG => 'DEBUG' + ); + + $message = dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".sprintf("%-5s", $logLevels[$content['level']])." ".sprintf("%-15s", $content['ip'])." ".$content['message']; + + fwrite($filefd, $message."\n"); + fclose($filefd); + } +} \ No newline at end of file diff --git a/htdocs/core/modules/syslog/mod_syslog_firephp.php b/htdocs/core/modules/syslog/mod_syslog_firephp.php new file mode 100644 index 00000000000..3bc0c6afbea --- /dev/null +++ b/htdocs/core/modules/syslog/mod_syslog_firephp.php @@ -0,0 +1,124 @@ +trans('FirePHPIncludePathWarning'); + } + + /** + * {@inheritDoc} + */ + public function isActive() + { + try + { + set_include_path('/usr/share/php/'); + $res = @include_once 'FirePHPCore/FirePHP.class.php'; + restore_include_path(); + if ($res) + { + return true; + } + } + catch(Exception $e) + { + print ''."\n"; + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function configure() + { + global $langs; + + return array( + array( + 'name' => $langs->trans('IncludePath'), + 'constant' => 'SYSLOG_FIREPHP_INCLUDEPATH', + 'default' => '/usr/share/php', + 'attr' => 'size="40"' + ) + ); + } + + /** + * {@inheritDoc} + */ + public function checkConfiguration() + { + global $langs; + + $errors = array(); + + $oldinclude = get_include_path(); + set_include_path(SYSLOG_FIREPHP_INCLUDEPATH); + + if (!file_exists('FirePHPCore/FirePHP.class.php')) + { + $errors[] = $langs->trans("ErrorFailedToOpenFile", 'FirePhp.php'); + } + + set_include_path($oldinclude); + + return $errors; + } + + /** + * {@inheritDoc} + */ + public function export($content) + { + //We check the configuration to avoid showing PHP warnings + if (count($this->checkConfiguration())) return false; + + try + { + // Warning FirePHPCore must be into PHP include path. It is not possible to use into require_once() a constant from + // database or config file because we must be able to log data before database or config file read. + $oldinclude=get_include_path(); + set_include_path('/usr/share/php/'); + include_once 'FirePHPCore/FirePHP.class.php'; + set_include_path($oldinclude); + ob_start(); // To be sure headers are not flushed until all page is completely processed + $firephp = FirePHP::getInstance(true); + if ($level == LOG_ERR) $firephp->error($message); + elseif ($level == LOG_WARNING) $firephp->warn($message); + elseif ($level == LOG_INFO) $firephp->log($message); + else $firephp->log($message); + } + catch (Exception $e) + { + // Do not use dol_syslog here to avoid infinite loop + return false; + } + } +} \ No newline at end of file diff --git a/htdocs/core/modules/syslog/mod_syslog_syslog.php b/htdocs/core/modules/syslog/mod_syslog_syslog.php new file mode 100644 index 00000000000..ad83bff2803 --- /dev/null +++ b/htdocs/core/modules/syslog/mod_syslog_syslog.php @@ -0,0 +1,109 @@ +trans('OnlyWindowsLOG_USER'); + } + + /** + * {@inheritDoc} + */ + public function isActive() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function configure() + { + global $langs; + + return array( + array( + 'constant' => 'SYSLOG_FACILITY', + 'name' => $langs->trans('SyslogFacility'), + 'default' => 'LOG_USER' + ) + ); + } + + /** + * {@inheritDoc} + */ + public function checkConfiguration() + { + global $langs; + + $errors = array(); + + $facility = SYSLOG_FACILITY; + if ($facility) + { + // Only LOG_USER supported on Windows + if (! empty($_SERVER["WINDIR"])) $facility='LOG_USER'; + + dol_syslog("admin/syslog: facility ".$facility); + } + else + { + $errors[] = $langs->trans("ErrorUnknownSyslogConstant", $facility); + } + + return $errors; + } + + /** + * Export the message + * @param array $content Array containing the info about the message + */ + public function export($content) + { + // This function does not exists on some ISP (Ex: Free in France) + if (!function_exists('openlog')) + { + throw new Exception('Function openlog is not available in this server'); + } + + if (defined("SYSLOG_FACILITY") && constant("SYSLOG_FACILITY")) + { + if (constant(constant('SYSLOG_FACILITY'))) + { + $facility = constant(constant("SYSLOG_FACILITY")); + } + else $facility = LOG_USER; + } + else $facility = LOG_USER; + + // (int) is required to avoid error parameter 3 expected to be long + openlog('dolibarr', LOG_PID | LOG_PERROR, (int) $facility); + syslog($content['level'], $content['message']); + closelog(); + } +} \ No newline at end of file From 0b825b373669dbfbc0080a764cd06e620b3b8520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Tue, 16 Oct 2012 02:03:12 +0200 Subject: [PATCH 2/7] Forgot to remove unnecesary code --- patch.diff | 1121 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1121 insertions(+) create mode 100644 patch.diff diff --git a/patch.diff b/patch.diff new file mode 100644 index 00000000000..a1442bbaa46 --- /dev/null +++ b/patch.diff @@ -0,0 +1,1121 @@ +From 76025a52c78c93aa82c6a969fb63796ef7367d2d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marcos=20Garci=CC=81a?= +Date: Tue, 16 Oct 2012 01:45:11 +0200 +Subject: [PATCH] Created a modular syslog handler system I've split all log + handlers into classes so that people can make new log + handler systems without making changes to the core. + +--- + htdocs/admin/syslog.php | 268 +++++++++++---------- + htdocs/core/lib/functions.lib.php | 183 +++++--------- + htdocs/core/modules/syslog/logHandler.php | 57 +++++ + htdocs/core/modules/syslog/logHandlerInterface.php | 12 + + .../core/modules/syslog/mod_syslog_chromephp.php | 122 ++++++++++ + htdocs/core/modules/syslog/mod_syslog_file.php | 110 +++++++++ + htdocs/core/modules/syslog/mod_syslog_firephp.php | 124 ++++++++++ + htdocs/core/modules/syslog/mod_syslog_syslog.php | 109 +++++++++ + 8 files changed, 741 insertions(+), 244 deletions(-) + create mode 100644 htdocs/core/modules/syslog/logHandler.php + create mode 100644 htdocs/core/modules/syslog/logHandlerInterface.php + create mode 100644 htdocs/core/modules/syslog/mod_syslog_chromephp.php + create mode 100644 htdocs/core/modules/syslog/mod_syslog_file.php + create mode 100644 htdocs/core/modules/syslog/mod_syslog_firephp.php + create mode 100644 htdocs/core/modules/syslog/mod_syslog_syslog.php + +diff --git a/htdocs/admin/syslog.php b/htdocs/admin/syslog.php +index 5a2b347..4038418 100644 +--- a/htdocs/admin/syslog.php ++++ b/htdocs/admin/syslog.php +@@ -33,10 +33,42 @@ $langs->load("other"); + + $error=0; $mesg=''; + $action = GETPOST("action"); +-$syslog_file_on=(defined('SYSLOG_FILE_ON') && constant('SYSLOG_FILE_ON'))?1:0; +-$syslog_syslog_on=(defined('SYSLOG_SYSLOG_ON') && constant('SYSLOG_SYSLOG_ON'))?1:0; +-$syslog_firephp_on=(defined('SYSLOG_FIREPHP_ON') && constant('SYSLOG_FIREPHP_ON'))?1:0; +-$syslog_chromephp_on=(defined('SYSLOG_CHROMEPHP_ON') && constant('SYSLOG_CHROMEPHP_ON'))?1:0; ++ ++$syslogModules = array(); ++$activeModules = array(); ++ ++if (defined('SYSLOG_HANDLERS')) $activeModules = unserialize(SYSLOG_HANDLERS); ++ ++$dir = dol_buildpath('/core/modules/syslog/'); ++ ++if (is_dir($dir)) ++{ ++ $handle = opendir($dir); ++ ++ if (is_resource($handle)) ++ { ++ $var=true; ++ ++ while (($file = readdir($handle))!==false) ++ { ++ if (substr($file, 0, 11) == 'mod_syslog_' && substr($file, dol_strlen($file)-3, 3) == 'php') ++ { ++ $file = substr($file, 0, dol_strlen($file)-4); ++ ++ require_once $dir.$file.'.php'; ++ ++ $module = new $file; ++ ++ // Show modules according to features level ++ if ($module->getVersion() == $module::DEVELOPMENT && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; ++ if ($module->getVersion() == $module::EXPERIMENTAL && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; ++ ++ $syslogModules[] = $file; ++ } ++ } ++ closedir($handle); ++ } ++} + + + /* +@@ -48,71 +80,32 @@ if ($action == 'set') + { + $db->begin(); + +- $res = dolibarr_del_const($db,"SYSLOG_FILE_ON",0); +- $res = dolibarr_del_const($db,"SYSLOG_SYSLOG_ON",0); +- $res = dolibarr_del_const($db,"SYSLOG_FIREPHP_ON",0); +- $res = dolibarr_del_const($db,"SYSLOG_CHROMEPHP_ON",0); +- +- $syslog_file_on=0; +- $syslog_syslog_on=0; +- $syslog_firephp_on=0; +- $syslog_chromephp_on=0; ++ $activeModules = array(); ++ $selectedModules = (isset($_POST['SYSLOG_HANDLERS']) ? $_POST['SYSLOG_HANDLERS'] : array()); + +- if (! $error && GETPOST("filename")) ++ foreach ($selectedModules as $syslogHandler) + { +- $filename=GETPOST("filename"); +- $filelog=GETPOST("filename"); +- $filelog=preg_replace('/DOL_DATA_ROOT/i',DOL_DATA_ROOT,$filelog); +- $file=@fopen($filelog,"a+"); +- if ($file) +- { +- fclose($file); +- +- dol_syslog("admin/syslog: file ".$filename); +- $res = dolibarr_set_const($db,"SYSLOG_FILE",$filename,'chaine',0,'',0); +- if (! $res > 0) $error++; +- $syslog_file_on=GETPOST('SYSLOG_FILE_ON'); +- if (! $error) $res = dolibarr_set_const($db,"SYSLOG_FILE_ON",$syslog_file_on,'chaine',0,'',0); +- } +- else ++ if (in_array($syslogHandler, $syslogModules)) + { +- $error++; +- $mesg = "".$langs->trans("ErrorFailedToOpenFile",$filename).""; ++ $module = new $syslogHandler; ++ ++ if ($module->isActive()) ++ { ++ $activeModules[] = $syslogHandler; ++ ++ foreach ($module->configure() as $option) ++ { ++ if ($_POST[$option['constant']]) ++ { ++ dolibarr_del_const($db, $option['constant'], 0); ++ dolibarr_set_const($db, $option['constant'], $_POST[$option['constant']], 'chaine'); ++ } ++ } ++ } + } + } + +- if (! $error && GETPOST("facility")) +- { +- $facility=GETPOST("facility"); +- if (defined($_POST["facility"])) +- { +- // Only LOG_USER supported on Windows +- if (! empty($_SERVER["WINDIR"])) $facility='LOG_USER'; +- +- dol_syslog("admin/syslog: facility ".$facility); +- $res = dolibarr_set_const($db,"SYSLOG_FACILITY",$facility,'chaine',0,'',0); +- if (! $res > 0) $error++; +- $syslog_syslog_on=GETPOST('SYSLOG_SYSLOG_ON'); +- if (! $error) $res = dolibarr_set_const($db,"SYSLOG_SYSLOG_ON",$syslog_syslog_on,'chaine',0,'',0); +- } +- else +- { +- $error++; +- $mesg = "".$langs->trans("ErrorUnknownSyslogConstant",$facility).""; +- } +- } +- +- if (! $error && isset($_POST['SYSLOG_FIREPHP_ON'])) // If firephp no available, post is not present. We must keep isset here. +- { +- $syslog_firephp_on=GETPOST('SYSLOG_FIREPHP_ON'); +- if (! $error) $res = dolibarr_set_const($db,"SYSLOG_FIREPHP_ON",$syslog_firephp_on,'chaine',0,'',0); +- } +- +- if (! $error && isset($_POST['SYSLOG_CHROMEPHP_ON'])) // If chromephp no available, post is not present. We must keep isset here. +- { +- $syslog_chromephp_on=GETPOST('SYSLOG_CHROMEPHP_ON'); +- if (! $error) $res = dolibarr_set_const($db,"SYSLOG_CHROMEPHP_ON",$syslog_chromephp_on,'chaine',0,'',0); +- } ++ dolibarr_set_const($db, 'SYSLOG_HANDLERS', serialize($activeModules), 'chaine'); + + if (! $error) + { +@@ -185,71 +178,102 @@ print '\n"; + $var=true; + +-// Output to file +-$var=!$var; +-print ' '.$langs->trans("SyslogSimpleFile").''; +-print ''.$langs->trans("SyslogFilename").': '; +-print ''; +-print "".$form->textwithpicto('',$langs->trans("YouCanUseDOL_DATA_ROOT")); +-print ''; ++foreach ($syslogModules as $moduleName) ++{ ++ $module = new $moduleName; + +-// Output to syslog +-$var=!$var; +-print ' '.$langs->trans("SyslogSyslog").''; +-print ''.$langs->trans("SyslogFacility").': '; +-print ''; +-print "".$form->textwithpicto('', $langs->trans('OnlyWindowsLOG_USER')); +-print ''; ++ $var=!$var; ++ print ''; ++ print 'isActive() ? 'disabled="disabled"' : '').'> '; ++ print $module->getName().''; + +-// Output to Firebug +-try +-{ +- set_include_path('/usr/share/php/'); +- $res=@include_once 'FirePHPCore/FirePHP.class.php'; +- restore_include_path(); +- if ($res) +- { +- $var=!$var; +- print ' '.$langs->trans("FirePHP").''; +- print ''; +- print ''; +- print "".$form->textwithpicto('','FirePHP must be installed onto PHP and FirePHP plugin for Firefox must also be installed'); +- print ''; +- } +-} +-catch(Exception $e) +-{ +- // Do nothing +- print ''."\n"; +-} ++ print ''; ++ if ($module->configure()) ++ { ++ foreach ($module->configure() as $option) ++ { ++ if (defined($option['constant'])) $value = constant($option['constant']); ++ else $value = (isset($option['default']) ? $option['default'] : ''); ++ ++ print $option['name'].': '; ++ } ++ } ++ print ''; + +-// Output to Chrome +-try +-{ +- set_include_path('/usr/share/php/'); +- $res=@include_once 'ChromePhp.php'; +- restore_include_path(); +- if ($res) ++ print ''; ++ if ($module->getInfo()) + { +- $var=!$var; +- print ' '.$langs->trans("ChromePHP").''; +- print ''; +- print ''; +- print "".$form->textwithpicto('','ChromePHP must be installed onto PHP path and ChromePHP plugin for Chrome must also be installed'); +- print ''; ++ print $form->textwithpicto('', $module->getInfo()); + } ++ print ''; ++ print "\n"; + } +-catch(Exception $e) +-{ +- // Do nothing +- print ''."\n"; +-} ++ ++// // Output to file ++// $var=!$var; ++// print ' '.$langs->trans("SyslogSimpleFile").''; ++// print ''.$langs->trans("SyslogFilename").': '; ++// print ''; ++// print "".$form->textwithpicto('',$langs->trans("YouCanUseDOL_DATA_ROOT")); ++// print ''; ++ ++// // Output to syslog ++// $var=!$var; ++// print ' '.$langs->trans("SyslogSyslog").''; ++// print ''.$langs->trans("SyslogFacility").': '; ++// print ''; ++// print "".$form->textwithpicto('', $langs->trans('OnlyWindowsLOG_USER')); ++// print ''; ++ ++// // Output to Firebug ++// try ++// { ++// set_include_path('/usr/share/php/'); ++// $res=@include_once 'FirePHPCore/FirePHP.class.php'; ++// restore_include_path(); ++// if ($res) ++// { ++// $var=!$var; ++// print ' '.$langs->trans("FirePHP").''; ++// print ''; ++// print ''; ++// print "".$form->textwithpicto('','FirePHP must be installed onto PHP and FirePHP plugin for Firefox must also be installed'); ++// print ''; ++// } ++// } ++// catch(Exception $e) ++// { ++// // Do nothing ++// print ''."\n"; ++// } ++ ++// // Output to Chrome ++// try ++// { ++// set_include_path('/usr/share/php/'); ++// $res=@include_once 'ChromePhp.php'; ++// restore_include_path(); ++// if ($res) ++// { ++// $var=!$var; ++// print ' '.$langs->trans("ChromePHP").''; ++// print ''; ++// print ''; ++// print "".$form->textwithpicto('','ChromePHP must be installed onto PHP path and ChromePHP plugin for Chrome must also be installed'); ++// print ''; ++// } ++// } ++// catch(Exception $e) ++// { ++// // Do nothing ++// print ''."\n"; ++// } + + print "\n"; + print "\n"; +diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php +index c4473d0..150c7c5 100644 +--- a/htdocs/core/lib/functions.lib.php ++++ b/htdocs/core/lib/functions.lib.php +@@ -463,147 +463,86 @@ function dol_escape_htmltag($stringtoescape,$keepb=0) + * On Linux LOG_ERR=3, LOG_WARNING=4, LOG_INFO=6, LOG_DEBUG=7 + * @return void + */ +-function dol_syslog($message, $level=LOG_INFO) ++function dol_syslog($message, $level = LOG_INFO) + { +- global $conf,$user,$langs,$_REQUEST; ++ global $conf, $user, $langs; ++ ++ // If syslog module enabled ++ if (empty($conf->syslog->enabled)) return false; ++ ++ if (!defined('SYSLOG_HANDLERS') || !constant('SYSLOG_HANDLERS')) return false; ++ ++ $logLevels = array( ++ LOG_EMERG, ++ LOG_ALERT, ++ LOG_CRIT, ++ LOG_ERR, ++ LOG_WARNING, ++ LOG_NOTICE, ++ LOG_INFO, ++ LOG_DEBUG ++ ); ++ ++ if (!in_array($level, $logLevels)) ++ { ++ throw new Exception('Incorrect log level'); ++ } ++ ++ if ($level > $conf->global->SYSLOG_LEVEL) return false; + + // If adding log inside HTML page is required + if (! empty($_REQUEST['logtohtml']) && ! empty($conf->global->MAIN_LOGTOHTML)) + { +- $conf->logbuffer[]=dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".$message; ++ $conf->logbuffer[] = dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".$message; + } + +- // If syslog module enabled +- if (! empty($conf->syslog->enabled)) ++ // If enable html log tag enabled and url parameter log defined, we show output log on HTML comments ++ if (! empty($conf->global->MAIN_ENABLE_LOG_HTML) && ! empty($_GET["log"])) + { +- //print $level.' - '.$conf->global->SYSLOG_LEVEL.' - '.$conf->syslog->enabled." \n"; +- if ($level > $conf->global->SYSLOG_LEVEL) return; +- +- // Translate error message if this is an error message (rare) and langs is loaded +- if ($level == LOG_ERR) +- { +- if (is_object($langs)) +- { +- $langs->load("errors"); +- if ($message != $langs->trans($message)) $message = $langs->trans($message); +- } +- } +- +- // Add page/script name to log message +- $script=isset($_SERVER['PHP_SELF'])?basename($_SERVER['PHP_SELF'],'.php').' ':''; +- $message=$script.$message; +- +- // Add user to log message +- $login='nologin'; +- if (is_object($user) && $user->id) $login=$user->login; +- $message=sprintf("%-8s",$login)." ".$message; +- +- // Check if log is to a file (SYSLOG_FILE_ON defined) +- if (defined("SYSLOG_FILE_ON") && constant("SYSLOG_FILE_ON")) +- { +- $filelog=SYSLOG_FILE; +- $filelog=preg_replace('/DOL_DATA_ROOT/i',DOL_DATA_ROOT,$filelog); +- //print "filelog=".$filelog."\n"; +- if (defined("SYSLOG_FILE_NO_ERROR")) $file=@fopen($filelog,"a+"); +- else $file=fopen($filelog,"a+"); ++ print "\n\n\n"; ++ } + +- if ($file) +- { +- $ip='???'; // $ip contains information to identify computer that run the code +- if (! empty($_SERVER["REMOTE_ADDR"])) $ip=$_SERVER["REMOTE_ADDR"]; // In most cases. +- else if (! empty($_SERVER['SERVER_ADDR'])) $ip=$_SERVER['SERVER_ADDR']; // This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache) +- else if (! empty($_SERVER['COMPUTERNAME'])) $ip=$_SERVER['COMPUTERNAME'].(empty($_SERVER['USERNAME'])?'':'@'.$_SERVER['USERNAME']); // This is when PHP session is ran outside a web server, like from Windows command line (Not always defined, but usefull if OS defined it). +- else if (! empty($_SERVER['LOGNAME'])) $ip='???@'.$_SERVER['LOGNAME']; // This is when PHP session is ran outside a web server, like from Linux command line (Not always defined, but usefull if OS defined it). ++ $data = array( ++ 'message' => $message, ++ 'script' => (isset($_SERVER['PHP_SELF'])? basename($_SERVER['PHP_SELF'],'.php') : false), ++ 'level' => $level, ++ 'user' => ((is_object($user) && $user->id) ? $user->login : false), ++ 'ip' => false ++ ); + +- $liblevelarray=array(LOG_ERR=>'ERROR',LOG_WARNING=>'WARN',LOG_INFO=>'INFO',LOG_DEBUG=>'DEBUG'); +- $liblevel=$liblevelarray[$level]; +- if (! $liblevel) $liblevel='UNDEF'; ++ if (! empty($_SERVER["REMOTE_ADDR"])) $data['ip'] = $_SERVER['REMOTE_ADDR']; ++ // This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache) ++ else if (! empty($_SERVER['SERVER_ADDR'])) $data['ip'] = $_SERVER['SERVER_ADDR']; ++ // This is when PHP session is ran outside a web server, like from Windows command line (Not always defined, but useful if OS defined it). ++ else if (! empty($_SERVER['COMPUTERNAME'])) $data['ip'] = $_SERVER['COMPUTERNAME'].(empty($_SERVER['USERNAME'])?'':'@'.$_SERVER['USERNAME']); ++ // This is when PHP session is ran outside a web server, like from Linux command line (Not always defined, but usefull if OS defined it). ++ else if (! empty($_SERVER['LOGNAME'])) $data['ip'] = '???@'.$_SERVER['LOGNAME']; + +- $message=dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".sprintf("%-5s",$liblevel)." ".sprintf("%-15s",$ip)." ".$message; ++ //We load SYSLOG handlers ++ if (defined('SYSLOG_HANDLERS')) $handlers = unserialize(SYSLOG_HANDLERS); ++ else $handlers = array(); + +- fwrite($file,$message."\n"); +- fclose($file); +- // This is for log file, we do not change permissions ++ foreach ($handlers as $handler) ++ { ++ $file = DOL_DOCUMENT_ROOT.'/core/modules/syslog/'.$handler.'.php'; + +- // If enable html log tag enabled and url parameter log defined, we show output log on HTML comments +- if (! empty($conf->global->MAIN_ENABLE_LOG_HTML) && ! empty($_GET["log"])) +- { +- print "\n\n\n"; +- } +- } +- elseif (! defined("SYSLOG_FILE_NO_ERROR")) +- { +- // Do not use here a call to functions that make call to dol_syslog so making call to langs. A simple print is enough. +- print "Error, failed to open file ".$filelog."\n"; +- } ++ if (!file_exists($file)) ++ { ++ throw new Exception('Missing log handler'); + } + +- // Check if log is to syslog (SYSLOG_SYSLOG_ON defined) +- if (defined("SYSLOG_SYSLOG_ON") && constant("SYSLOG_SYSLOG_ON")) +- { +- if (function_exists('openlog')) // This function does not exists on some ISP (Ex: Free in France) +- { +- $facility = LOG_USER; +- if (defined("SYSLOG_FACILITY") && constant("SYSLOG_FACILITY")) +- { +- // Exemple: SYSLOG_FACILITY vaut LOG_USER qui vaut 8. On a besoin de 8 dans $facility. +- $facility = constant("SYSLOG_FACILITY"); +- } ++ require_once $file; + +- openlog("dolibarr", LOG_PID | LOG_PERROR, (int) $facility); // (int) is required to avoid error parameter 3 expected to be long +- if (! $level) syslog(LOG_ERR, $message); +- else syslog($level, $message); +- closelog(); +- } +- } ++ $class = new $handler(); + +- // Check if log is to syslog (SYSLOG_FIREPHP_ON defined) +- if (defined("SYSLOG_FIREPHP_ON") && constant("SYSLOG_FIREPHP_ON") && ! empty($_SERVER["SERVER_NAME"])) //! empty($_SERVER["SERVER_NAME"]) to be sure to enable this in Web mode only ++ if (!$class instanceof LogHandlerInterface) + { +- try +- { +- // Warning FirePHPCore must be into PHP include path. It is not possible to use into require_once() a constant from +- // database or config file because we must be able to log data before database or config file read. +- $oldinclude=get_include_path(); +- set_include_path('/usr/share/php/'); +- include_once 'FirePHPCore/FirePHP.class.php'; +- set_include_path($oldinclude); +- ob_start(); // To be sure headers are not flushed until all page is completely processed +- $firephp = FirePHP::getInstance(true); +- if ($level == LOG_ERR) $firephp->error($message); +- elseif ($level == LOG_WARNING) $firephp->warn($message); +- elseif ($level == LOG_INFO) $firephp->log($message); +- else $firephp->log($message); +- } +- catch(Exception $e) +- { +- // Do not use dol_syslog here to avoid infinite loop +- } +- } +- // Check if log is to syslog (SYSLOG_FIREPHP_ON defined) +- if (defined("SYSLOG_CHROMEPHP_ON") && constant("SYSLOG_CHROMEPHP_ON") && ! empty($_SERVER["SERVER_NAME"])) //! empty($_SERVER["SERVER_NAME"]) to be sure to enable this in Web mode only +- { +- try +- { +- // Warning ChromePHP must be into PHP include path. It is not possible to use into require_once() a constant from +- // database or config file because we must be able to log data before database or config file read. +- $oldinclude=get_include_path(); +- set_include_path('/usr/share/php/'); +- include_once 'ChromePhp.php'; +- set_include_path($oldinclude); +- ob_start(); // To be sure headers are not flushed until all page is completely processed +- if ($level == LOG_ERR) ChromePhp::error($message); +- elseif ($level == LOG_WARNING) ChromePhp::warn($message); +- elseif ($level == LOG_INFO) ChromePhp::log($message); +- else ChromePhp::log($message); +- } +- catch(Exception $e) +- { +- // Do not use dol_syslog here to avoid infinite loop +- } ++ throw new Exception('Log handler does not extend LogHandlerInterface'); + } ++ ++ $class->export($data); + } + } + +diff --git a/htdocs/core/modules/syslog/logHandler.php b/htdocs/core/modules/syslog/logHandler.php +new file mode 100644 +index 0000000..8825e26 +--- /dev/null ++++ b/htdocs/core/modules/syslog/logHandler.php +@@ -0,0 +1,57 @@ ++trans('ChromePHPIncludePathWarning'); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function isActive() ++ { ++ try ++ { ++ set_include_path('/usr/share/php/'); ++ $res = @include_once 'ChromePhp.class.php'; ++ restore_include_path(); ++ if ($res) ++ { ++ return true; ++ } ++ } ++ catch(Exception $e) ++ { ++ print ''."\n"; ++ } ++ ++ return false; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function configure() ++ { ++ global $langs; ++ ++ return array( ++ array( ++ 'name' => $langs->trans('IncludePath'), ++ 'constant' => 'SYSLOG_CHROMEPHP_INCLUDEPATH', ++ 'default' => '/usr/share/php', ++ 'attr' => 'size="40"' ++ ) ++ ); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function checkConfiguration() ++ { ++ global $langs; ++ ++ $errors = array(); ++ ++ $oldinclude = get_include_path(); ++ set_include_path(SYSLOG_CHROMEPHP_INCLUDEPATH); ++ ++ if (!file_exists('ChromePhp.php')) ++ { ++ $errors[] = $langs->trans("ErrorFailedToOpenFile", 'ChromePhp.php'); ++ } ++ ++ set_include_path($oldinclude); ++ ++ return $errors; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function export($content) ++ { ++ //We check the configuration to avoid showing PHP warnings ++ if (count($this->checkConfiguration())) return false; ++ ++ try ++ { ++ // Warning ChromePHP must be into PHP include path. It is not possible to use into require_once() a constant from ++ // database or config file because we must be able to log data before database or config file read. ++ $oldinclude=get_include_path(); ++ set_include_path(SYSLOG_CHROMEPHP_INCLUDEPATH); ++ include_once 'ChromePhp.php'; ++ set_include_path($oldinclude); ++ ob_start(); // To be sure headers are not flushed until all page is completely processed ++ if ($level == LOG_ERR) ChromePhp::error($message); ++ elseif ($level == LOG_WARNING) ChromePhp::warn($message); ++ elseif ($level == LOG_INFO) ChromePhp::log($message); ++ else ChromePhp::log($message); ++ } ++ catch (Exception $e) ++ { ++ // Do not use dol_syslog here to avoid infinite loop ++ } ++ } ++} +\ No newline at end of file +diff --git a/htdocs/core/modules/syslog/mod_syslog_file.php b/htdocs/core/modules/syslog/mod_syslog_file.php +new file mode 100644 +index 0000000..0e21610 +--- /dev/null ++++ b/htdocs/core/modules/syslog/mod_syslog_file.php +@@ -0,0 +1,110 @@ ++trans('File'); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function getVersion() ++ { ++ return self::STABLE; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function getInfo() ++ { ++ global $langs; ++ ++ return $langs->trans('YouCanUseDOL_DATA_ROOT'); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function isActive() ++ { ++ return true; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function configure() ++ { ++ global $langs; ++ ++ return array( ++ array( ++ 'name' => $langs->trans('SyslogFilename'), ++ 'constant' => 'SYSLOG_FILE', ++ 'default' => 'DOL_DATA_ROOT/dolibarr.log', ++ 'attr' => 'size="60"' ++ ) ++ ); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function checkConfiguration() ++ { ++ global $langs; ++ ++ $errors = array(); ++ ++ $filename = $this->getFilename(); ++ ++ if (file_exists($filename) && is_writable($filename)) ++ { ++ dol_syslog('admin/syslog: file '.$filename); ++ } ++ else $errors[] = $langs->trans("ErrorFailedToOpenFile", $filename); ++ ++ return $errors; ++ } ++ ++ /** ++ * Return the parsed logfile path ++ * @return string ++ */ ++ private function getFilename() ++ { ++ return str_replace('DOL_DATA_ROOT', DOL_DATA_ROOT, SYSLOG_FILE); ++ } ++ ++ /** ++ * Export the message ++ * @param array $content Array containing the info about the message ++ */ ++ public function export($content) ++ { ++ $logfile = $this->getFilename(); ++ ++ if (defined("SYSLOG_FILE_NO_ERROR")) $filefd = @fopen($logfile, 'a+'); ++ else $filefd = fopen($logfile, 'a+'); ++ ++ if (!$filefd && ! defined("SYSLOG_FILE_NO_ERROR")) ++ { ++ throw new Exception('Failed to open log file '.$logfile); ++ } ++ ++ $message = dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".sprintf("%-5s", $content['level'])." ".sprintf("%-15s", $content['ip'])." ".$content['message']; ++ ++ fwrite($filefd, $message."\n"); ++ fclose($filefd); ++ } ++} +\ No newline at end of file +diff --git a/htdocs/core/modules/syslog/mod_syslog_firephp.php b/htdocs/core/modules/syslog/mod_syslog_firephp.php +new file mode 100644 +index 0000000..3bc0c6a +--- /dev/null ++++ b/htdocs/core/modules/syslog/mod_syslog_firephp.php +@@ -0,0 +1,124 @@ ++trans('FirePHPIncludePathWarning'); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function isActive() ++ { ++ try ++ { ++ set_include_path('/usr/share/php/'); ++ $res = @include_once 'FirePHPCore/FirePHP.class.php'; ++ restore_include_path(); ++ if ($res) ++ { ++ return true; ++ } ++ } ++ catch(Exception $e) ++ { ++ print ''."\n"; ++ } ++ ++ return false; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function configure() ++ { ++ global $langs; ++ ++ return array( ++ array( ++ 'name' => $langs->trans('IncludePath'), ++ 'constant' => 'SYSLOG_FIREPHP_INCLUDEPATH', ++ 'default' => '/usr/share/php', ++ 'attr' => 'size="40"' ++ ) ++ ); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function checkConfiguration() ++ { ++ global $langs; ++ ++ $errors = array(); ++ ++ $oldinclude = get_include_path(); ++ set_include_path(SYSLOG_FIREPHP_INCLUDEPATH); ++ ++ if (!file_exists('FirePHPCore/FirePHP.class.php')) ++ { ++ $errors[] = $langs->trans("ErrorFailedToOpenFile", 'FirePhp.php'); ++ } ++ ++ set_include_path($oldinclude); ++ ++ return $errors; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function export($content) ++ { ++ //We check the configuration to avoid showing PHP warnings ++ if (count($this->checkConfiguration())) return false; ++ ++ try ++ { ++ // Warning FirePHPCore must be into PHP include path. It is not possible to use into require_once() a constant from ++ // database or config file because we must be able to log data before database or config file read. ++ $oldinclude=get_include_path(); ++ set_include_path('/usr/share/php/'); ++ include_once 'FirePHPCore/FirePHP.class.php'; ++ set_include_path($oldinclude); ++ ob_start(); // To be sure headers are not flushed until all page is completely processed ++ $firephp = FirePHP::getInstance(true); ++ if ($level == LOG_ERR) $firephp->error($message); ++ elseif ($level == LOG_WARNING) $firephp->warn($message); ++ elseif ($level == LOG_INFO) $firephp->log($message); ++ else $firephp->log($message); ++ } ++ catch (Exception $e) ++ { ++ // Do not use dol_syslog here to avoid infinite loop ++ return false; ++ } ++ } ++} +\ No newline at end of file +diff --git a/htdocs/core/modules/syslog/mod_syslog_syslog.php b/htdocs/core/modules/syslog/mod_syslog_syslog.php +new file mode 100644 +index 0000000..ad83bff +--- /dev/null ++++ b/htdocs/core/modules/syslog/mod_syslog_syslog.php +@@ -0,0 +1,109 @@ ++trans('OnlyWindowsLOG_USER'); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function isActive() ++ { ++ return true; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function configure() ++ { ++ global $langs; ++ ++ return array( ++ array( ++ 'constant' => 'SYSLOG_FACILITY', ++ 'name' => $langs->trans('SyslogFacility'), ++ 'default' => 'LOG_USER' ++ ) ++ ); ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ public function checkConfiguration() ++ { ++ global $langs; ++ ++ $errors = array(); ++ ++ $facility = SYSLOG_FACILITY; ++ if ($facility) ++ { ++ // Only LOG_USER supported on Windows ++ if (! empty($_SERVER["WINDIR"])) $facility='LOG_USER'; ++ ++ dol_syslog("admin/syslog: facility ".$facility); ++ } ++ else ++ { ++ $errors[] = $langs->trans("ErrorUnknownSyslogConstant", $facility); ++ } ++ ++ return $errors; ++ } ++ ++ /** ++ * Export the message ++ * @param array $content Array containing the info about the message ++ */ ++ public function export($content) ++ { ++ // This function does not exists on some ISP (Ex: Free in France) ++ if (!function_exists('openlog')) ++ { ++ throw new Exception('Function openlog is not available in this server'); ++ } ++ ++ if (defined("SYSLOG_FACILITY") && constant("SYSLOG_FACILITY")) ++ { ++ if (constant(constant('SYSLOG_FACILITY'))) ++ { ++ $facility = constant(constant("SYSLOG_FACILITY")); ++ } ++ else $facility = LOG_USER; ++ } ++ else $facility = LOG_USER; ++ ++ // (int) is required to avoid error parameter 3 expected to be long ++ openlog('dolibarr', LOG_PID | LOG_PERROR, (int) $facility); ++ syslog($content['level'], $content['message']); ++ closelog(); ++ } ++} +\ No newline at end of file +-- +1.7.11.3 + From f250bb41e9e70deff9946e5c04baca469787f4df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Tue, 16 Oct 2012 02:13:38 +0200 Subject: [PATCH 3/7] Removed unnecessary comments and commented unused config variables --- htdocs/admin/syslog.php | 66 ------------------- .../modules/syslog/mod_syslog_chromephp.php | 30 ++++----- .../modules/syslog/mod_syslog_firephp.php | 32 ++++----- 3 files changed, 31 insertions(+), 97 deletions(-) diff --git a/htdocs/admin/syslog.php b/htdocs/admin/syslog.php index 4038418061c..18dfabefcb0 100644 --- a/htdocs/admin/syslog.php +++ b/htdocs/admin/syslog.php @@ -209,72 +209,6 @@ foreach ($syslogModules as $moduleName) print "\n"; } -// // Output to file -// $var=!$var; -// print ' '.$langs->trans("SyslogSimpleFile").''; -// print ''.$langs->trans("SyslogFilename").': '; -// print ''; -// print "".$form->textwithpicto('',$langs->trans("YouCanUseDOL_DATA_ROOT")); -// print ''; - -// // Output to syslog -// $var=!$var; -// print ' '.$langs->trans("SyslogSyslog").''; -// print ''.$langs->trans("SyslogFacility").': '; -// print ''; -// print "".$form->textwithpicto('', $langs->trans('OnlyWindowsLOG_USER')); -// print ''; - -// // Output to Firebug -// try -// { -// set_include_path('/usr/share/php/'); -// $res=@include_once 'FirePHPCore/FirePHP.class.php'; -// restore_include_path(); -// if ($res) -// { -// $var=!$var; -// print ' '.$langs->trans("FirePHP").''; -// print ''; -// print ''; -// print "".$form->textwithpicto('','FirePHP must be installed onto PHP and FirePHP plugin for Firefox must also be installed'); -// print ''; -// } -// } -// catch(Exception $e) -// { -// // Do nothing -// print ''."\n"; -// } - -// // Output to Chrome -// try -// { -// set_include_path('/usr/share/php/'); -// $res=@include_once 'ChromePhp.php'; -// restore_include_path(); -// if ($res) -// { -// $var=!$var; -// print ' '.$langs->trans("ChromePHP").''; -// print ''; -// print ''; -// print "".$form->textwithpicto('','ChromePHP must be installed onto PHP path and ChromePHP plugin for Chrome must also be installed'); -// print ''; -// } -// } -// catch(Exception $e) -// { -// // Do nothing -// print ''."\n"; -// } - print "\n"; print "\n"; diff --git a/htdocs/core/modules/syslog/mod_syslog_chromephp.php b/htdocs/core/modules/syslog/mod_syslog_chromephp.php index 633dbfd581e..dc26fa35722 100644 --- a/htdocs/core/modules/syslog/mod_syslog_chromephp.php +++ b/htdocs/core/modules/syslog/mod_syslog_chromephp.php @@ -53,22 +53,22 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface return false; } - /** - * {@inheritDoc} - */ - public function configure() - { - global $langs; + // /** + // * {@inheritDoc} + // */ + // public function configure() + // { + // global $langs; - return array( - array( - 'name' => $langs->trans('IncludePath'), - 'constant' => 'SYSLOG_CHROMEPHP_INCLUDEPATH', - 'default' => '/usr/share/php', - 'attr' => 'size="40"' - ) - ); - } + // return array( + // array( + // 'name' => $langs->trans('IncludePath'), + // 'constant' => 'SYSLOG_CHROMEPHP_INCLUDEPATH', + // 'default' => '/usr/share/php', + // 'attr' => 'size="40"' + // ) + // ); + // } /** * {@inheritDoc} diff --git a/htdocs/core/modules/syslog/mod_syslog_firephp.php b/htdocs/core/modules/syslog/mod_syslog_firephp.php index 3bc0c6afbea..ca6396db50d 100644 --- a/htdocs/core/modules/syslog/mod_syslog_firephp.php +++ b/htdocs/core/modules/syslog/mod_syslog_firephp.php @@ -53,22 +53,22 @@ class mod_syslog_firephp extends LogHandler implements LogHandlerInterface return false; } - /** - * {@inheritDoc} - */ - public function configure() - { - global $langs; + // /** + // * {@inheritDoc} + // */ + // public function configure() + // { + // global $langs; - return array( - array( - 'name' => $langs->trans('IncludePath'), - 'constant' => 'SYSLOG_FIREPHP_INCLUDEPATH', - 'default' => '/usr/share/php', - 'attr' => 'size="40"' - ) - ); - } + // return array( + // array( + // 'name' => $langs->trans('IncludePath'), + // 'constant' => 'SYSLOG_FIREPHP_INCLUDEPATH', + // 'default' => '/usr/share/php', + // 'attr' => 'size="40"' + // ) + // ); + // } /** * {@inheritDoc} @@ -80,7 +80,7 @@ class mod_syslog_firephp extends LogHandler implements LogHandlerInterface $errors = array(); $oldinclude = get_include_path(); - set_include_path(SYSLOG_FIREPHP_INCLUDEPATH); + set_include_path('/usr/share/php/'); if (!file_exists('FirePHPCore/FirePHP.class.php')) { From 180eddff49d7105548e77fed1adc33632d09ae56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Tue, 16 Oct 2012 02:25:48 +0200 Subject: [PATCH 4/7] Because the rest of the class is using SYSLOG_CHROMEPHP_INCLUDEPATH it needs to be restored... --- .../modules/syslog/mod_syslog_chromephp.php | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/htdocs/core/modules/syslog/mod_syslog_chromephp.php b/htdocs/core/modules/syslog/mod_syslog_chromephp.php index dc26fa35722..49f6ed5299f 100644 --- a/htdocs/core/modules/syslog/mod_syslog_chromephp.php +++ b/htdocs/core/modules/syslog/mod_syslog_chromephp.php @@ -37,7 +37,7 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface { try { - set_include_path('/usr/share/php/'); + set_include_path(SYSLOG_CHROMEPHP_INCLUDEPATH); $res = @include_once 'ChromePhp.class.php'; restore_include_path(); if ($res) @@ -53,22 +53,22 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface return false; } - // /** - // * {@inheritDoc} - // */ - // public function configure() - // { - // global $langs; + /** + * {@inheritDoc} + */ + public function configure() + { + global $langs; - // return array( - // array( - // 'name' => $langs->trans('IncludePath'), - // 'constant' => 'SYSLOG_CHROMEPHP_INCLUDEPATH', - // 'default' => '/usr/share/php', - // 'attr' => 'size="40"' - // ) - // ); - // } + return array( + array( + 'name' => $langs->trans('IncludePath'), + 'constant' => 'SYSLOG_CHROMEPHP_INCLUDEPATH', + 'default' => '/usr/share/php', + 'attr' => 'size="40"' + ) + ); + } /** * {@inheritDoc} From e0200acc5f134ca6521128759a4275f53c5d4fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Tue, 16 Oct 2012 02:33:12 +0200 Subject: [PATCH 5/7] =?UTF-8?q?Sorry=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- patch.diff | 1121 ---------------------------------------------------- 1 file changed, 1121 deletions(-) delete mode 100644 patch.diff diff --git a/patch.diff b/patch.diff deleted file mode 100644 index a1442bbaa46..00000000000 --- a/patch.diff +++ /dev/null @@ -1,1121 +0,0 @@ -From 76025a52c78c93aa82c6a969fb63796ef7367d2d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marcos=20Garci=CC=81a?= -Date: Tue, 16 Oct 2012 01:45:11 +0200 -Subject: [PATCH] Created a modular syslog handler system I've split all log - handlers into classes so that people can make new log - handler systems without making changes to the core. - ---- - htdocs/admin/syslog.php | 268 +++++++++++---------- - htdocs/core/lib/functions.lib.php | 183 +++++--------- - htdocs/core/modules/syslog/logHandler.php | 57 +++++ - htdocs/core/modules/syslog/logHandlerInterface.php | 12 + - .../core/modules/syslog/mod_syslog_chromephp.php | 122 ++++++++++ - htdocs/core/modules/syslog/mod_syslog_file.php | 110 +++++++++ - htdocs/core/modules/syslog/mod_syslog_firephp.php | 124 ++++++++++ - htdocs/core/modules/syslog/mod_syslog_syslog.php | 109 +++++++++ - 8 files changed, 741 insertions(+), 244 deletions(-) - create mode 100644 htdocs/core/modules/syslog/logHandler.php - create mode 100644 htdocs/core/modules/syslog/logHandlerInterface.php - create mode 100644 htdocs/core/modules/syslog/mod_syslog_chromephp.php - create mode 100644 htdocs/core/modules/syslog/mod_syslog_file.php - create mode 100644 htdocs/core/modules/syslog/mod_syslog_firephp.php - create mode 100644 htdocs/core/modules/syslog/mod_syslog_syslog.php - -diff --git a/htdocs/admin/syslog.php b/htdocs/admin/syslog.php -index 5a2b347..4038418 100644 ---- a/htdocs/admin/syslog.php -+++ b/htdocs/admin/syslog.php -@@ -33,10 +33,42 @@ $langs->load("other"); - - $error=0; $mesg=''; - $action = GETPOST("action"); --$syslog_file_on=(defined('SYSLOG_FILE_ON') && constant('SYSLOG_FILE_ON'))?1:0; --$syslog_syslog_on=(defined('SYSLOG_SYSLOG_ON') && constant('SYSLOG_SYSLOG_ON'))?1:0; --$syslog_firephp_on=(defined('SYSLOG_FIREPHP_ON') && constant('SYSLOG_FIREPHP_ON'))?1:0; --$syslog_chromephp_on=(defined('SYSLOG_CHROMEPHP_ON') && constant('SYSLOG_CHROMEPHP_ON'))?1:0; -+ -+$syslogModules = array(); -+$activeModules = array(); -+ -+if (defined('SYSLOG_HANDLERS')) $activeModules = unserialize(SYSLOG_HANDLERS); -+ -+$dir = dol_buildpath('/core/modules/syslog/'); -+ -+if (is_dir($dir)) -+{ -+ $handle = opendir($dir); -+ -+ if (is_resource($handle)) -+ { -+ $var=true; -+ -+ while (($file = readdir($handle))!==false) -+ { -+ if (substr($file, 0, 11) == 'mod_syslog_' && substr($file, dol_strlen($file)-3, 3) == 'php') -+ { -+ $file = substr($file, 0, dol_strlen($file)-4); -+ -+ require_once $dir.$file.'.php'; -+ -+ $module = new $file; -+ -+ // Show modules according to features level -+ if ($module->getVersion() == $module::DEVELOPMENT && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; -+ if ($module->getVersion() == $module::EXPERIMENTAL && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; -+ -+ $syslogModules[] = $file; -+ } -+ } -+ closedir($handle); -+ } -+} - - - /* -@@ -48,71 +80,32 @@ if ($action == 'set') - { - $db->begin(); - -- $res = dolibarr_del_const($db,"SYSLOG_FILE_ON",0); -- $res = dolibarr_del_const($db,"SYSLOG_SYSLOG_ON",0); -- $res = dolibarr_del_const($db,"SYSLOG_FIREPHP_ON",0); -- $res = dolibarr_del_const($db,"SYSLOG_CHROMEPHP_ON",0); -- -- $syslog_file_on=0; -- $syslog_syslog_on=0; -- $syslog_firephp_on=0; -- $syslog_chromephp_on=0; -+ $activeModules = array(); -+ $selectedModules = (isset($_POST['SYSLOG_HANDLERS']) ? $_POST['SYSLOG_HANDLERS'] : array()); - -- if (! $error && GETPOST("filename")) -+ foreach ($selectedModules as $syslogHandler) - { -- $filename=GETPOST("filename"); -- $filelog=GETPOST("filename"); -- $filelog=preg_replace('/DOL_DATA_ROOT/i',DOL_DATA_ROOT,$filelog); -- $file=@fopen($filelog,"a+"); -- if ($file) -- { -- fclose($file); -- -- dol_syslog("admin/syslog: file ".$filename); -- $res = dolibarr_set_const($db,"SYSLOG_FILE",$filename,'chaine',0,'',0); -- if (! $res > 0) $error++; -- $syslog_file_on=GETPOST('SYSLOG_FILE_ON'); -- if (! $error) $res = dolibarr_set_const($db,"SYSLOG_FILE_ON",$syslog_file_on,'chaine',0,'',0); -- } -- else -+ if (in_array($syslogHandler, $syslogModules)) - { -- $error++; -- $mesg = "".$langs->trans("ErrorFailedToOpenFile",$filename).""; -+ $module = new $syslogHandler; -+ -+ if ($module->isActive()) -+ { -+ $activeModules[] = $syslogHandler; -+ -+ foreach ($module->configure() as $option) -+ { -+ if ($_POST[$option['constant']]) -+ { -+ dolibarr_del_const($db, $option['constant'], 0); -+ dolibarr_set_const($db, $option['constant'], $_POST[$option['constant']], 'chaine'); -+ } -+ } -+ } - } - } - -- if (! $error && GETPOST("facility")) -- { -- $facility=GETPOST("facility"); -- if (defined($_POST["facility"])) -- { -- // Only LOG_USER supported on Windows -- if (! empty($_SERVER["WINDIR"])) $facility='LOG_USER'; -- -- dol_syslog("admin/syslog: facility ".$facility); -- $res = dolibarr_set_const($db,"SYSLOG_FACILITY",$facility,'chaine',0,'',0); -- if (! $res > 0) $error++; -- $syslog_syslog_on=GETPOST('SYSLOG_SYSLOG_ON'); -- if (! $error) $res = dolibarr_set_const($db,"SYSLOG_SYSLOG_ON",$syslog_syslog_on,'chaine',0,'',0); -- } -- else -- { -- $error++; -- $mesg = "".$langs->trans("ErrorUnknownSyslogConstant",$facility).""; -- } -- } -- -- if (! $error && isset($_POST['SYSLOG_FIREPHP_ON'])) // If firephp no available, post is not present. We must keep isset here. -- { -- $syslog_firephp_on=GETPOST('SYSLOG_FIREPHP_ON'); -- if (! $error) $res = dolibarr_set_const($db,"SYSLOG_FIREPHP_ON",$syslog_firephp_on,'chaine',0,'',0); -- } -- -- if (! $error && isset($_POST['SYSLOG_CHROMEPHP_ON'])) // If chromephp no available, post is not present. We must keep isset here. -- { -- $syslog_chromephp_on=GETPOST('SYSLOG_CHROMEPHP_ON'); -- if (! $error) $res = dolibarr_set_const($db,"SYSLOG_CHROMEPHP_ON",$syslog_chromephp_on,'chaine',0,'',0); -- } -+ dolibarr_set_const($db, 'SYSLOG_HANDLERS', serialize($activeModules), 'chaine'); - - if (! $error) - { -@@ -185,71 +178,102 @@ print '\n"; - $var=true; - --// Output to file --$var=!$var; --print ' '.$langs->trans("SyslogSimpleFile").''; --print ''.$langs->trans("SyslogFilename").': '; --print ''; --print "".$form->textwithpicto('',$langs->trans("YouCanUseDOL_DATA_ROOT")); --print ''; -+foreach ($syslogModules as $moduleName) -+{ -+ $module = new $moduleName; - --// Output to syslog --$var=!$var; --print ' '.$langs->trans("SyslogSyslog").''; --print ''.$langs->trans("SyslogFacility").': '; --print ''; --print "".$form->textwithpicto('', $langs->trans('OnlyWindowsLOG_USER')); --print ''; -+ $var=!$var; -+ print ''; -+ print 'isActive() ? 'disabled="disabled"' : '').'> '; -+ print $module->getName().''; - --// Output to Firebug --try --{ -- set_include_path('/usr/share/php/'); -- $res=@include_once 'FirePHPCore/FirePHP.class.php'; -- restore_include_path(); -- if ($res) -- { -- $var=!$var; -- print ' '.$langs->trans("FirePHP").''; -- print ''; -- print ''; -- print "".$form->textwithpicto('','FirePHP must be installed onto PHP and FirePHP plugin for Firefox must also be installed'); -- print ''; -- } --} --catch(Exception $e) --{ -- // Do nothing -- print ''."\n"; --} -+ print ''; -+ if ($module->configure()) -+ { -+ foreach ($module->configure() as $option) -+ { -+ if (defined($option['constant'])) $value = constant($option['constant']); -+ else $value = (isset($option['default']) ? $option['default'] : ''); -+ -+ print $option['name'].': '; -+ } -+ } -+ print ''; - --// Output to Chrome --try --{ -- set_include_path('/usr/share/php/'); -- $res=@include_once 'ChromePhp.php'; -- restore_include_path(); -- if ($res) -+ print ''; -+ if ($module->getInfo()) - { -- $var=!$var; -- print ' '.$langs->trans("ChromePHP").''; -- print ''; -- print ''; -- print "".$form->textwithpicto('','ChromePHP must be installed onto PHP path and ChromePHP plugin for Chrome must also be installed'); -- print ''; -+ print $form->textwithpicto('', $module->getInfo()); - } -+ print ''; -+ print "\n"; - } --catch(Exception $e) --{ -- // Do nothing -- print ''."\n"; --} -+ -+// // Output to file -+// $var=!$var; -+// print ' '.$langs->trans("SyslogSimpleFile").''; -+// print ''.$langs->trans("SyslogFilename").': '; -+// print ''; -+// print "".$form->textwithpicto('',$langs->trans("YouCanUseDOL_DATA_ROOT")); -+// print ''; -+ -+// // Output to syslog -+// $var=!$var; -+// print ' '.$langs->trans("SyslogSyslog").''; -+// print ''.$langs->trans("SyslogFacility").': '; -+// print ''; -+// print "".$form->textwithpicto('', $langs->trans('OnlyWindowsLOG_USER')); -+// print ''; -+ -+// // Output to Firebug -+// try -+// { -+// set_include_path('/usr/share/php/'); -+// $res=@include_once 'FirePHPCore/FirePHP.class.php'; -+// restore_include_path(); -+// if ($res) -+// { -+// $var=!$var; -+// print ' '.$langs->trans("FirePHP").''; -+// print ''; -+// print ''; -+// print "".$form->textwithpicto('','FirePHP must be installed onto PHP and FirePHP plugin for Firefox must also be installed'); -+// print ''; -+// } -+// } -+// catch(Exception $e) -+// { -+// // Do nothing -+// print ''."\n"; -+// } -+ -+// // Output to Chrome -+// try -+// { -+// set_include_path('/usr/share/php/'); -+// $res=@include_once 'ChromePhp.php'; -+// restore_include_path(); -+// if ($res) -+// { -+// $var=!$var; -+// print ' '.$langs->trans("ChromePHP").''; -+// print ''; -+// print ''; -+// print "".$form->textwithpicto('','ChromePHP must be installed onto PHP path and ChromePHP plugin for Chrome must also be installed'); -+// print ''; -+// } -+// } -+// catch(Exception $e) -+// { -+// // Do nothing -+// print ''."\n"; -+// } - - print "\n"; - print "\n"; -diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php -index c4473d0..150c7c5 100644 ---- a/htdocs/core/lib/functions.lib.php -+++ b/htdocs/core/lib/functions.lib.php -@@ -463,147 +463,86 @@ function dol_escape_htmltag($stringtoescape,$keepb=0) - * On Linux LOG_ERR=3, LOG_WARNING=4, LOG_INFO=6, LOG_DEBUG=7 - * @return void - */ --function dol_syslog($message, $level=LOG_INFO) -+function dol_syslog($message, $level = LOG_INFO) - { -- global $conf,$user,$langs,$_REQUEST; -+ global $conf, $user, $langs; -+ -+ // If syslog module enabled -+ if (empty($conf->syslog->enabled)) return false; -+ -+ if (!defined('SYSLOG_HANDLERS') || !constant('SYSLOG_HANDLERS')) return false; -+ -+ $logLevels = array( -+ LOG_EMERG, -+ LOG_ALERT, -+ LOG_CRIT, -+ LOG_ERR, -+ LOG_WARNING, -+ LOG_NOTICE, -+ LOG_INFO, -+ LOG_DEBUG -+ ); -+ -+ if (!in_array($level, $logLevels)) -+ { -+ throw new Exception('Incorrect log level'); -+ } -+ -+ if ($level > $conf->global->SYSLOG_LEVEL) return false; - - // If adding log inside HTML page is required - if (! empty($_REQUEST['logtohtml']) && ! empty($conf->global->MAIN_LOGTOHTML)) - { -- $conf->logbuffer[]=dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".$message; -+ $conf->logbuffer[] = dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".$message; - } - -- // If syslog module enabled -- if (! empty($conf->syslog->enabled)) -+ // If enable html log tag enabled and url parameter log defined, we show output log on HTML comments -+ if (! empty($conf->global->MAIN_ENABLE_LOG_HTML) && ! empty($_GET["log"])) - { -- //print $level.' - '.$conf->global->SYSLOG_LEVEL.' - '.$conf->syslog->enabled." \n"; -- if ($level > $conf->global->SYSLOG_LEVEL) return; -- -- // Translate error message if this is an error message (rare) and langs is loaded -- if ($level == LOG_ERR) -- { -- if (is_object($langs)) -- { -- $langs->load("errors"); -- if ($message != $langs->trans($message)) $message = $langs->trans($message); -- } -- } -- -- // Add page/script name to log message -- $script=isset($_SERVER['PHP_SELF'])?basename($_SERVER['PHP_SELF'],'.php').' ':''; -- $message=$script.$message; -- -- // Add user to log message -- $login='nologin'; -- if (is_object($user) && $user->id) $login=$user->login; -- $message=sprintf("%-8s",$login)." ".$message; -- -- // Check if log is to a file (SYSLOG_FILE_ON defined) -- if (defined("SYSLOG_FILE_ON") && constant("SYSLOG_FILE_ON")) -- { -- $filelog=SYSLOG_FILE; -- $filelog=preg_replace('/DOL_DATA_ROOT/i',DOL_DATA_ROOT,$filelog); -- //print "filelog=".$filelog."\n"; -- if (defined("SYSLOG_FILE_NO_ERROR")) $file=@fopen($filelog,"a+"); -- else $file=fopen($filelog,"a+"); -+ print "\n\n\n"; -+ } - -- if ($file) -- { -- $ip='???'; // $ip contains information to identify computer that run the code -- if (! empty($_SERVER["REMOTE_ADDR"])) $ip=$_SERVER["REMOTE_ADDR"]; // In most cases. -- else if (! empty($_SERVER['SERVER_ADDR'])) $ip=$_SERVER['SERVER_ADDR']; // This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache) -- else if (! empty($_SERVER['COMPUTERNAME'])) $ip=$_SERVER['COMPUTERNAME'].(empty($_SERVER['USERNAME'])?'':'@'.$_SERVER['USERNAME']); // This is when PHP session is ran outside a web server, like from Windows command line (Not always defined, but usefull if OS defined it). -- else if (! empty($_SERVER['LOGNAME'])) $ip='???@'.$_SERVER['LOGNAME']; // This is when PHP session is ran outside a web server, like from Linux command line (Not always defined, but usefull if OS defined it). -+ $data = array( -+ 'message' => $message, -+ 'script' => (isset($_SERVER['PHP_SELF'])? basename($_SERVER['PHP_SELF'],'.php') : false), -+ 'level' => $level, -+ 'user' => ((is_object($user) && $user->id) ? $user->login : false), -+ 'ip' => false -+ ); - -- $liblevelarray=array(LOG_ERR=>'ERROR',LOG_WARNING=>'WARN',LOG_INFO=>'INFO',LOG_DEBUG=>'DEBUG'); -- $liblevel=$liblevelarray[$level]; -- if (! $liblevel) $liblevel='UNDEF'; -+ if (! empty($_SERVER["REMOTE_ADDR"])) $data['ip'] = $_SERVER['REMOTE_ADDR']; -+ // This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache) -+ else if (! empty($_SERVER['SERVER_ADDR'])) $data['ip'] = $_SERVER['SERVER_ADDR']; -+ // This is when PHP session is ran outside a web server, like from Windows command line (Not always defined, but useful if OS defined it). -+ else if (! empty($_SERVER['COMPUTERNAME'])) $data['ip'] = $_SERVER['COMPUTERNAME'].(empty($_SERVER['USERNAME'])?'':'@'.$_SERVER['USERNAME']); -+ // This is when PHP session is ran outside a web server, like from Linux command line (Not always defined, but usefull if OS defined it). -+ else if (! empty($_SERVER['LOGNAME'])) $data['ip'] = '???@'.$_SERVER['LOGNAME']; - -- $message=dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".sprintf("%-5s",$liblevel)." ".sprintf("%-15s",$ip)." ".$message; -+ //We load SYSLOG handlers -+ if (defined('SYSLOG_HANDLERS')) $handlers = unserialize(SYSLOG_HANDLERS); -+ else $handlers = array(); - -- fwrite($file,$message."\n"); -- fclose($file); -- // This is for log file, we do not change permissions -+ foreach ($handlers as $handler) -+ { -+ $file = DOL_DOCUMENT_ROOT.'/core/modules/syslog/'.$handler.'.php'; - -- // If enable html log tag enabled and url parameter log defined, we show output log on HTML comments -- if (! empty($conf->global->MAIN_ENABLE_LOG_HTML) && ! empty($_GET["log"])) -- { -- print "\n\n\n"; -- } -- } -- elseif (! defined("SYSLOG_FILE_NO_ERROR")) -- { -- // Do not use here a call to functions that make call to dol_syslog so making call to langs. A simple print is enough. -- print "Error, failed to open file ".$filelog."\n"; -- } -+ if (!file_exists($file)) -+ { -+ throw new Exception('Missing log handler'); - } - -- // Check if log is to syslog (SYSLOG_SYSLOG_ON defined) -- if (defined("SYSLOG_SYSLOG_ON") && constant("SYSLOG_SYSLOG_ON")) -- { -- if (function_exists('openlog')) // This function does not exists on some ISP (Ex: Free in France) -- { -- $facility = LOG_USER; -- if (defined("SYSLOG_FACILITY") && constant("SYSLOG_FACILITY")) -- { -- // Exemple: SYSLOG_FACILITY vaut LOG_USER qui vaut 8. On a besoin de 8 dans $facility. -- $facility = constant("SYSLOG_FACILITY"); -- } -+ require_once $file; - -- openlog("dolibarr", LOG_PID | LOG_PERROR, (int) $facility); // (int) is required to avoid error parameter 3 expected to be long -- if (! $level) syslog(LOG_ERR, $message); -- else syslog($level, $message); -- closelog(); -- } -- } -+ $class = new $handler(); - -- // Check if log is to syslog (SYSLOG_FIREPHP_ON defined) -- if (defined("SYSLOG_FIREPHP_ON") && constant("SYSLOG_FIREPHP_ON") && ! empty($_SERVER["SERVER_NAME"])) //! empty($_SERVER["SERVER_NAME"]) to be sure to enable this in Web mode only -+ if (!$class instanceof LogHandlerInterface) - { -- try -- { -- // Warning FirePHPCore must be into PHP include path. It is not possible to use into require_once() a constant from -- // database or config file because we must be able to log data before database or config file read. -- $oldinclude=get_include_path(); -- set_include_path('/usr/share/php/'); -- include_once 'FirePHPCore/FirePHP.class.php'; -- set_include_path($oldinclude); -- ob_start(); // To be sure headers are not flushed until all page is completely processed -- $firephp = FirePHP::getInstance(true); -- if ($level == LOG_ERR) $firephp->error($message); -- elseif ($level == LOG_WARNING) $firephp->warn($message); -- elseif ($level == LOG_INFO) $firephp->log($message); -- else $firephp->log($message); -- } -- catch(Exception $e) -- { -- // Do not use dol_syslog here to avoid infinite loop -- } -- } -- // Check if log is to syslog (SYSLOG_FIREPHP_ON defined) -- if (defined("SYSLOG_CHROMEPHP_ON") && constant("SYSLOG_CHROMEPHP_ON") && ! empty($_SERVER["SERVER_NAME"])) //! empty($_SERVER["SERVER_NAME"]) to be sure to enable this in Web mode only -- { -- try -- { -- // Warning ChromePHP must be into PHP include path. It is not possible to use into require_once() a constant from -- // database or config file because we must be able to log data before database or config file read. -- $oldinclude=get_include_path(); -- set_include_path('/usr/share/php/'); -- include_once 'ChromePhp.php'; -- set_include_path($oldinclude); -- ob_start(); // To be sure headers are not flushed until all page is completely processed -- if ($level == LOG_ERR) ChromePhp::error($message); -- elseif ($level == LOG_WARNING) ChromePhp::warn($message); -- elseif ($level == LOG_INFO) ChromePhp::log($message); -- else ChromePhp::log($message); -- } -- catch(Exception $e) -- { -- // Do not use dol_syslog here to avoid infinite loop -- } -+ throw new Exception('Log handler does not extend LogHandlerInterface'); - } -+ -+ $class->export($data); - } - } - -diff --git a/htdocs/core/modules/syslog/logHandler.php b/htdocs/core/modules/syslog/logHandler.php -new file mode 100644 -index 0000000..8825e26 ---- /dev/null -+++ b/htdocs/core/modules/syslog/logHandler.php -@@ -0,0 +1,57 @@ -+trans('ChromePHPIncludePathWarning'); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function isActive() -+ { -+ try -+ { -+ set_include_path('/usr/share/php/'); -+ $res = @include_once 'ChromePhp.class.php'; -+ restore_include_path(); -+ if ($res) -+ { -+ return true; -+ } -+ } -+ catch(Exception $e) -+ { -+ print ''."\n"; -+ } -+ -+ return false; -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function configure() -+ { -+ global $langs; -+ -+ return array( -+ array( -+ 'name' => $langs->trans('IncludePath'), -+ 'constant' => 'SYSLOG_CHROMEPHP_INCLUDEPATH', -+ 'default' => '/usr/share/php', -+ 'attr' => 'size="40"' -+ ) -+ ); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function checkConfiguration() -+ { -+ global $langs; -+ -+ $errors = array(); -+ -+ $oldinclude = get_include_path(); -+ set_include_path(SYSLOG_CHROMEPHP_INCLUDEPATH); -+ -+ if (!file_exists('ChromePhp.php')) -+ { -+ $errors[] = $langs->trans("ErrorFailedToOpenFile", 'ChromePhp.php'); -+ } -+ -+ set_include_path($oldinclude); -+ -+ return $errors; -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function export($content) -+ { -+ //We check the configuration to avoid showing PHP warnings -+ if (count($this->checkConfiguration())) return false; -+ -+ try -+ { -+ // Warning ChromePHP must be into PHP include path. It is not possible to use into require_once() a constant from -+ // database or config file because we must be able to log data before database or config file read. -+ $oldinclude=get_include_path(); -+ set_include_path(SYSLOG_CHROMEPHP_INCLUDEPATH); -+ include_once 'ChromePhp.php'; -+ set_include_path($oldinclude); -+ ob_start(); // To be sure headers are not flushed until all page is completely processed -+ if ($level == LOG_ERR) ChromePhp::error($message); -+ elseif ($level == LOG_WARNING) ChromePhp::warn($message); -+ elseif ($level == LOG_INFO) ChromePhp::log($message); -+ else ChromePhp::log($message); -+ } -+ catch (Exception $e) -+ { -+ // Do not use dol_syslog here to avoid infinite loop -+ } -+ } -+} -\ No newline at end of file -diff --git a/htdocs/core/modules/syslog/mod_syslog_file.php b/htdocs/core/modules/syslog/mod_syslog_file.php -new file mode 100644 -index 0000000..0e21610 ---- /dev/null -+++ b/htdocs/core/modules/syslog/mod_syslog_file.php -@@ -0,0 +1,110 @@ -+trans('File'); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function getVersion() -+ { -+ return self::STABLE; -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function getInfo() -+ { -+ global $langs; -+ -+ return $langs->trans('YouCanUseDOL_DATA_ROOT'); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function isActive() -+ { -+ return true; -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function configure() -+ { -+ global $langs; -+ -+ return array( -+ array( -+ 'name' => $langs->trans('SyslogFilename'), -+ 'constant' => 'SYSLOG_FILE', -+ 'default' => 'DOL_DATA_ROOT/dolibarr.log', -+ 'attr' => 'size="60"' -+ ) -+ ); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function checkConfiguration() -+ { -+ global $langs; -+ -+ $errors = array(); -+ -+ $filename = $this->getFilename(); -+ -+ if (file_exists($filename) && is_writable($filename)) -+ { -+ dol_syslog('admin/syslog: file '.$filename); -+ } -+ else $errors[] = $langs->trans("ErrorFailedToOpenFile", $filename); -+ -+ return $errors; -+ } -+ -+ /** -+ * Return the parsed logfile path -+ * @return string -+ */ -+ private function getFilename() -+ { -+ return str_replace('DOL_DATA_ROOT', DOL_DATA_ROOT, SYSLOG_FILE); -+ } -+ -+ /** -+ * Export the message -+ * @param array $content Array containing the info about the message -+ */ -+ public function export($content) -+ { -+ $logfile = $this->getFilename(); -+ -+ if (defined("SYSLOG_FILE_NO_ERROR")) $filefd = @fopen($logfile, 'a+'); -+ else $filefd = fopen($logfile, 'a+'); -+ -+ if (!$filefd && ! defined("SYSLOG_FILE_NO_ERROR")) -+ { -+ throw new Exception('Failed to open log file '.$logfile); -+ } -+ -+ $message = dol_print_date(time(),"%Y-%m-%d %H:%M:%S")." ".sprintf("%-5s", $content['level'])." ".sprintf("%-15s", $content['ip'])." ".$content['message']; -+ -+ fwrite($filefd, $message."\n"); -+ fclose($filefd); -+ } -+} -\ No newline at end of file -diff --git a/htdocs/core/modules/syslog/mod_syslog_firephp.php b/htdocs/core/modules/syslog/mod_syslog_firephp.php -new file mode 100644 -index 0000000..3bc0c6a ---- /dev/null -+++ b/htdocs/core/modules/syslog/mod_syslog_firephp.php -@@ -0,0 +1,124 @@ -+trans('FirePHPIncludePathWarning'); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function isActive() -+ { -+ try -+ { -+ set_include_path('/usr/share/php/'); -+ $res = @include_once 'FirePHPCore/FirePHP.class.php'; -+ restore_include_path(); -+ if ($res) -+ { -+ return true; -+ } -+ } -+ catch(Exception $e) -+ { -+ print ''."\n"; -+ } -+ -+ return false; -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function configure() -+ { -+ global $langs; -+ -+ return array( -+ array( -+ 'name' => $langs->trans('IncludePath'), -+ 'constant' => 'SYSLOG_FIREPHP_INCLUDEPATH', -+ 'default' => '/usr/share/php', -+ 'attr' => 'size="40"' -+ ) -+ ); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function checkConfiguration() -+ { -+ global $langs; -+ -+ $errors = array(); -+ -+ $oldinclude = get_include_path(); -+ set_include_path(SYSLOG_FIREPHP_INCLUDEPATH); -+ -+ if (!file_exists('FirePHPCore/FirePHP.class.php')) -+ { -+ $errors[] = $langs->trans("ErrorFailedToOpenFile", 'FirePhp.php'); -+ } -+ -+ set_include_path($oldinclude); -+ -+ return $errors; -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function export($content) -+ { -+ //We check the configuration to avoid showing PHP warnings -+ if (count($this->checkConfiguration())) return false; -+ -+ try -+ { -+ // Warning FirePHPCore must be into PHP include path. It is not possible to use into require_once() a constant from -+ // database or config file because we must be able to log data before database or config file read. -+ $oldinclude=get_include_path(); -+ set_include_path('/usr/share/php/'); -+ include_once 'FirePHPCore/FirePHP.class.php'; -+ set_include_path($oldinclude); -+ ob_start(); // To be sure headers are not flushed until all page is completely processed -+ $firephp = FirePHP::getInstance(true); -+ if ($level == LOG_ERR) $firephp->error($message); -+ elseif ($level == LOG_WARNING) $firephp->warn($message); -+ elseif ($level == LOG_INFO) $firephp->log($message); -+ else $firephp->log($message); -+ } -+ catch (Exception $e) -+ { -+ // Do not use dol_syslog here to avoid infinite loop -+ return false; -+ } -+ } -+} -\ No newline at end of file -diff --git a/htdocs/core/modules/syslog/mod_syslog_syslog.php b/htdocs/core/modules/syslog/mod_syslog_syslog.php -new file mode 100644 -index 0000000..ad83bff ---- /dev/null -+++ b/htdocs/core/modules/syslog/mod_syslog_syslog.php -@@ -0,0 +1,109 @@ -+trans('OnlyWindowsLOG_USER'); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function isActive() -+ { -+ return true; -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function configure() -+ { -+ global $langs; -+ -+ return array( -+ array( -+ 'constant' => 'SYSLOG_FACILITY', -+ 'name' => $langs->trans('SyslogFacility'), -+ 'default' => 'LOG_USER' -+ ) -+ ); -+ } -+ -+ /** -+ * {@inheritDoc} -+ */ -+ public function checkConfiguration() -+ { -+ global $langs; -+ -+ $errors = array(); -+ -+ $facility = SYSLOG_FACILITY; -+ if ($facility) -+ { -+ // Only LOG_USER supported on Windows -+ if (! empty($_SERVER["WINDIR"])) $facility='LOG_USER'; -+ -+ dol_syslog("admin/syslog: facility ".$facility); -+ } -+ else -+ { -+ $errors[] = $langs->trans("ErrorUnknownSyslogConstant", $facility); -+ } -+ -+ return $errors; -+ } -+ -+ /** -+ * Export the message -+ * @param array $content Array containing the info about the message -+ */ -+ public function export($content) -+ { -+ // This function does not exists on some ISP (Ex: Free in France) -+ if (!function_exists('openlog')) -+ { -+ throw new Exception('Function openlog is not available in this server'); -+ } -+ -+ if (defined("SYSLOG_FACILITY") && constant("SYSLOG_FACILITY")) -+ { -+ if (constant(constant('SYSLOG_FACILITY'))) -+ { -+ $facility = constant(constant("SYSLOG_FACILITY")); -+ } -+ else $facility = LOG_USER; -+ } -+ else $facility = LOG_USER; -+ -+ // (int) is required to avoid error parameter 3 expected to be long -+ openlog('dolibarr', LOG_PID | LOG_PERROR, (int) $facility); -+ syslog($content['level'], $content['message']); -+ closelog(); -+ } -+} -\ No newline at end of file --- -1.7.11.3 - From df2262f8be0d51709e25861ceea36140c06e5607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Tue, 16 Oct 2012 12:18:05 +0200 Subject: [PATCH 6/7] Stopped using (un)serialize functions but json functions --- htdocs/admin/syslog.php | 4 ++-- htdocs/core/lib/functions.lib.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/syslog.php b/htdocs/admin/syslog.php index 18dfabefcb0..88ebf1d9456 100644 --- a/htdocs/admin/syslog.php +++ b/htdocs/admin/syslog.php @@ -37,7 +37,7 @@ $action = GETPOST("action"); $syslogModules = array(); $activeModules = array(); -if (defined('SYSLOG_HANDLERS')) $activeModules = unserialize(SYSLOG_HANDLERS); +if (defined('SYSLOG_HANDLERS')) $activeModules = json_decode(SYSLOG_HANDLERS); $dir = dol_buildpath('/core/modules/syslog/'); @@ -105,7 +105,7 @@ if ($action == 'set') } } - dolibarr_set_const($db, 'SYSLOG_HANDLERS', serialize($activeModules), 'chaine'); + dolibarr_set_const($db, 'SYSLOG_HANDLERS', json_encode($activeModules), 'chaine'); if (! $error) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 150c7c5948d..e4d869a4287 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -521,7 +521,7 @@ function dol_syslog($message, $level = LOG_INFO) else if (! empty($_SERVER['LOGNAME'])) $data['ip'] = '???@'.$_SERVER['LOGNAME']; //We load SYSLOG handlers - if (defined('SYSLOG_HANDLERS')) $handlers = unserialize(SYSLOG_HANDLERS); + if (defined('SYSLOG_HANDLERS')) $handlers = json_decode(SYSLOG_HANDLERS); else $handlers = array(); foreach ($handlers as $handler) From ac4ee0172336b379c4074df1f3895813d417164d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Tue, 16 Oct 2012 13:39:23 +0200 Subject: [PATCH 7/7] mod_syslog_syslog class shouldn't be active if openlog is not available --- htdocs/core/modules/syslog/mod_syslog_syslog.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/syslog/mod_syslog_syslog.php b/htdocs/core/modules/syslog/mod_syslog_syslog.php index ad83bff2803..d2befc42844 100644 --- a/htdocs/core/modules/syslog/mod_syslog_syslog.php +++ b/htdocs/core/modules/syslog/mod_syslog_syslog.php @@ -35,6 +35,12 @@ class mod_syslog_syslog extends LogHandler implements LogHandlerInterface */ public function isActive() { + // This function does not exists on some ISP (Ex: Free in France) + if (!function_exists('openlog')) + { + return false; + } + return true; } @@ -85,12 +91,6 @@ class mod_syslog_syslog extends LogHandler implements LogHandlerInterface */ public function export($content) { - // This function does not exists on some ISP (Ex: Free in France) - if (!function_exists('openlog')) - { - throw new Exception('Function openlog is not available in this server'); - } - if (defined("SYSLOG_FACILITY") && constant("SYSLOG_FACILITY")) { if (constant(constant('SYSLOG_FACILITY')))