Search code examples
phploggingzend-framework3log-level

Writing logs based on log level in Zend Framework 3


We recently started migrating a project from Zend Framework 1 to Zend Framework 3. With Zend Framework 1, we were using Log4PHP library for application logging. With Log4PHP we are able to log the logs in different files based on log levels (debug, info & error).

The Log4PHP library is not compatible with Zend Framework 3. Hence decided to use Zend Log component available in Zend Framework 3. I tried to put the logs based on log level by seeing the documentation available over the internet and noticed that all logs are getting written to all the mentioned files specified as part of writer.

HomeControllerFactory.php

    <?php
    namespace Application\Controller;

    use Zend\ServiceManager\Factory\FactoryInterface;
    use Interop\Container\ContainerInterface;
    use Zend\Log\Logger;
    use Zend\Log\Writer;

    class HomeControllerFactory implements FactoryInterface
    {
        public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
        {
            $serviceManager = $container->get('ServiceManager');
            $logger = $container->get(Logger::class);
            $infoWriter = new Writer\Stream('C:\log\info.log');
            $debugWriter = new Writer\Stream('C:\log\debug.log');
            $errorWriter = new Writer\Stream('C:\log\error.log');
            $logger->addWriter($infoWriter,6);
            $logger->addWriter($debugWriter,7);
            $logger->addWriter($errorWriter,3);
            return new HomeController($serviceManager, $logger);
        }
    }

HomeController.php

    <?php
    /**
     * @link      http://github.com/zendframework/ZendSkeletonApplication for the canonical source     repository
     * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
     * @license   http://framework.zend.com/license/new-bsd New BSD License
     */
    
    namespace Application\Controller;
    
    use Zend\Mvc\Controller\AbstractActionController;
    use Zend\View\Model\ViewModel;
    use \Zend\ServiceManager\ServiceManager;
    use Zend\Log\Logger;
    use Application\Model\UTP\UTPUtils;
    
    class HomeController extends AbstractActionController {
    
        private $serviceManager;
        private $logger;
    
        public function __construct(ServiceManager $serviceManager, Logger $objLogger)
        {
            $this->serviceManager = $serviceManager;
            $this->logger = $objLogger;
        }
    
        public function indexAction() {
            $config = $this->serviceManager->get('config');

            $this->logger->info(__CLASS__ . ' It is an info log');
            $this->logger->debug(__CLASS__ . ' It is a debug log');
            $this->logger->err(__CLASS__ . ' It is an error log');
        }

    }

With this, all three logs are writing into all 3 files error.log, info.log, debug.log What I am trying to achieve is, if we call

  • $this->logger->debug(<message>), logs should be written to debug.log file
  • $this->logger->info(<message>), logs should be written to info.log file
  • $this->logger->err(<message>), logs should be written to error.log file

Solution

  • Maybe you could Monolog library instead of Zend Log ? Then you could write:

    use Monolog\Logger;
    use Monolog\Handler\StreamHandler;
    
    // create a log channel
    $log = new Logger('name');
    $log->pushHandler(new StreamHandler('C:\log\info.log', Logger::INFO));
    $log->pushHandler(new StreamHandler('C:\log\debug.log', Logger::DEBUG));
    $log->pushHandler(new StreamHandler('C:\log\error.log', Logger::ERROR));
    
    // add records to the log
    $log->warning('Foo');
    $log->error('Bar');
    

    And your code will be compatible with PSR-3 standard