From ed884a147df25e7edc00ff7ede59c3adb763ca14 Mon Sep 17 00:00:00 2001
From: Jaime Perez Crespo <jaime.perez@uninett.no>
Date: Fri, 1 Apr 2016 16:11:07 +0200
Subject: [PATCH] Migrate all the logging handlers to namespaces. Make
 SimpleSAML\Logger a bit more intelligent so that it allows using custom
 logging handlers. Now you just need to implement
 SimpleSAML\Logger\LogginghandlerInterface in a class, and set the
 'logging.handler' option in the configuration file to a string with the full
 name of your class.

---
 lib/SimpleSAML/Logger.php                     | 58 ++++++++++---------
 ...rrorLog.php => ErrorLogLoggingHandler.php} | 52 +++++++++++------
 ...HandlerFile.php => FileLoggingHandler.php} | 34 +++++------
 ...andler.php => LoggingHandlerInterface.php} | 17 +++++-
 ...or.php => StandardErrorLoggingHandler.php} |  5 +-
 ...lerSyslog.php => SyslogLoggingHandler.php} | 20 +++----
 lib/_autoload_modules.php                     |  4 ++
 7 files changed, 113 insertions(+), 77 deletions(-)
 rename lib/SimpleSAML/Logger/{LoggingHandlerErrorLog.php => ErrorLogLoggingHandler.php} (53%)
 rename lib/SimpleSAML/Logger/{LoggingHandlerFile.php => FileLoggingHandler.php} (77%)
 rename lib/SimpleSAML/Logger/{LoggingHandler.php => LoggingHandlerInterface.php} (53%)
 rename lib/SimpleSAML/Logger/{StandardError.php => StandardErrorLoggingHandler.php} (76%)
 rename lib/SimpleSAML/Logger/{LoggingHandlerSyslog.php => SyslogLoggingHandler.php} (78%)

diff --git a/lib/SimpleSAML/Logger.php b/lib/SimpleSAML/Logger.php
index ef3127afc..7954693e7 100644
--- a/lib/SimpleSAML/Logger.php
+++ b/lib/SimpleSAML/Logger.php
@@ -84,9 +84,10 @@ class Logger
      *   about the format.
      *
      * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname'
-     *   option.
+     *   option. The SyslogLoggingHandler will just remove this.
      *
-     * - %level: the log level (name or number depending on the handler used).
+     * - %level: the log level (name or number depending on the handler used). Please note different logging handlers
+     *   will print the log level differently.
      *
      * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind
      *   the trailing space).
@@ -280,6 +281,7 @@ class Logger
      * Evaluate whether errors of a certain error level are masked or not.
      *
      * @param int $errno The level of the error to check.
+     *
      * @return bool True if the error is masked, false otherwise.
      */
     public static function isErrorMasked($errno)
@@ -324,8 +326,8 @@ class Logger
     /**
      * Defer a message for later logging.
      *
-     * @param int $level The log level corresponding to this message.
-     * @param string $message The message itself to log.
+     * @param int     $level The log level corresponding to this message.
+     * @param string  $message The message itself to log.
      * @param boolean $stats Whether this is a stats message or a regular one.
      */
     private static function defer($level, $message, $stats)
@@ -340,44 +342,48 @@ class Logger
         }
     }
 
+
     private static function createLoggingHandler($handler = null)
     {
-        // set to FALSE to indicate that it is being initialized
+        // set to false to indicate that it is being initialized
         self::$loggingHandler = false;
 
+        // a set of known logging handlers
+        $known_handlers = array(
+            'syslog'   => 'SimpleSAML\Logger\SyslogLoggingHandler',
+            'file'     => 'SimpleSAML\Logger\FileLoggingHandler',
+            'errorlog' => 'SimpleSAML\Logger\ErrorLogLoggingHandler',
+        );
+
         // get the configuration
         $config = \SimpleSAML_Configuration::getInstance();
         assert($config instanceof \SimpleSAML_Configuration);
 
+        // setting minimum log_level
+        self::$logLevel = $config->getInteger('logging.level', self::INFO);
+
         // get the metadata handler option from the configuration
         if (is_null($handler)) {
             $handler = $config->getString('logging.handler', 'syslog');
         }
 
-        // setting minimum log_level
-        self::$logLevel = $config->getInteger('logging.level', self::INFO);
-
-        $handler = strtolower($handler);
-
-        if ($handler === 'syslog') {
-            $sh = new \SimpleSAML_Logger_LoggingHandlerSyslog();
-        } elseif ($handler === 'file') {
-            $sh = new \SimpleSAML_Logger_LoggingHandlerFile();
-        } elseif ($handler === 'errorlog') {
-            $sh = new \SimpleSAML_Logger_LoggingHandlerErrorLog();
-        } elseif ($handler === 'stderr') {
-            $sh = new \SimpleSAML\Logger\StandardError();
+        if (class_exists($handler)) {
+            if (!in_array('SimpleSAML\Logger\LoggingHandlerInterface', class_implements($handler))) {
+                throw new \Exception("The logging handler '$handler' is invalid.");
+            }
         } else {
-            throw new \Exception(
-                'Invalid value for the [logging.handler] configuration option. Unknown handler: '.$handler
-            );
+            $handler = strtolower($handler);
+            if (!array_key_exists($handler, $known_handlers)) {
+                throw new \Exception(
+                    "Invalid value for the 'logging.handler' configuration option. Unknown handler '".$handler."''."
+                );
+            }
+            $handler = $known_handlers[$handler];
         }
+        self::$loggingHandler = new $handler($config);
 
         self::$format = $config->getString('logging.format', self::$format);
-        $sh->setLogFormat(self::$format);
-
-        // set the session handler
-        self::$loggingHandler = $sh;
+        self::$loggingHandler->setLogFormat(self::$format);
     }
 
 
@@ -390,7 +396,7 @@ class Logger
         } elseif (php_sapi_name() === 'cli' || defined('STDIN')) {
             // we are being executed from the CLI, nowhere to log
             if (is_null(self::$loggingHandler)) {
-                self::createLoggingHandler('stderr');
+                self::createLoggingHandler('SimpleSAML\Logger\StandardErrorLoggingHandler');
             }
             $_SERVER['REMOTE_ADDR'] = "CLI";
         } elseif (self::$loggingHandler === null) {
diff --git a/lib/SimpleSAML/Logger/LoggingHandlerErrorLog.php b/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php
similarity index 53%
rename from lib/SimpleSAML/Logger/LoggingHandlerErrorLog.php
rename to lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php
index 119027a75..845103cf2 100644
--- a/lib/SimpleSAML/Logger/LoggingHandlerErrorLog.php
+++ b/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php
@@ -1,5 +1,9 @@
 <?php
 
+namespace SimpleSAML\Logger;
+
+use SimpleSAML\Logger;
+
 /**
  * A class for logging to the default php error log.
  *
@@ -7,25 +11,41 @@
  * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
- * @version $ID$
  */
-class SimpleSAML_Logger_LoggingHandlerErrorLog implements SimpleSAML_Logger_LoggingHandler
+class ErrorLogLoggingHandler implements LoggingHandlerInterface
 {
 
     /**
-     * This array contains the mappings from syslog loglevel to names.
+     * This array contains the mappings from syslog log level to names.
      */
     private static $levelNames = array(
-        SimpleSAML\Logger::EMERG   => 'EMERG',
-        SimpleSAML\Logger::ALERT   => 'ALERT',
-        SimpleSAML\Logger::CRIT    => 'CRIT',
-        SimpleSAML\Logger::ERR     => 'ERR',
-        SimpleSAML\Logger::WARNING => 'WARNING',
-        SimpleSAML\Logger::NOTICE  => 'NOTICE',
-        SimpleSAML\Logger::INFO    => 'INFO',
-        SimpleSAML\Logger::DEBUG   => 'DEBUG',
+        Logger::EMERG   => 'EMERG',
+        Logger::ALERT   => 'ALERT',
+        Logger::CRIT    => 'CRIT',
+        Logger::ERR     => 'ERR',
+        Logger::WARNING => 'WARNING',
+        Logger::NOTICE  => 'NOTICE',
+        Logger::INFO    => 'INFO',
+        Logger::DEBUG   => 'DEBUG',
     );
-    private $format;
+
+    /**
+     * The name of this process.
+     *
+     * @var string
+     */
+    private $processname;
+
+
+    /**
+     * ErrorLogLoggingHandler constructor.
+     *
+     * @param \SimpleSAML_Configuration $config The configuration object for this handler.
+     */
+    public function __construct(\SimpleSAML_Configuration $config)
+    {
+        $this->processname = $config->getString('logging.processname', 'SimpleSAMLphp');
+    }
 
 
     /**
@@ -35,7 +55,7 @@ class SimpleSAML_Logger_LoggingHandlerErrorLog implements SimpleSAML_Logger_Logg
      */
     public function setLogFormat($format)
     {
-        $this->format = $format;
+        // we don't need the format here
     }
 
 
@@ -47,10 +67,6 @@ class SimpleSAML_Logger_LoggingHandlerErrorLog implements SimpleSAML_Logger_Logg
      */
     public function log($level, $string)
     {
-        $config = SimpleSAML_Configuration::getInstance();
-        assert($config instanceof SimpleSAML_Configuration);
-        $processname = $config->getString('logging.processname', 'SimpleSAMLphp');
-
         if (array_key_exists($level, self::$levelNames)) {
             $levelName = self::$levelNames[$level];
         } else {
@@ -58,7 +74,7 @@ class SimpleSAML_Logger_LoggingHandlerErrorLog implements SimpleSAML_Logger_Logg
         }
 
         $formats = array('%process', '%level');
-        $replacements = array($processname, $levelName);
+        $replacements = array($this->processname, $levelName);
         $string = str_replace($formats, $replacements, $string);
         $string = preg_replace('/%\w+(\{[^\}]+\})?/', '', $string);
         $string = trim($string);
diff --git a/lib/SimpleSAML/Logger/LoggingHandlerFile.php b/lib/SimpleSAML/Logger/FileLoggingHandler.php
similarity index 77%
rename from lib/SimpleSAML/Logger/LoggingHandlerFile.php
rename to lib/SimpleSAML/Logger/FileLoggingHandler.php
index e1deff7e8..a0a1280d9 100644
--- a/lib/SimpleSAML/Logger/LoggingHandlerFile.php
+++ b/lib/SimpleSAML/Logger/FileLoggingHandler.php
@@ -1,14 +1,17 @@
 <?php
 
+namespace SimpleSAML\Logger;
+
+use SimpleSAML\Logger;
 
 /**
- * A class for logging
+ * A logging handler that dumps logs to files.
  *
  * @author Lasse Birnbaum Jensen, SDU.
  * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Logger_LoggingHandlerFile implements SimpleSAML_Logger_LoggingHandler
+class FileLoggingHandler implements LoggingHandlerInterface
 {
 
     /**
@@ -23,14 +26,14 @@ class SimpleSAML_Logger_LoggingHandlerFile implements SimpleSAML_Logger_LoggingH
      * SimpleSAML_Logger_LoggingHandlerErrorLog.
      */
     private static $levelNames = array(
-        SimpleSAML\Logger::EMERG   => 'EMERGENCY',
-        SimpleSAML\Logger::ALERT   => 'ALERT',
-        SimpleSAML\Logger::CRIT    => 'CRITICAL',
-        SimpleSAML\Logger::ERR     => 'ERROR',
-        SimpleSAML\Logger::WARNING => 'WARNING',
-        SimpleSAML\Logger::NOTICE  => 'NOTICE',
-        SimpleSAML\Logger::INFO    => 'INFO',
-        SimpleSAML\Logger::DEBUG   => 'DEBUG',
+        Logger::EMERG   => 'EMERGENCY',
+        Logger::ALERT   => 'ALERT',
+        Logger::CRIT    => 'CRITICAL',
+        Logger::ERR     => 'ERROR',
+        Logger::WARNING => 'WARNING',
+        Logger::NOTICE  => 'NOTICE',
+        Logger::INFO    => 'INFO',
+        Logger::DEBUG   => 'DEBUG',
     );
     protected $processname = null;
     protected $format;
@@ -39,11 +42,8 @@ class SimpleSAML_Logger_LoggingHandlerFile implements SimpleSAML_Logger_LoggingH
     /**
      * Build a new logging handler based on files.
      */
-    public function __construct()
+    public function __construct(\SimpleSAML_Configuration $config)
     {
-        $config = SimpleSAML_Configuration::getInstance();
-        assert($config instanceof SimpleSAML_Configuration);
-
         // get the metadata handler option from the configuration
         $this->logFile = $config->getPathValue('loggingdir', 'log/').
             $config->getString('logging.logfile', 'simplesamlphp.log');
@@ -51,18 +51,18 @@ class SimpleSAML_Logger_LoggingHandlerFile implements SimpleSAML_Logger_LoggingH
 
         if (@file_exists($this->logFile)) {
             if (!@is_writeable($this->logFile)) {
-                throw new Exception("Could not write to logfile: ".$this->logFile);
+                throw new \Exception("Could not write to logfile: ".$this->logFile);
             }
         } else {
             if (!@touch($this->logFile)) {
-                throw new Exception(
+                throw new \Exception(
                     "Could not create logfile: ".$this->logFile.
                     " The logging directory is not writable for the web server user."
                 );
             }
         }
 
-        SimpleSAML\Utils\Time::initTimezone();
+        \SimpleSAML\Utils\Time::initTimezone();
     }
 
 
diff --git a/lib/SimpleSAML/Logger/LoggingHandler.php b/lib/SimpleSAML/Logger/LoggingHandlerInterface.php
similarity index 53%
rename from lib/SimpleSAML/Logger/LoggingHandler.php
rename to lib/SimpleSAML/Logger/LoggingHandlerInterface.php
index 674d5b80c..c7b00eb01 100644
--- a/lib/SimpleSAML/Logger/LoggingHandler.php
+++ b/lib/SimpleSAML/Logger/LoggingHandlerInterface.php
@@ -1,19 +1,30 @@
 <?php
+
+namespace SimpleSAML\Logger;
+
 /**
  * The interface that must be implemented by any log handler.
  *
  * @author Jaime Perez Crespo, UNINETT AS.
  * @package SimpleSAMLphp
- * @version $ID$
  */
 
-interface SimpleSAML_Logger_LoggingHandler
+interface LoggingHandlerInterface
 {
+
+    /**
+     * Constructor for log handlers. It must accept receiving a \SimpleSAML_Configuration object.
+     *
+     * @param \SimpleSAML_Configuration $config The configuration to use in this log handler.
+     */
+    public function __construct(\SimpleSAML_Configuration $config);
+
+
     /**
      * Log a message to its destination.
      *
      * @param int $level The log level.
-     * @param string $string The formatted message to log.
+     * @param string $string The message to log.
      */
     public function log($level, $string);
 
diff --git a/lib/SimpleSAML/Logger/StandardError.php b/lib/SimpleSAML/Logger/StandardErrorLoggingHandler.php
similarity index 76%
rename from lib/SimpleSAML/Logger/StandardError.php
rename to lib/SimpleSAML/Logger/StandardErrorLoggingHandler.php
index f6d07088c..0f35fcf54 100644
--- a/lib/SimpleSAML/Logger/StandardError.php
+++ b/lib/SimpleSAML/Logger/StandardErrorLoggingHandler.php
@@ -8,7 +8,7 @@ namespace SimpleSAML\Logger;
  * @author Jaime Perez Crespo, UNINETT AS <jaime.perez@uninett.no>
  * @package SimpleSAMLphp
  */
-class StandardError extends \SimpleSAML_Logger_LoggingHandlerFile
+class StandardErrorLoggingHandler extends FileLoggingHandler
 {
 
     /**
@@ -16,9 +16,8 @@ class StandardError extends \SimpleSAML_Logger_LoggingHandlerFile
      *
      * It runs the parent constructor and sets the log file to be the standard error descriptor.
      */
-    public function __construct()
+    public function __construct(\SimpleSAML_Configuration $config)
     {
-        $config = \SimpleSAML_Configuration::getInstance();
         $this->processname = $config->getString('logging.processname', 'SimpleSAMLphp');
         $this->logFile = 'php://stderr';
     }
diff --git a/lib/SimpleSAML/Logger/LoggingHandlerSyslog.php b/lib/SimpleSAML/Logger/SyslogLoggingHandler.php
similarity index 78%
rename from lib/SimpleSAML/Logger/LoggingHandlerSyslog.php
rename to lib/SimpleSAML/Logger/SyslogLoggingHandler.php
index c0a94ea22..ce2739798 100644
--- a/lib/SimpleSAML/Logger/LoggingHandlerSyslog.php
+++ b/lib/SimpleSAML/Logger/SyslogLoggingHandler.php
@@ -1,34 +1,34 @@
 <?php
 
+namespace SimpleSAML\Logger;
+
+use SimpleSAML\Utils\System;
+
 /**
- * A class for logging
+ * A logger that sends messages to syslog.
  *
  * @author Lasse Birnbaum Jensen, SDU.
  * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
- * @version $ID$
  */
-
-class SimpleSAML_Logger_LoggingHandlerSyslog implements SimpleSAML_Logger_LoggingHandler
+class SyslogLoggingHandler implements LoggingHandlerInterface
 {
-    private $isWindows = FALSE;
+    private $isWindows = false;
     private $format;
 
 
     /**
      * Build a new logging handler based on syslog.
      */
-    public function __construct()
+    public function __construct(\SimpleSAML_Configuration $config)
     {
-        $config = SimpleSAML_Configuration::getInstance();
-        assert($config instanceof SimpleSAML_Configuration);
         $facility = $config->getInteger('logging.facility', defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER);
 
         $processname = $config->getString('logging.processname', 'SimpleSAMLphp');
 
         // Setting facility to LOG_USER (only valid in Windows), enable log level rewrite on windows systems
-        if (SimpleSAML\Utils\System::getOS() === SimpleSAML\Utils\System::WINDOWS) {
-            $this->isWindows = TRUE;
+        if (System::getOS() === System::WINDOWS) {
+            $this->isWindows = true;
             $facility = LOG_USER;
         }
 
diff --git a/lib/_autoload_modules.php b/lib/_autoload_modules.php
index c60038853..c0d8befa5 100644
--- a/lib/_autoload_modules.php
+++ b/lib/_autoload_modules.php
@@ -27,6 +27,10 @@ function temporaryLoader($class)
     // list of classes that have been renamed or moved
     $renamed = array(
         'SimpleSAML_Metadata_MetaDataStorageHandlerMDX' => 'SimpleSAML_Metadata_Sources_MDQ',
+        'SimpleSAML_Logger_LoggingHandlerSyslog' => 'SimpleSAML_Logger_SyslogLoggingHandler',
+        'SimpleSAML_Logger_LoggingHandlerErrorLog' => 'SimpleSAML_Logger_ErrorLogLoggingHandler',
+        'SimpleSAML_Logger_LoggingHandlerFile' => 'SimpleSAML_Logger_FileLoggingHandler',
+        'SimpleSAML_Logger_LoggingHandler' => 'SimpleSAML_Logger_LoggingHandlerInterface',
     );
     if (array_key_exists($class, $renamed)) {
         // the class has been renamed, try to load it and create an alias
-- 
GitLab