]> git.mxchange.org Git - friendica.git/commitdiff
Adding Develop and normal Logging instances
authorPhilipp Holzer <admin@philipp.info>
Tue, 1 Jan 2019 16:42:08 +0000 (17:42 +0100)
committerHypolite Petovan <hypolite@mrpetovan.com>
Mon, 21 Jan 2019 14:59:08 +0000 (09:59 -0500)
14 files changed:
bin/auth_ejabberd.php
bin/console.php
bin/daemon.php
bin/worker.php
index.php
src/App.php
src/App/FriendicaLoggerProcessor.php [deleted file]
src/BaseObject.php
src/Core/Addon.php
src/Core/Logger.php
src/Util/Logger/FriendicaDevelopHandler.php [new file with mode: 0644]
src/Util/LoggerFactory.php [new file with mode: 0644]
tests/src/BaseObjectTest.php
update.php

index dcc4b19591482ea443fb50176dc05dfd3a83b404..a6f30d20193275192d808dc5a9f9190d7d5f5e9e 100755 (executable)
@@ -33,8 +33,8 @@
  */
 
 use Friendica\App;
-use Friendica\Core\Logger;
 use Friendica\Util\ExAuth;
+use Friendica\Util\LoggerFactory;
 
 if (sizeof($_SERVER["argv"]) == 0) {
        die();
@@ -52,7 +52,7 @@ chdir($directory);
 
 require dirname(__DIR__) . '/vendor/autoload.php';
 
-$logger = Logger::create('ejabberd');
+$logger = LoggerFactory::create('auth_ejabberd');
 
 $a = new App(dirname(__DIR__), $logger);
 
index d783e1159f7a273a1e6e350537ae2cbc83c022bc..9264e3eee46080d294ff79fd28041340ed239942 100755 (executable)
@@ -3,9 +3,9 @@
 
 require dirname(__DIR__) . '/vendor/autoload.php';
 
-use Friendica\Core\Logger;
+use Friendica\Util\LoggerFactory;
 
-$logger = Logger::create('console');
+$logger = LoggerFactory::create('console');
 
 $a = new Friendica\App(dirname(__DIR__), $logger);
 \Friendica\BaseObject::setApp($a);
index a65502f796646fca3b25385a24d5e2dbc1402b1a..c7b321c11c3c455ab8d31fc61b48b30ee68a0ebc 100755 (executable)
@@ -9,9 +9,9 @@
 
 use Friendica\App;
 use Friendica\Core\Config;
-use Friendica\Core\Logger;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
+use Friendica\Util\LoggerFactory;
 
 // Get options
 $shortopts = 'f';
@@ -32,7 +32,7 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
 
 require dirname(__DIR__) . '/vendor/autoload.php';
 
-$logger = Logger::create('daemon');
+$logger = LoggerFactory::create('daemon');
 
 $a = new App(dirname(__DIR__), $logger);
 
index 5b5e949757fb8036230de480cd60f6a744cf74b1..a64b6a83305660f705bf5530141061ddcf379269 100755 (executable)
@@ -6,9 +6,9 @@
  */
 use Friendica\App;
 use Friendica\Core\Config;
-use Friendica\Core\Logger;
 use Friendica\Core\Worker;
 use Friendica\Core\Update;
+use Friendica\Util\LoggerFactory;
 
 // Get options
 $shortopts = 'sn';
@@ -29,7 +29,7 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
 
 require dirname(__DIR__) . '/vendor/autoload.php';
 
-$logger = Logger::create('worker');
+$logger = LoggerFactory::create('worker');
 
 $a = new App(dirname(__DIR__), $logger);
 
index d4480549d7192ac271499f053fd03b24316cad5b..c0a891bfddfed2ddf0a74949b850b6d5f421c088 100644 (file)
--- a/index.php
+++ b/index.php
@@ -5,7 +5,7 @@
  */
 
 use Friendica\App;
-use Friendica\Core\Logger;
+use Friendica\Util\LoggerFactory;
 
 if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
        die('Vendor path not found. Please execute "bin/composer.phar --no-dev install" on the command line in the web root.');
@@ -13,7 +13,7 @@ if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
 
 require __DIR__ . '/vendor/autoload.php';
 
-$logger = Logger::create('app');
+$logger = LoggerFactory::create('app');
 
 // We assume that the index.php is called by a frontend process
 // The value is set to "true" by default in App
index 793590bae43205ef14f88e6c25b8d37540ebeb20..1fb79deceacb0f9579961d564e2c140d70423a92 100644 (file)
@@ -8,10 +8,9 @@ use Detection\MobileDetect;
 use DOMDocument;
 use DOMXPath;
 use Exception;
-use Friendica\Core\Logger;
 use Friendica\Database\DBA;
 use Friendica\Network\HTTPException\InternalServerErrorException;
-use Monolog;
+use Psr\Log\LoggerInterface;
 
 /**
  *
@@ -109,7 +108,7 @@ class App
        public $mobileDetect;
 
        /**
-        * @var Monolog\Logger The current logger of this App
+        * @var LoggerInterface The current logger of this App
         */
        private $logger;
 
@@ -153,9 +152,9 @@ class App
        /**
         * @brief App constructor.
         *
-        * @param string $basePath  Path to the app base folder
-        * @param Monolog\Logger    Logger of this application
-        * @param bool   $isBackend Whether it is used for backend or frontend (Default true=backend)
+        * @param string           $basePath  Path to the app base folder
+        * @param LoggerInterface  $logger    Logger of this application
+        * @param bool             $isBackend Whether it is used for backend or frontend (Default true=backend)
         *
         * @throws Exception if the Basepath is not usable
         */
@@ -314,7 +313,7 @@ class App
        /**
         * Returns the Logger of the Application
         *
-        * @return Monolog\Logger The Logger
+        * @return LoggerInterface The Logger
         * @throws InternalServerErrorException when the logger isn't created
         */
        public function getLogger()
@@ -354,7 +353,7 @@ class App
 
                $this->process_id = Core\System::processID('log');
 
-               Logger::loadDefaultHandler($this->logger, $this);
+               Core\Logger::setLogger($this->logger);
        }
 
        /**
diff --git a/src/App/FriendicaLoggerProcessor.php b/src/App/FriendicaLoggerProcessor.php
deleted file mode 100644 (file)
index bb359c9..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-namespace Friendica\App;
-
-use Monolog\Processor\ProcessorInterface;
-
-/**
- * Includes the Friendica specific process_id of "app->process_id"
- *
- * @package Friendica\App
- */
-class FriendicaLoggerProcessor implements ProcessorInterface
-{
-       /**
-        * @var string the ID of the current Friendica process
-        */
-       private $processId = null;
-
-       /**
-        * Set the process id based on the Application instance
-        *
-        * @param string $processId the process id
-        */
-       public function setProcessId($processId)
-       {
-               if (!isset($this->processId) || $this->processId == '')
-               {
-                       $this->processId = $processId;
-               }
-       }
-
-       public function __construct()
-       {
-               $this->processId = session_id();
-       }
-
-       public function __invoke(array $records)
-       {
-               $records['extra'] = array_merge(
-                       $records['extra'],
-                       [
-                               'app_id' => $this->processId,
-                       ]
-               );
-
-               return $records;
-       }
-}
index d8d36e37b94e0cb2af2e5af0544e058d435b6c4d..39f98a38fde061d34b6ba08c75b74569745cea53 100644 (file)
@@ -6,7 +6,7 @@ namespace Friendica;
 
 require_once 'boot.php';
 
-use Friendica\Core\Logger;
+use Friendica\Util\LoggerFactory;
 
 /**
  * Basic object
@@ -27,7 +27,7 @@ class BaseObject
        public static function getApp()
        {
                if (empty(self::$app)) {
-                       $logger = Logger::create('app');
+                       $logger = $logger = LoggerFactory::create('app');
                        self::$app = new App(dirname(__DIR__), $logger);
                }
 
index a06982820e11530dd8e605789b3150d48bb3f42c..ee89f4d77235b189831072d265c40eeafad45609 100644 (file)
@@ -4,9 +4,7 @@
  */
 namespace Friendica\Core;
 
-use Friendica\App;
 use Friendica\BaseObject;
-use Friendica\Core\Logger;
 use Friendica\Database\DBA;
 
 /**
@@ -76,7 +74,7 @@ class Addon extends BaseObject
         */
        public static function uninstall($addon)
        {
-               Logger::log("Addons: uninstalling " . $addon);
+               Logger::notice("Addon {addon}: {action}", ['action' => 'uninstall', 'addon' => $addon]);
                DBA::delete('addon', ['name' => $addon]);
 
                @include_once('addon/' . $addon . '/' . $addon . '.php');
@@ -101,7 +99,7 @@ class Addon extends BaseObject
                if (!file_exists('addon/' . $addon . '/' . $addon . '.php')) {
                        return false;
                }
-               Logger::log("Addons: installing " . $addon);
+               Logger::notice("Addon {addon}: {action}", ['action' => 'install', 'addon' => $addon]);
                $t = @filemtime('addon/' . $addon . '/' . $addon . '.php');
                @include_once('addon/' . $addon . '/' . $addon . '.php');
                if (function_exists($addon . '_install')) {
@@ -126,7 +124,7 @@ class Addon extends BaseObject
                        }
                        return true;
                } else {
-                       Logger::log("Addons: FAILED installing " . $addon);
+                       Logger::error("Addon {addon}: {action} failed", ['action' => 'uninstall', 'addon' => $addon]);
                        return false;
                }
        }
@@ -156,7 +154,8 @@ class Addon extends BaseObject
                                                $t = @filemtime($fname);
                                                foreach ($installed as $i) {
                                                        if (($i['name'] == $addon) && ($i['timestamp'] != $t)) {
-                                                               Logger::log('Reloading addon: ' . $i['name']);
+
+                                                               Logger::notice("Addon {addon}: {action}", ['action' => 'reload', 'addon' => $i['name']]);
                                                                @include_once($fname);
 
                                                                if (function_exists($addon . '_uninstall')) {
index 3d5d9fb50a8bb3002a657f1c1786d2f351d76aca..6102baa5a5cb2ab73f564596494deb83a36fa669 100644 (file)
@@ -4,10 +4,11 @@
  */
 namespace Friendica\Core;
 
-use Friendica\App;
 use Friendica\BaseObject;
-use Monolog;
-use Friendica\Util\DateTimeFormat;
+use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Util\LoggerFactory;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
 
 /**
  * @brief Logger functions
@@ -15,70 +16,298 @@ use Friendica\Util\DateTimeFormat;
 class Logger extends BaseObject
 {
        /**
-        * Creates a basic Monolog instance for logging.
+        * @deprecated 2019.03 use Logger::error() instead
+        * @see Logger::error()
+        */
+       const WARNING = 0;
+       /**
+        * @deprecated 2019.03 use Logger::warning() instead
+        * @see Logger::warning()
+        */
+       const INFO = 1;
+       /**
+        * @deprecated 2019.03 use Logger::notice() instead
+        * @see Logger::notice()
+        */
+       const TRACE = 2;
+       /**
+        * @deprecated 2019.03 use Logger::info() instead
+        * @see Logger::info()
+        */
+       const DEBUG = 3;
+       /**
+        * @deprecated 2019.03 use Logger::debug() instead
+        * @see Logger::debug()
+        */
+       const DATA = 4;
+       /**
+        * @deprecated 2019.03 use Logger::debug() instead
+        * @see Logger::debug()
+        */
+       const ALL = 5;
+
+       /**
+        * @var array the legacy loglevels
+        * @deprecated 2019.03 use PSR-3 loglevels
+        * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#5-psrlogloglevel
         *
-        * @param string $application the current application name (index, daemon, ...)
+        */
+       public static $levels = [
+               self::WARNING => 'Warning',
+               self::INFO => 'Info',
+               self::TRACE => 'Trace',
+               self::DEBUG => 'Debug',
+               self::DATA => 'Data',
+               self::ALL => 'All',
+       ];
+
+       /**
+        * @var LoggerInterface A PSR-3 compliant logger instance
+        */
+       private static $logger;
+
+       /**
+        * @var LoggerInterface A PSR-3 compliant logger instance for developing only
+        */
+       private static $devLogger;
+
+       /**
+        * Sets the default logging handler for Friendica.
+        * @todo Can be combined with other handlers too if necessary, could be configurable.
+        *
+        * @param LoggerInterface $logger The Logger instance of this Application
         *
-        * @return Monolog\Logger The Logger instance
+        * @throws InternalServerErrorException if the logger factory is incompatible to this logger
         */
-       public static function create($application)
+       public static function setLogger($logger)
        {
-               $logger = new Monolog\Logger($application);
+               $debugging = Config::get('system', 'debugging');
+               $logfile = Config::get('system', 'logfile');
+               $loglevel = intval(Config::get('system', 'loglevel'));
 
-               $logger->pushProcessor(new Monolog\Processor\IntrospectionProcessor());
-               $logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
-               $logger->pushProcessor(new Monolog\Processor\WebProcessor());
-               $logger->pushProcessor(new App\FriendicaLoggerProcessor());
+               if (!$debugging || !$logfile) {
+                       return;
+               }
+
+               LoggerFactory::addStreamHandler($logger, $logfile, $loglevel);
+
+               $logfile = Config::get('system', 'dlogfile');
+
+               if (!$logfile) {
+                       return;
+               }
 
-               return $logger;
+               $developIp = Config::get('system', 'dlogip');
+
+               self::$devLogger = LoggerFactory::createDev('develop', $developIp);
+               LoggerFactory::addStreamHandler(self::$devLogger, $logfile, LogLevel::DEBUG);
        }
 
        /**
-        * Sets the default Logging handler for this instance.
-        * Can be combined with other handlers too if necessary.
+        * System is unusable.
+        * @see LoggerInterface::emergency()
+        *
+        * @param string $message
+        * @param array  $context
+        *
+        * @return void
         *
-        * @param Monolog\Logger $logger The Logger instance of this Application
-        * @param App            $app    The Friendica Application
         */
-       public static function loadDefaultHandler($logger, $app)
+       public static function emergency($message, $context = [])
        {
-               foreach ($logger->getProcessors() as $processor) {
-                       if ($processor instanceof App\FriendicaLoggerProcessor) {
-                               $processor->setProcessId($app->process_id);
-                       }
+               if (!isset(self::$logger)) {
+                       return;
                }
 
-               $debugging = Config::get('system', 'debugging');
-               $logfile   = Config::get('system', 'logfile');
-               $loglevel = intval(Config::get('system', 'loglevel'));
+               $stamp1 = microtime(true);
+               self::$logger->emergency($message, $context);
+               self::getApp()->saveTimestamp($stamp1, 'file');
+       }
 
-               if (!$debugging || !$logfile) {
+       /**
+        * Action must be taken immediately.
+        * @see LoggerInterface::alert()
+        *
+        * Example: Entire website down, database unavailable, etc. This should
+        * trigger the SMS alerts and wake you up.
+        *
+        * @param string $message
+        * @param array  $context
+        *
+        * @return void
+        *
+        */
+       public static function alert($message, $context = [])
+       {
+               if (!isset(self::$logger)) {
+                       return;
+               }
+
+               $stamp1 = microtime(true);
+               self::$logger->alert($message, $context);
+               self::getApp()->saveTimestamp($stamp1, 'file');
+       }
+
+       /**
+        * Critical conditions.
+        * @see LoggerInterface::critical()
+        *
+        * Example: Application component unavailable, unexpected exception.
+        *
+        * @param string $message
+        * @param array  $context
+        *
+        * @return void
+        *
+        */
+       public static function critical($message, $context = [])
+       {
+               if (!isset(self::$logger)) {
                        return;
                }
 
-               $fileHandler = new Monolog\Handler\StreamHandler($logfile . ".1", $loglevel);
-               $logger->pushHandler($fileHandler);
+               $stamp1 = microtime(true);
+               self::$logger->critical($message, $context);
+               self::getApp()->saveTimestamp($stamp1, 'file');
        }
 
-    // Log levels:
-       //EMERGENCY
-       //ALERT
-       //CRITICAL
-    const WARNING = 0; //ERROR
-    const INFO = 1; //WARNING
-    const TRACE = 2; //NOTICE(default)
-    const DEBUG = 3; //INFO
-    const DATA = 4; //INFO
-    const ALL = 5; //DEBUG
-
-    public static $levels = [
-        self::WARNING => 'Warning',
-        self::INFO => 'Info',
-        self::TRACE => 'Trace',
-        self::DEBUG => 'Debug',
-        self::DATA => 'Data',
-        self::ALL => 'All',
-    ];
+       /**
+        * Runtime errors that do not require immediate action but should typically
+        * be logged and monitored.
+        * @see LoggerInterface::error()
+        *
+        * @param string $message
+        * @param array  $context
+        *
+        * @return void
+        *
+        */
+       public static function error($message, $context = [])
+       {
+               if (!isset(self::$logger)) {
+                       return;
+               }
+
+               $stamp1 = microtime(true);
+               self::$logger->error($message, $context);
+               self::getApp()->saveTimestamp($stamp1, 'file');
+       }
+
+       /**
+        * Exceptional occurrences that are not errors.
+        * @see LoggerInterface::warning()
+        *
+        * Example: Use of deprecated APIs, poor use of an API, undesirable things
+        * that are not necessarily wrong.
+        *
+        * @param string $message
+        * @param array  $context
+        *
+        * @return void
+        *
+        */
+       public static function warning($message, $context = [])
+       {
+               if (!isset(self::$logger)) {
+                       return;
+               }
+
+               $stamp1 = microtime(true);
+               self::$logger->warning($message, $context);
+               self::getApp()->saveTimestamp($stamp1, 'file');
+       }
+
+       /**
+        * Normal but significant events.
+        * @see LoggerInterface::notice()
+        *
+        * @param string $message
+        * @param array  $context
+        *
+        * @return void
+        *
+        */
+       public static function notice($message, $context = [])
+       {
+               if (!isset(self::$logger)) {
+                       return;
+               }
+
+               $stamp1 = microtime(true);
+               self::$logger->notice($message, $context);
+               self::getApp()->saveTimestamp($stamp1, 'file');
+       }
+
+       /**
+        * Interesting events.
+        * @see LoggerInterface::info()
+        *
+        * Example: User logs in, SQL logs.
+        *
+        * @param string $message
+        * @param array  $context
+        *
+        * @return void
+        *
+        */
+       public static function info($message, $context = [])
+       {
+               if (!isset(self::$logger)) {
+                       return;
+               }
+
+               $stamp1 = microtime(true);
+               self::$logger->info($message, $context);
+               self::getApp()->saveTimestamp($stamp1, 'file');
+       }
+
+       /**
+        * Detailed debug information.
+        * @see LoggerInterface::debug()
+        *
+        * @param string $message
+        * @param array  $context
+        *
+        * @return void
+        */
+       public static function debug($message, $context = [])
+       {
+               if (!isset(self::$logger)) {
+                       return;
+               }
+
+               $stamp1 = microtime(true);
+               self::$logger->debug($message, $context);
+               self::getApp()->saveTimestamp($stamp1, 'file');
+       }
+
+       /**
+        * Mapping a legacy level to the PSR-3 compliant levels
+        * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#5-psrlogloglevel
+        *
+        * @param int $level the level to be mapped
+        *
+        * @return string the PSR-3 compliant level
+        */
+       private static function mapPSR3Level($level)
+       {
+               switch ($level) {
+                       case self::WARNING:
+                               return LogLevel::ERROR;
+                       case self::INFO:
+                               return LogLevel::WARNING;
+                       case self::TRACE:
+                               return LogLevel::NOTICE;
+                       case self::DEBUG:
+                               return LogLevel::INFO;
+                       case self::DATA:
+                               return LogLevel::DEBUG;
+                       case self::ALL:
+                               return LogLevel::DEBUG;
+                       default:
+                               return LogLevel::CRITICAL;
+               }
+       }
 
     /**
      * @brief Logs the given message at the given log level
@@ -86,52 +315,19 @@ class Logger extends BaseObject
      * @param string $msg
      * @param int $level
         *
-        * @deprecated since 2019.03 - use App->getLogger() instead
+        * @deprecated since 2019.03 Use Logger::debug() Logger::info() , ... instead
      */
     public static function log($msg, $level = self::INFO)
     {
-        $a = self::getApp();
-
-        $debugging = Config::get('system', 'debugging');
-        $logfile   = Config::get('system', 'logfile');
-        $loglevel = intval(Config::get('system', 'loglevel'));
-
-        if (
-            !$debugging
-            || !$logfile
-            || $level > $loglevel
-        ) {
-            return;
-        }
-
-        $processId = session_id();
-
-        if ($processId == '')
-        {
-            $processId = $a->process_id;
-        }
-
-        $callers = debug_backtrace();
-
-        if (count($callers) > 1) {
-            $function = $callers[1]['function'];
-        } else {
-            $function = '';
-        }
-
-        $logline = sprintf("%s@%s\t[%s]:%s:%s:%s\t%s\n",
-                DateTimeFormat::utcNow(DateTimeFormat::ATOM),
-                $processId,
-                self::$levels[$level],
-                basename($callers[0]['file']),
-                $callers[0]['line'],
-                $function,
-                $msg
-            );
+               if (!isset(self::$logger)) {
+                       return;
+               }
+
+               $loglevel = self::mapPSR3Level($level);
 
         $stamp1 = microtime(true);
-        @file_put_contents($logfile, $logline, FILE_APPEND);
-        $a->saveTimestamp($stamp1, "file");
+               self::$logger->log($loglevel, $msg);
+        self::getApp()->saveTimestamp($stamp1, "file");
     }
 
     /**
@@ -141,49 +337,16 @@ class Logger extends BaseObject
      * personally without background noise
      *
      * @param string $msg
-        *
-        * * @deprecated since 2019.03 - never used
+        * @param string $level
      */
-    public static function devLog($msg)
+    public static function devLog($msg, $level = LogLevel::DEBUG)
     {
-        $a = self::getApp();
-
-        $logfile = Config::get('system', 'dlogfile');
-
-        if (!$logfile) {
-            return;
-        }
-
-        $dlogip = Config::get('system', 'dlogip');
-
-        if (!is_null($dlogip) && $_SERVER['REMOTE_ADDR'] != $dlogip)
-        {
-            return;
-        }
-
-        $processId = session_id();
-
-        if ($processId == '')
-        {
-            $processId = $a->process_id;
-        }
-
-        if (!is_string($msg)) {
-               $msg = var_export($msg, true);
-        }
-
-        $callers = debug_backtrace();
-        $logline = sprintf("%s@\t%s:\t%s:\t%s\t%s\t%s\n",
-                DateTimeFormat::utcNow(),
-                $processId,
-                basename($callers[0]['file']),
-                $callers[0]['line'],
-                $callers[1]['function'],
-                $msg
-            );
+               if (!isset(self::$logger)) {
+                       return;
+               }
 
         $stamp1 = microtime(true);
-        @file_put_contents($logfile, $logline, FILE_APPEND);
-        $a->saveTimestamp($stamp1, "file");
+        self::$devLogger->log($level, $msg);
+        self::getApp()->saveTimestamp($stamp1, "file");
     }
 }
diff --git a/src/Util/Logger/FriendicaDevelopHandler.php b/src/Util/Logger/FriendicaDevelopHandler.php
new file mode 100644 (file)
index 0000000..908d705
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+namespace Friendica\Util\Logger;
+
+use Monolog\Handler;
+use Monolog\Logger;
+
+/**
+ * Simple handler for Friendica developers to use for deeper logging
+ *
+ * If you want to debug only interactions from your IP or the IP of a remote server for federation debug,
+ * you'll use Logger::develop() for the duration of your work, and you clean it up when you're done before submitting your PR.
+ */
+class FriendicaDevelopHandler extends Handler\AbstractHandler
+{
+       /**
+        * @var string The IP of the developer who wants to debug
+        */
+       private $developerIp;
+
+       /**
+        * @param string $developerIp  The IP of the developer who wants to debug
+        * @param int    $level        The minimum logging level at which this handler will be triggered
+        * @param bool   $bubble       Whether the messages that are handled can bubble up the stack or not
+        */
+       public function __construct($developerIp, $level = Logger::DEBUG, $bubble = true)
+       {
+               parent::__construct($level, $bubble);
+
+               $this->developerIp = $developerIp;
+       }
+
+       /**
+        * {@inheritdoc}
+        */
+       public function handle(array $record)
+       {
+               if (!$this->isHandling($record)) {
+                       return false;
+               }
+
+               /// Just in case the remote IP is the same as the developer IP log the output
+               if (!is_null($this->developerIp) && $_SERVER['REMOTE_ADDR'] != $this->developerIp)
+               {
+                       return false;
+               }
+
+               return false === $this->bubble;
+       }
+}
diff --git a/src/Util/LoggerFactory.php b/src/Util/LoggerFactory.php
new file mode 100644 (file)
index 0000000..ac6f6c9
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+namespace Friendica\Util;
+
+use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Util\Logger\FriendicaDevelopHandler;
+use Monolog;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+
+/**
+ * A logger factory
+ *
+ * Currently only Monolog is supported
+ */
+class LoggerFactory
+{
+       /**
+        * Creates a new PSR-3 compliant logger instances
+        *
+        * @param string $channel The channel of the logger instance
+        *
+        * @return LoggerInterface The PSR-3 compliant logger instance
+        */
+       public static function create($channel)
+       {
+               $logger = new Monolog\Logger($channel);
+               $logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
+
+               return $logger;
+       }
+
+       /**
+        * Creates a new PSR-3 compliant develop logger
+        *
+        * If you want to debug only interactions from your IP or the IP of a remote server for federation debug,
+        * you'll use this logger instance for the duration of your work.
+        *
+        * It should never get filled during normal usage of Friendica
+        *
+        * @param string $channel      The channel of the logger instance
+        * @param string $developerIp  The IP of the developer who wants to use the logger
+        *
+        * @return LoggerInterface The PSR-3 compliant logger instance
+        */
+       public static function createDev($channel, $developerIp)
+       {
+               $logger = new Monolog\Logger($channel);
+               $logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
+
+               $logger->pushHandler(new FriendicaDevelopHandler($developerIp));
+
+               return $logger;
+       }
+
+       /**
+        * Adding a handler to a given logger instance
+        *
+        * @param LoggerInterface $logger  The logger instance
+        * @param mixed           $stream  The stream which handles the logger output
+        * @param string          $level   The level, for which this handler at least should handle logging
+        *
+        * @return void
+        *
+        * @throws InternalServerErrorException if the logger is incompatible to the logger factory
+        * @throws \Exception in case of general failures
+        */
+       public static function addStreamHandler($logger, $stream, $level = LogLevel::NOTICE)
+       {
+               if ($logger instanceof Monolog\Logger) {
+                       $fileHandler = new Monolog\Handler\StreamHandler($stream . ".1", Monolog\Logger::toMonologLevel($level));
+
+                       $formatter = new Monolog\Formatter\LineFormatter("%channel% [%level_name%]: %message% %context% %extra%");
+                       $fileHandler->setFormatter($formatter);
+
+                       $logger->pushHandler($fileHandler);
+               } else {
+                       throw new InternalServerErrorException('Logger instance incompatible for MonologFactory');
+               }
+       }
+}
index 7e14c71b72a052c809f8cf14da5ec5a8a4ec99e8..8eef2ac3dbfd560681bf50300ec3d7c0a68b41c3 100644 (file)
@@ -7,7 +7,7 @@ namespace Friendica\Test;
 
 use Friendica\App;
 use Friendica\BaseObject;
-use Friendica\Core\Logger;
+use Friendica\Util\Logger;
 use PHPUnit\Framework\TestCase;
 
 /**
@@ -39,7 +39,7 @@ class BaseObjectTest extends TestCase
         */
        public function testSetApp()
        {
-               $logger = Logger::create('test');
+               $logger = $logger = Logger\LoggerFactory::create('test');
                $app = new App(__DIR__ . '/../../', $logger);
                $this->assertNull($this->baseObject->setApp($app));
                $this->assertEquals($app, $this->baseObject->getApp());
index dfda25979791bf20af6e2dea4ac57993e7a2bebd..2ed1a819979b60f45e0b1f0b7752bead2592a63f 100644 (file)
@@ -1,9 +1,9 @@
 <?php
 
 use Friendica\Core\Addon;
-use Friendica\BaseObject;
 use Friendica\Core\Config;
 use Friendica\Core\L10n;
+use Friendica\Core\Logger;
 use Friendica\Core\PConfig;
 use Friendica\Core\Update;
 use Friendica\Core\Worker;
@@ -332,9 +332,7 @@ function update_1298()
                                        $fail++;
                                } else {
                                        DBA::update('profile', [$translateKey => $key], ['id' => $data['id']]);
-                                       BaseObject::getApp()
-                                               ->getLogger()
-                                               ->notice('Updated contact', ['action' => 'update', 'contact' => $data['id'], "$translateKey" => $key,
+                                       Logger::notice('Updated contact', ['action' => 'update', 'contact' => $data['id'], "$translateKey" => $key,
                                                'was' => $data[$translateKey]]);
                                        Worker::add(PRIORITY_LOW, 'ProfileUpdate', $data['id']);                
                                        Contact::updateSelfFromUserID($data['id']);
@@ -344,9 +342,7 @@ function update_1298()
                        }
                }
 
-               BaseObject::getApp()
-                       ->getLogger()
-                       ->notice($translateKey . " fix completed", ['action' => 'update', 'translateKey' => $translateKey, 'Success' => $success, 'Fail' => $fail ]);
+               Logger::notice($translateKey . " fix completed", ['action' => 'update', 'translateKey' => $translateKey, 'Success' => $success, 'Fail' => $fail ]);
        }
        return Update::SUCCESS;
 }