记录自定义元素Zend Log Formatter XML

时间:2013-03-29 14:57:55

标签: xml logging zend-framework2 zend-log

我正在尝试提供有关请求的一些信息,结果应该放在XML文件中。 我正在使用以下元素:

  • logEntry(root)(默认)
    • timestamp(默认)(字符串)timestamp
    • 优先级(默认)(字符串)优先级
    • priorityName(默认)(字符串)优先级名称
    • message(默认)(字符串)消息
    • uniqueId(new)(字符串)唯一ID
    • method(new)(string)Namespace \ Class :: MethodName()
    • args(new)(string)base64 encoded,serialized func_get_args();

应该是:

<logEntry><timestamp>2013-03-29T15:47:41+01:00</timestamp><priority>6</priority><priorityName>INFO</priorityName><message>Called</message><uniqueId>564fg56d4g5d4fg5f4g56fg465dfg</uniqueId><method>\Namespace\Controller::methodName</method><args>aa5abc8d6efeabcd7f67cb6a7df6bac5ba7a5fd7a5d6bac67a5bf6abcbb408f098=</args></logEntry>

我读过的文件: http://zf2.readthedocs.org/en/latest/modules/zend.log.formatters.html

无效代码:

$writer    = new \Zend\Log\Writer\Stream(getenv('LOG_FILE_LOCATION'));
$formatter = new \Zend\Log\Formatter\Xml('logEntry', array(
    'timestamp'    => 'timestamp',
    'priority'     => 'priority',
    'priorityName' => 'priorityName',
    'message'      => 'message',
    'uniqueId'     => 'uniqueId',
    'method'       => 'method',
    'args'         => 'args',
));
$writer->setFormatter($formatter);
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

$logger->info('Started', array(
    'uniqueId' => $this->createGuid(),
    'method'   => __METHOD__,
    'args'     => serialize(array(get_class($e))), 
));

错误: 注意:未定义的索引:第168行的/var/www/library/Zend/Log/Formatter/Xml.php中的uniqueId

Xml.php的代码 https://github.com/zendframework/zf2/blob/master/library/Zend/Log/Formatter/Xml.php#L168

$ event [$ fieldKey]是问题所在。 $ fieldKey仅存在于$ event ['extra'] [$ fieldKey]中。 $ this-&gt; elementMap是平的(没有添加额外的额外数组)。

Array
(
    [timestamp] => timestamp
    [priority] => priority
    [priorityName] => priorityName
    [message] => message
    [uniqueId] => uniqueId
    [method] => method
    [args] => args
)

我做错了什么?

我认为这是一个ZF2错误......当在Github上阅读代码时,我无法找到并检测到额外的字段和密钥......你们有什么想法?

1 个答案:

答案 0 :(得分:4)

问题是Xml格式化程序忽略了传递给记录器的extra数据(记录器希望它是一个数组,格式化程序隐式忽略任何不是空字符串,带有__toString()的对象方法或标量。解决方案似乎是编写自己的处理器以将额外数据与从记录器传递的常规事件数据合并。

这是一个非常简单的示例,尽管您可能希望对自己函数中额外数据数组中传递的允许键值进行一些检查,但这可用于演示目的。 (你也可以为这个课提出一个更好的名字:D)

<?php
namespace Application\Log\Processor;

use Zend\Log\Processor\ProcessorInterface;

class Merger implements ProcessorInterface
{

    /**
     * Merge extra data into the event data
     * @param array $event event data
     * @return array event data
     */
    public function process(array $event)
    {
        if (!isset($event['extra'])) {
            $event['extra'] = array();
        }
        return array_merge($event, $event['extra']);
    }
}

要实现,请执行第一个非工作代码示例,但只传入要使用的根元素名称

$writer    = new \Zend\Log\Writer\Stream(getenv('LOG_FILE_LOCATION'));
$formatter = new \Zend\Log\Formatter\Xml('logEntry');
$writer->setFormatter($formatter);
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

// add the processor into the mix
$processor = new \Application\Log\Processor\Merger;
$logger->addProcessor($processor);

$data = array(
    'uniqueId' => $this->createGuid(),
    'method'   => __METHOD__,
    'args'     => serialize(func_get_args()), 
);
$logger->info('Testing', $data);