2

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

  • logEntry(根)(默认)
    • 时间戳(默认)(字符串)时间戳
    • 优先级(默认)(字符串)优先级
    • priorityName (default) (string) 优先级名称
    • 消息(默认)(字符串)消息
    • uniqueId (new) (string) 唯一 ID
    • 方法(新)(字符串)命名空间\类::方法名()
    • args (new) (string) base64 编码,序列化 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->elementMap 是扁平的(没有添加额外的额外数组)。

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

我究竟做错了什么?

我在想这是一个 ZF2 错误...在阅读 Github 上的代码时,我无法找到并检测到额外的字段和键...你们怎么看?

4

1 回答 1

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);
于 2013-03-29T16:08:39.800 回答