Continued:
authorRoland Häder <roland@mxchange.org>
Sat, 18 Feb 2023 22:46:28 +0000 (23:46 +0100)
committerRoland Häder <roland@mxchange.org>
Sat, 18 Feb 2023 22:46:28 +0000 (23:46 +0100)
- rewrote logger system away from monolithic methods in BaseFrameworkSystem
  class which later allows more "backend" loggers being supported
- DebugMiddleware::output() is now private

framework/main/classes/class_BaseFrameworkSystem.php
framework/main/classes/registry/class_BaseRegistry.php
framework/main/middleware/compressor/class_CompressorChannel.php
framework/main/middleware/database/class_DatabaseConnection.php
framework/main/middleware/debug/class_DebugMiddleware.php

index c18f2bdfffded46b94b8ee2b053c9fe08a07fb7b..57f241098e74d616981d8b538b40dca24168e1c8 100644 (file)
@@ -57,6 +57,11 @@ abstract class BaseFrameworkSystem extends stdClass implements FrameworkInterfac
         */
        private static $selfInstance = NULL;
 
+       /**
+        * Debug instance
+        */
+       private static $debugInstance = NULL;
+
        /**
         * Stub methods
         */
@@ -183,7 +188,7 @@ abstract class BaseFrameworkSystem extends stdClass implements FrameworkInterfac
                        $this->setRealClass('DestructedObject');
                } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
                        // Already destructed object
-                       self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('The object <span class="object_name">%s</span> is already destroyed.',
+                       self::createDebugInstance(__CLASS__, __LINE__)->warningMessage(sprintf('The object <span class="object_name">%s</span> is already destroyed.',
                                $this->__toString()
                        ));
                } else {
@@ -289,7 +294,7 @@ abstract class BaseFrameworkSystem extends stdClass implements FrameworkInterfac
 
                // Output stub message
                // @TODO __CLASS__ does always return BaseFrameworkSystem but not the extending (=child) class
-               self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('[%s::%s]: Stub! Args: %s',
+               self::createDebugInstance(__CLASS__, __LINE__)->warningMessage(sprintf('[%s::%s]: Stub! Args: %s',
                        $className,
                        $methodName,
                        $argsString
@@ -404,7 +409,7 @@ abstract class BaseFrameworkSystem extends stdClass implements FrameworkInterfac
         * @return      $debugInstance  Instance to class DebugConsoleOutput or DebugWebOutput
         */
        public final function getDebugInstance () {
-               return GenericRegistry::getRegistry()->getInstance('debug');
+               return self::$debugInstance;
        }
 
        /**
@@ -557,7 +562,7 @@ Loaded includes:
                // Debug instance is there?
                if (!is_null($this->getDebugInstance())) {
                        // Output stub message
-                       self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($stubMessage);
+                       self::createDebugInstance(__CLASS__, __LINE__)->warningMessage($stubMessage);
                } else {
                        // Trigger an error
                        trigger_error($stubMessage);
@@ -595,38 +600,40 @@ Loaded includes:
         * @param       $className              Name of the class (currently unsupported)
         * @param       $lineNumber             Line number where the call was made
         * @return      $debugInstance  An instance of a debugger class
+        * @throws      InvalidArgumentException        If a parameter has an invalid value
         * @deprecated  Not fully, as the new Logger facilities are not finished yet.
         */
        public final static function createDebugInstance (string $className, int $lineNumber = NULL) {
                // Validate parameter
+               //* NOISY-DEBUG: */ printf('[%s:%d]: className=%s,lineNumber[%s]=%d - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $className, gettype($lineNumber), $lineNumber);
                if (empty($className)) {
                        // Throw IAE
                        throw new InvalidArgumentException('Parameter "className" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
-               } elseif (!GenericRegistry::getRegistry()->instanceExists('debug')) {
+               }
+
+               // Is the debug instance set?
+               //* NOISY-DEBUG: */ printf('[%s:%d]: self::debugInstance[]=%s' . PHP_EOL, __METHOD__, __LINE__, gettype(self::$debugInstance));
+               if (is_null(self::$debugInstance)) {
                        // Init debug instance
-                       $debugInstance = NULL;
+                       self::$debugInstance = NULL;
 
                        // Try it
                        try {
                                // Get a debugger instance
-                               $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_class'), $className);
+                               self::$debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_class'), $className);
                        } catch (NullPointerException $e) {
                                // Didn't work, no instance there
                                exit(sprintf('[%s:%d]: Cannot create debugInstance! Exception=%s,message=%s,className=%s,lineNumber=%d' . PHP_EOL, __METHOD__, __LINE__, $e->__toString(), $e->getMessage(), $className, $lineNumber));
                        }
 
                        // Empty string should be ignored and used for testing the middleware
+                       //* NOISY-DEBUG: */ printf('[%s:%d]: Invoking DebugMiddleware->selfInstance->output() ...' . PHP_EOL, __METHOD__, __LINE__);
                        DebugMiddleware::getSelfInstance()->output('');
-
-                       // Set it in registry
-                       GenericRegistry::getRegistry()->addInstance('debug', $debugInstance);
-               } else {
-                       // Get instance from registry
-                       $debugInstance = GenericRegistry::getRegistry()->getDebugInstance();
                }
 
                // Return it
-               return $debugInstance;
+               //* NOISY-DEBUG: */ printf('[%s:%d]: self::debugInstance=%s - EXIT!' . PHP_EOL, __METHOD__, __LINE__, self::$debugInstance->__toString());
+               return self::$debugInstance;
        }
 
        /**
@@ -640,77 +647,6 @@ Loaded includes:
                print($message . PHP_EOL);
        }
 
-       /**
-        * Outputs a debug message whether to debug instance (should be set!) or
-        * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
-        * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
-        *
-        * @param       $message        Message we shall send out...
-        * @param       $doPrint        Whether print or die here (default: print)
-        * @paran       $stripTags      Whether to strip tags (default: false)
-        * @return      void
-        */
-       public function debugOutput (string $message, bool $doPrint = true, bool $stripTags = false) {
-               // Set debug instance to NULL
-               $debugInstance = NULL;
-
-               // Get backtrace
-               $backtrace = debug_backtrace(!DEBUG_BACKTRACE_PROVIDE_OBJECT);
-
-               // Is function partialStub/__callStatic ?
-               if (isset(self::$stubMethods[$backtrace[1]['function']])) {
-                       // Prepend class::function:line from 3rd element
-                       $message = sprintf('[%s::%s:%d]: %s',
-                               $backtrace[2]['class'],
-                               $backtrace[2]['function'],
-                               (isset($backtrace[2]['line']) ? $backtrace[2]['line'] : '0'),
-                               $message
-                       );
-               } else {
-                       // Prepend class::function:line from 2nd element
-                       $message = sprintf('[%s::%s:%d]: %s',
-                               $backtrace[1]['class'],
-                               $backtrace[1]['function'],
-                               (isset($backtrace[1]['line']) ? $backtrace[1]['line'] : '0'),
-                               $message
-                       );
-               }
-
-               // Try it:
-               try {
-                       // Get debug instance
-                       $debugInstance = $this->getDebugInstance();
-               } catch (NullPointerException $e) {
-                       // The debug instance is not set (yet)
-               }
-
-               // Is the debug instance there?
-               if (is_object($debugInstance)) {
-                       // Use debug output handler
-                       $debugInstance->output($message, $stripTags);
-
-                       if ($doPrint === false) {
-                               // Die here if not printed
-                               exit();
-                       }
-               } else {
-                       // Are debug times enabled?
-                       if (FrameworkBootstrap::getConfigurationInstance()->isEnabled('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_output_timings')) {
-                               // Prepent it
-                               $message = $this->getPrintableExecutionTime() . $message;
-                       }
-
-                       // Put directly out
-                       if ($doPrint === true) {
-                               // Print message
-                               $this->outputLine($message);
-                       } else {
-                               // Die here
-                               exit($message);
-                       }
-               }
-       }
-
        /**
         * Marks up the code by adding e.g. line numbers
         *
@@ -758,30 +694,36 @@ Loaded includes:
         */
        protected final function getDatabaseEntry () {
                // This method is deprecated
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: CALLED!');
                $this->deprecationWarning('Monolithic method, should be moved to proper classes');
 
                // Is there an instance?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->resultInstance[]=%s', gettype($this->getResultInstance())));
                if (!$this->getResultInstance() instanceof SearchableResult) {
                        // Throw an exception here
                        throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
                }
 
                // Rewind it
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: Invoking this->resultInstance->rewind() ...');
                $this->getResultInstance()->rewind();
 
                // Do we have an entry?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->resultInstance->isValid()=%d', intval($this->getResultInstance()->isValid())));
                if ($this->getResultInstance()->valid() === false) {
                        // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available
                        throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
                }
 
                // Get next entry
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: Invoking this->resultInstance->next() ...');
                $this->getResultInstance()->next();
 
                // Fetch it
                $entry = $this->getResultInstance()->current();
 
                // And return it
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: entry[]=%s - EXIT!', gettype($entry)));
                return $entry;
        }
 
@@ -796,6 +738,7 @@ Loaded includes:
         */
        public final function getField (string $fieldName) {
                // Check parameter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName=%s - CALLED!', $fieldName));
                if (empty($fieldName)) {
                        // Throw IAE
                        throw new InvalidArgumentException('Parameter "fieldName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
@@ -811,6 +754,7 @@ Loaded includes:
                $resultInstance = $this->getResultInstance();
 
                // Is this instance null?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: resultInstance[]=%s', gettype($resultInstance)));
                if (is_null($resultInstance)) {
                        // Then the user instance is no longer valid (expired cookies?)
                        throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
@@ -818,24 +762,26 @@ Loaded includes:
 
                // Get current array
                $fieldArray = $resultInstance->current();
-               //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, true).'</pre>');
 
                // Convert dashes to underscore
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldArray()=%d', count($fieldArray)));
                $fieldName2 = StringUtils::convertDashesToUnderscores($fieldName);
 
                // Does the field exist?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName2=%s', $fieldName2));
                if ($this->isFieldSet($fieldName)) {
                        // Get it
                        $fieldValue = $fieldArray[$fieldName2];
                } elseif (FrameworkBootstrap::getConfigurationInstance()->isEnabled('developer_mode')) {
                        // Missing field entry, may require debugging
-                       self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FRAMEWORK-SYSTEM: fieldArray<pre>=' . print_r($fieldArray, true) . '</pre>,fieldName=' . $fieldName . ' not found!');
+                       self::createDebugInstance(__CLASS__, __LINE__)->warningMessage('BASE-FRAMEWORK-SYSTEM: fieldArray<pre>=' . print_r($fieldArray, true) . '</pre>,fieldName=' . $fieldName . ' not found!');
                } else {
                        // Missing field entry, may require debugging
-                       self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FRAMEWORK-SYSTEM: fieldName=' . $fieldName . ' not found!');
+                       self::createDebugInstance(__CLASS__, __LINE__)->warningMessage('BASE-FRAMEWORK-SYSTEM: fieldName=' . $fieldName . ' not found!');
                }
 
                // Return it
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldValue[]=%s - EXIT!', gettype($fieldValue)));
                return $fieldValue;
        }
 
@@ -849,6 +795,7 @@ Loaded includes:
         */
        public function isFieldSet (string $fieldName) {
                // Check parameter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName=%s - CALLED!', $fieldName));
                if (empty($fieldName)) {
                        // Throw IAE
                        throw new InvalidArgumentException('Parameter "fieldName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
@@ -858,6 +805,7 @@ Loaded includes:
                $resultInstance = $this->getResultInstance();
 
                // Is this instance null?
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: resultInstance[]=%s', gettype($resultInstance)));
                if (is_null($resultInstance)) {
                        // Then the user instance is no longer valid (expired cookies?)
                        throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
@@ -865,16 +813,18 @@ Loaded includes:
 
                // Get current array
                $fieldArray = $resultInstance->current();
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . $this->__toString() . ':' . __LINE__ . '] fieldName=' . $fieldName . ',fieldArray=<pre>'.print_r($fieldArray, true).'</pre>');
 
                // Convert dashes to underscore
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldArray()=%d,fieldName=%s - BEFORE!', count($fieldArray), $fieldName));
                $fieldName = StringUtils::convertDashesToUnderscores($fieldName);
 
                // Determine it
-               $isSet = isset($fieldArray[$fieldName]);
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName=%s - AFTER!', $fieldName));
+               $isset = isset($fieldArray[$fieldName]);
 
                // Return result
-               return $isSet;
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isset=%d - EXIT!', intval($isset)));
+               return $isset;
        }
 
        /**
@@ -890,7 +840,7 @@ Loaded includes:
                        // Debug instance is there?
                        if (!is_null($this->getDebugInstance())) {
                                // Output stub message
-                               self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($message);
+                               self::createDebugInstance(__CLASS__, __LINE__)->warningMessage($message);
                        } else {
                                // Trigger an error
                                trigger_error($message . "<br />\n");
index 9f788c1b3d0c1c097dc01f9f6b416d129d93c559..bac576c9239cd4eb549e53517e8526884454d785 100644 (file)
@@ -108,13 +108,18 @@ abstract class BaseRegistry extends BaseFrameworkSystem implements Register, Reg
         */
        public function addInstance (string $instanceKey, Registerable $objectInstance) {
                // Validate parameter
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-REGISTRY: instanceKey=%s,objectInstance=%s - CALLED!', $instanceKey, $objectInstance->__toString()));
                if (empty($instanceKey)) {
                        // Throw IAE
                        throw new InvalidArgumentExeption('Parameter "instanceKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
                }
 
                // Set entry in generic array
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-REGISTRY: Invoking this->setGenericArrayKey(registry,instance,%s,%s) ...', $instanceKey, $objectInstance->__toString()));
                $this->setGenericArrayKey('registry', 'instance', $instanceKey, $objectInstance);
+
+               // Trace message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-REGISTRY: EXIT!');
        }
 
        /**
index f72053cbfb5b0fcea5f8ca30bd1b49e702fa5928..a78bb6e82786d2d662e4e4db8d78da9cf14b6823 100644 (file)
@@ -71,10 +71,8 @@ class CompressorChannel extends BaseMiddleware implements Registerable {
 
                        // Read all directories but no sub directories, .htaccess files and NullCompressor class
                        while ($directoryEntry = $directoryInstance->readDirectoryExcept(array('class_NullCompressor.php'))) {
-                               // Debug message
-                               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('COMPRESSOR: directoryEntry=' . $directoryEntry);
-
                                // Is this a class file?
+                               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage('COMPRESSOR: directoryEntry=' . $directoryEntry);
                                if ((substr($directoryEntry, 0, 6) == 'class_') && (substr($directoryEntry, -4, 4) == '.php')) {
                                        /* Get the compressor's name. That's why you must name
                                         * your files like your classes and also that's why you
index 29e8c7c25714906d6ec6bc6d97e9099546ace7bd..38be6e7decb0bdd99f6bd46cbfbfe791f4d0a216 100644 (file)
@@ -237,13 +237,15 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re
         */
        public function removeNonPublicDataFromArray (array $data) {
                // Connect to the database
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DB-CONNECTION: data()=%d - CALLED!', count($data)));
                $this->backendInstance->connectToDatabase();
 
                // Call database backend
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DB-CONNECTION[' . $this->__toString() . ']: Invoking this->backendInstance->removeNonPublicDataFromArray(data) ...');
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('DB-CONNECTION: Invoking this->backendInstance->removeNonPublicDataFromArray(data()=%d) ...', count($data)));
                $data = $this->backendInstance->removeNonPublicDataFromArray($data);
 
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DB-CONNECTION[' . $this->__toString() . ']: data[]=' . gettype($data));
+               // Trace message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DB-CONNECTION: data()=%d - EXIT!', count($data)));
                return $data;
        }
 
@@ -256,6 +258,7 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re
         */
        public function countTotalRows (string $tableName) {
                // Validate parameter
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DB-CONNECTION: tableName=%s - CALLED!', $tableName));
                if (empty($tableName)) {
                        // Throw IAE
                        throw new InvalidArgumentException('Parameter "tableName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
@@ -268,6 +271,7 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re
                $count = $this->backendInstance->countTotalRows($tableName);
 
                // Return the value
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('DB-CONNECTION: count=%d - CALLED!', $count));
                return $count;
        }
 
index 6e4552d66e8c6f8dfefabf9c4479003c7bed8529..0f693dd57a548c3ebc92a4c0498b666745cf4904 100644 (file)
@@ -9,6 +9,9 @@ use Org\Mxchange\CoreFramework\Middleware\BaseMiddleware;
 use Org\Mxchange\CoreFramework\Registry\Registerable;
 use Org\Mxchange\CoreFramework\Stream\Output\OutputStreamer;
 
+// Import SPL stuff
+use \InvalidArgumentException;
+
 /**
  * The middlware debug output system. A *real* or concrete output class shall
  * become registered with this middleware because the back-fall class will
@@ -47,10 +50,11 @@ class DebugMiddleware extends BaseMiddleware implements Registerable {
         */
        private function __construct () {
                // Call parent constructor
+               //* NOISY-DEBUG: */ printf('[%s:%d]: CONSTRUCTED!' . PHP_EOL, __METHOD__, __LINE__);
                parent::__construct(__CLASS__);
 
-               // Set own instance
-               self::$selfInstance = $this;
+               // Trace message
+               //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
        }
 
        /**
@@ -63,36 +67,107 @@ class DebugMiddleware extends BaseMiddleware implements Registerable {
         * @param       $className              Class where a output should be created and
         *                                                      configured for
         * @return      $debugInstance  An instance of this middleware class
+        * @throws      InvalidArgumentException        If a parameter has an invalid value
         */
        public static final function createDebugMiddleware (string $outputClass, string $className) {
-               //* DEBUG-DIE: */ die(__METHOD__.': outputClass=' . $outputClass . ',className=' . $className);
-
-               // Create an instance if this middleware
-               $debugInstance = new DebugMiddleware();
+               // Check parameter
+               //* NOISY-DEBUG: */ printf('[%s:%d]: outputClass=%s,className=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $outputClass, $className);
+               if (empty($outputClass)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "outputClass" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (empty($className)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "className" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               }
 
-               // Default is that $outputClass may be invalid
-               $isInitialized = false;
+               // Is a static instance there?
+               //* NOISY-DEBUG: */ printf('[%s:%d]: self::selfInstance[]=%s' . PHP_EOL, __METHOD__, __LINE__, gettype(self::$selfInstance));
+               if (is_null(self::$selfInstance)) {
+                       // Create an instance if this middleware
+                       self::$selfInstance = new DebugMiddleware();
+               }
 
                // Is there a valid output instance provided?
-               if (class_exists($outputClass)) {
+               //* NOISY-DEBUG: */ printf('[%s:%d]: outputClass=%s' . PHP_EOL, __METHOD__, __LINE__, $outputClass);
+               if (class_exists($outputClass) && is_null(self::$selfInstance->getOutputInstance())) {
                        // A name for a debug output class has been provided so we try to get it
+                       //* NOISY-DEBUG: */ printf('[%s:%d]: Initializing outputClass=%s ...' . PHP_EOL, __METHOD__, __LINE__, $outputClass);
                        $outputInstance = ObjectFactory::createObjectByName($outputClass);
 
                        // Set this as output class
-                       $debugInstance->setOutputInstance($outputInstance);
-
-                       // All fine
-                       $isInitialized = true;
+                       //* NOISY-DEBUG: */ printf('[%s:%d]: outputInstance=%s' . PHP_EOL, __METHOD__, __LINE__, $outputInstance->__toString());
+                       self::$selfInstance->setOutputInstance($outputInstance);
                }
 
-               // Is the output class initialized?
-               if ($isInitialized === true) {
+               // Is the output class loadable and an output instance is set?
+               if (class_exists($outputClass) && !is_null(self::$selfInstance->getOutputInstance())) {
                        // Then set class name
-                       $debugInstance->getOutputInstance()->setLoggerClassName($className);
+                       //* NOISY-DEBUG: */ printf('[%s:%d]: Setting className=%s as logger class ...' . PHP_EOL, __METHOD__, __LINE__, $className);
+                       self::$selfInstance->getOutputInstance()->setLoggerClassName($className);
                }
 
                // Return instance
-               return $debugInstance;
+               //* NOISY-DEBUG: */ printf('[%s:%d]: debugInstance=%s - EXIT!' . PHP_EOL, __METHOD__, __LINE__, self::$selfInstance->__toString());
+               return self::$selfInstance;
+       }
+
+       /**
+        * This method shall send debug output which can be HTML code for the
+        * browser or debug lines for a log file, etc. to the registered debug
+        * output instance.
+        *
+        * @param       $message        Data we shall 'stream' out to the world
+        * @param       $stripTags      Whether HTML tags shall be stripped out
+        * @return      void
+        * @throws      NullPointerException    If this->outputInstance is NULL
+        */
+       private function output (string $message, bool $stripTags = false) {
+               // Is the output stream set
+               //* NOISY-DEBUG: */ printf('[%s:%d]: message=%s,stripTags=%d - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $message, intval($stripTags));
+               if (empty($message)) {
+                       // @TODO Initialization phase
+                       //* NOISY-DEBUG: */ printf('[%s:%d]: message is empty - EXIT!' . PHP_EOL, __METHOD__, __LINE__);
+                       return;
+               }
+
+               // Get backtrace
+               $backtrace = debug_backtrace(!DEBUG_BACKTRACE_PROVIDE_OBJECT);
+
+               // Is the deprecated debugOutput() or partialStub() invoked before?
+               if (isset($backtrace[4]) && $backtrace[3]['function'] == 'partialStub') {
+                       // Prepend class::function:line from 2nd element
+                       //* NOISY-DEBUG: */ printf('[%s:%d]: partialStub() was invoked ...' . PHP_EOL, __METHOD__, __LINE__);
+                       $message = sprintf('[%s::%s:%d]: %s',
+                               $backtrace[4]['class'],
+                               $backtrace[4]['function'],
+                               (isset($backtrace[4]['line']) ? $backtrace[4]['line'] : '0'),
+                               $message
+                       );
+               } elseif (isset($backtrace[3]) && $backtrace[2]['function'] == 'debugOutput') {
+                       // Prepend class::function:line from 2nd element
+                       //* NOISY-DEBUG: */ printf('[%s:%d]: debugOutput() was invoked ...' . PHP_EOL, __METHOD__, __LINE__);
+                       $message = sprintf('[%s::%s:%d]: DEPRECATED: %s',
+                               $backtrace[3]['class'],
+                               $backtrace[3]['function'],
+                               (isset($backtrace[3]['line']) ? $backtrace[3]['line'] : '0'),
+                               $message
+                       );
+               } else {
+                       // Prepend class::function:line from 2nd element
+                       //* NOISY-DEBUG: */ printf('[%s:%d]: Ordinary invocation ...' . PHP_EOL, __METHOD__, __LINE__);
+                       $message = sprintf('[%s::%s:%d]: %s',
+                               $backtrace[2]['class'],
+                               $backtrace[2]['function'],
+                               (isset($backtrace[2]['line']) ? $backtrace[2]['line'] : '0'),
+                               $message
+                       );
+               }
+
+               // Use the output instance
+               $this->getOutputInstance()->outputStream($message, $stripTags);
+
+               // Trace message
+               //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
        }
 
        /**
@@ -105,26 +180,131 @@ class DebugMiddleware extends BaseMiddleware implements Registerable {
        }
 
        /**
-        * This method shall send debug output which can be HTML code for the
-        * browser or debug lines for a log file, etc. to the registered debug
-        * output instance.
+        * Outputs a trace message whether to debug instance (should be set!) or
+        * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
+        * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
         *
-        * @param       $outStream      Data we shall 'stream' out to the world
-        * @param       $stripTags      Whether HTML tags shall be stripped out
+        * @param       $message        Message we shall send out...
+        * @param       $doPrint        Whether print or die here (default: print)
+        * @paran       $stripTags      Whether to strip tags (default: false)
         * @return      void
+        * @throws      InvalidArgumentException        If a parameter has an invalid value
+        * @throws      NullPointerException    If this->outputInstance is NULL
+        * @todo        Remove $doPrint parameter
         */
-       public final function output (string $outStream, bool $stripTags = false) {
-               // Is the output stream set
-               if (empty($outStream)) {
-                       // @TODO Initialization phase
-                       return;
+       public function traceMessage (string $message, bool $doPrint = true, bool $stripTags = false) {
+               // Check parameter
+               //* NOISY-DEBUG: */ printf('[%s:%d]: message=%s,doPrint=%d,stripTags=%d - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $message, intval($doPrint), intval($stripTags));
+               if (empty($message)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
                } elseif (is_null($this->getOutputInstance())) {
                        // Should not be NULL
                        throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
                }
 
-               // Use the output instance
-               $this->getOutputInstance()->outputStream($outStream, $stripTags);
+               // Use debug output handler
+               //* NOISY-DEBUG: */ printf('[%s:%d]: Invoking this->output(%s,%d) ...' . PHP_EOL, __METHOD__, __LINE__, $message, intval($stripTags));
+               $this->output($message, $stripTags);
+
+               // Trace message
+               //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
+       }
+
+       /**
+        * Outputs a debug message whether to debug instance (should be set!) or
+        * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
+        * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
+        *
+        * @param       $message        Message we shall send out...
+        * @param       $doPrint        Whether print or die here (default: print)
+        * @paran       $stripTags      Whether to strip tags (default: false)
+        * @return      void
+        * @throws      InvalidArgumentException        If a parameter has an invalid value
+        * @throws      NullPointerException    If this->outputInstance is NULL
+        * @todo        Remove $doPrint parameter
+        */
+       public function debugMessage (string $message, bool $doPrint = true, bool $stripTags = false) {
+               // Check parameter
+               //* NOISY-DEBUG: */ printf('[%s:%d]: message=%s,doPrint=%d,stripTags=%d - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $message, intval($doPrint), intval($stripTags));
+               if (empty($message)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (is_null($this->getOutputInstance())) {
+                       // Should not be NULL
+                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+               }
+
+               // Use debug output handler
+               //* NOISY-DEBUG: */ printf('[%s:%d]: Invoking this->output(%s,%d) ...' . PHP_EOL, __METHOD__, __LINE__, $message, intval($stripTags));
+               $this->output($message, $stripTags);
+
+               // Trace message
+               //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
+       }
+
+       /**
+        * Outputs a warning message whether to debug instance (should be set!) or
+        * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
+        * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
+        *
+        * @param       $message        Message we shall send out...
+        * @param       $doPrint        Whether print or die here (default: print)
+        * @paran       $stripTags      Whether to strip tags (default: false)
+        * @return      void
+        * @throws      InvalidArgumentException        If a parameter has an invalid value
+        * @throws      NullPointerException    If this->outputInstance is NULL
+        * @todo        Remove $doPrint parameter
+        */
+       public function warningMessage (string $message, bool $doPrint = true, bool $stripTags = false) {
+               // Check parameter
+               //* NOISY-DEBUG: */ printf('[%s:%d]: message=%s,doPrint=%d,stripTags=%d - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $message, intval($doPrint), intval($stripTags));
+               if (empty($message)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (is_null($this->getOutputInstance())) {
+                       // Should not be NULL
+                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+               }
+
+               // Use debug output handler
+               //* NOISY-DEBUG: */ printf('[%s:%d]: Invoking this->output(%s,%d) ...' . PHP_EOL, __METHOD__, __LINE__, $message, intval($stripTags));
+               $this->output($message, $stripTags);
+
+               // Trace message
+               //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
+       }
+
+       /**
+        * Outputs a debug message whether to debug instance (should be set!) or
+        * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
+        * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
+        *
+        * @param       $message        Message we shall send out...
+        * @param       $doPrint        Whether print or die here (default: print)
+        * @paran       $stripTags      Whether to strip tags (default: false)
+        * @return      void
+        * @throws      InvalidArgumentException        If a parameter has an invalid value
+        * @throws      NullPointerException    If this->outputInstance is NULL
+        * @todo        Remove $doPrint parameter
+        * @deprecated  Rewrite to "new" methods above
+        */
+       public function debugOutput (string $message, bool $doPrint = true, bool $stripTags = false) {
+               // Check parameter
+               //* NOISY-DEBUG: */ printf('[%s:%d]: message=%s,doPrint=%d,stripTags=%d - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $message, intval($doPrint), intval($stripTags));
+               if (empty($message)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (is_null($this->getOutputInstance())) {
+                       // Should not be NULL
+                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+               }
+
+               // Invoke new version
+               $this->debugMessage($message, $doPrint, $stripTags);
+
+               // Trace message
+               //* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
        }
 
 }