Как зарегистрировать экземпляр Zend\Log в ServiceManager в ZF2

Мне интересно, как лучше всего инициировать и повторно использовать экземпляр регистратора через ServiceManager в ZF2. Конечно, я могу сделать простой метод для использования в любом классе, например:

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

person Al-Punk    schedule 27.07.2012    source источник


Ответы (5)


Добавьте следующие данные в «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...');
person arturgrigor    schedule 14.10.2012
comment
@Arthur: Есть ли способ быть менее многословным при вызове $this->getServiceLocator()->get('Zend\Log')->info('Something...');? - person Tinou; 09.01.2013
comment
Это рабочее решение, пока вы не захотите кэшировать свою конфигурацию. Из-за использования Closure это не удастся. Но реализация фабричного класса кажется немного неудобной (особенно если вы хотите переопределить в local.php). У Вас есть какие-то предложения? - person Dennis D.; 22.10.2013
comment
Не уверен, что вы все еще ищете это, но вы также можете использовать абстрактную фабрику. фреймворк. zend.com/manual/2.2/en/modules/ решение будет опубликовано ниже - person Manuel; 20.06.2014

В качестве альтернативы и более элегантно вы можете настроить прослушиватель журнала и отделить свой журнал от вашего приложения. 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'
                                                      ));
person markus    schedule 08.02.2013
comment
Я думаю, что это отличный способ сделать это @markus, тогда все, что нам нужно сделать, это реализовать EventManagerAware или что-то в этом роде. - person Gabriel Baker; 01.04.2013

Возможно, для настройки используйте абстрактную фабрику регистраторов вместо обычной фабрики.

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',
                    ),
                ),
            ),
        ),
    ),
);
person Manuel    schedule 20.06.2014
comment
Я хотел бы узнать, ГДЕ мы должны поместить эти данные конфигурации. Я пытался понять это весь день. - person David; 15.07.2015
comment
@David: это конфигурация модуля (module/MODULENAME/config/module.config.php) - person MonkeyMonkey; 27.11.2015
comment
@monkeymoney: ииииии, мне потребовалось некоторое время, чтобы понять это. документы ZF обычно дают примеры конфигурации таким образом, и это может ввести в заблуждение новичка. если он предназначен для перехода в module.config.php, пример может включать /* все остальные тонны данных конфигурации, опущенные */ для ясности. - person David; 09.12.2015

Пожалуйста, попробуйте еще раз, используя абсолютный путь \

$writer = new \Zend\Log\Writer\Stream('log.log');
$logger = new \Zend\Log\Logger($writer);
person Thorsten    schedule 18.09.2012

Я создал объект записи базы данных по умолчанию в своем бутстрапе и зарегистрировал его в 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');

    ...
}
person Matthias Lill    schedule 18.02.2013