7

我想知道通过 ZF2 中的 ServiceManager 启动和重用记录器实例的最佳方法是什么。当然我可以做一个简单的方法在任何类中使用,比如:

public function getLogger () {
        $this->logger = new Logger();
        $this->logger->addWriter(new Writer\Stream('/log/cms_errors.log'));
        return $logger;
    }

但我想知道在 global.php 中注册类似结构的最佳方法是什么。到目前为止我可以

将以下内容添加到 global.php

'Zend\Log'=>array(
        'timestampFormat' => 'Y-m-d',
        array(
            'writerName'   => 'Stream',
            'writerParams' => array(
                'stream'   => '/log/zend.log',
            ),
            'formatterName' => 'Simple',            
        ),
    ),

如果我尝试通过以下方式调用它:

$this->getServiceLocator()->get('Zend\Log')

我得到一个:

Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Zend\Log
4

5 回答 5

21

将以下数据添加到 'global.php'

'service_manager' => array(
    'factories' => array(
        'Zend\Log' => function ($sm) {
            $log = new Zend\Log\Logger();
            $writer = new Zend\Log\Writer\Stream('./data/logs/logfile');
            $log->addWriter($writer);

            return $log;
        },
    ),
),

然后你就可以打电话了

$this->getServiceLocator()->get('Zend\Log')->info('Something...');
于 2012-10-14T20:11:19.560 回答
11

或者,更优雅的是,您可以设置一个日志侦听器并使您的记录器与您的应用程序分离。这EventManager是一个非常强大的组件,ZF2 现在基本上是一个事件驱动的框架。

在你的module.php你可以添加类似的东西:

// Setup the Zend Logger, pseudocode
$logger = new Logger;
$writer = new Writer;
$logger->addWriter($writer);

// Attach a logging listener for the log event on application level, working code
$events = StaticEventManager::getInstance();
$events->attach('*', 'log', function($event) use ($logger) {
    $target = get_class($event->getTarget());
    $message = $event->getParam('message', 'No message provided');
    $priority = (int) $event->getParam('priority', Logger::INFO);
    $message = sprintf('%s: %s', $target, $message);
    $logger->log($priority, $message);
});

然后从任何地方,例如从控制器,您可以执行以下操作:

$this->getEventManager()->trigger('log', $this, array(
                                                       'priority' => 7, 
                                                       'message' => 'some log message'
                                                      ));
于 2013-02-08T00:44:53.860 回答
2

也许使用抽象记录器工厂而不是普通工厂进行配置

http://framework.zend.com/manual/2.2/en/modules/zend.mvc.services.html#zend-log-loggerabstractservicefactory

return array(
    'log' => array(
        'Log\App' => array(
            'writers' => array(
                array(
                    'name' => 'stream',
                    'priority' => 1000,
                    'options' => array(
                        'stream' => 'data/logs/app.log',
                    ),
                ),
            ),
        ),
    ),
);
于 2014-06-20T19:15:14.537 回答
1

请使用绝对路径重试\

$writer = new \Zend\Log\Writer\Stream('log.log');
$logger = new \Zend\Log\Logger($writer);
于 2012-09-18T19:08:42.087 回答
1

我在我的引导程序中创建了一个默认的数据库写入器对象并将其注册到 ServiceManager 中。

public function onBootstrap(MvcEvent $e)
{
    ...

    $serviceManager     = $e->getApplication()->getServiceManager();
    $dbAdapter          = $serviceManager->get('Zend\Db\Adapter\Adapter');

    $writer = new \Zend\Log\Writer\Db($dbAdapter, 'log_database_table');
    $logger = new \Zend\Log\Logger();
    $logger->addWriter($writer);

    // this is optional but nice to have
    \Zend\Log\Logger::registerErrorHandler($logger);

    $serviceManager->setService('Zend\Log', $logger);
}

AbstractController 是“ServiceLocatorAwareInterface”的一个实例。所以我可以调用我的控制器

public function indexAction()
{
    ...

    $this->getServiceLocator()->get('Zend\Log')->info('this is a test log message');

    ...
}
于 2013-02-18T18:48:55.060 回答