记录自定义元素 Zend Log Formatter XML

Posted

技术标签:

【中文标题】记录自定义元素 Zend Log Formatter XML【英文标题】:Logging custom elements Zend Log Formatter XML 【发布时间】:2013-03-20 07:17:30 【问题描述】:

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

logEntry(root)(默认) 时间戳(默认)(字符串)时间戳 优先级(默认)(字符串)优先级 priorityName(默认)(字符串)优先级名称 消息(默认)(字符串)消息 uniqueId(新)(字符串)唯一标识 方法(新)(字符串)命名空间\Class::MethodName() 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))), 
));

错误: 注意:未定义索引:/var/www/library/Zend/Log/Formatter/Xml.php 168 行中的 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 上的代码时,我无法找到和检测额外的字段和键...你们怎么看?

【问题讨论】:

您的 Github 链接导致 404。没有代码很难诊断问题。 【参考方案1】:

问题是 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);

【讨论】:

以上是关于记录自定义元素 Zend Log Formatter XML的主要内容,如果未能解决你的问题,请参考以下文章

自定义元素(custom elements)

Zend:如何正确破坏 PHP 7 中的自定义对象?

小玩意--自定义log记录

自定义表单装饰器中的 Zend 框架类

Zend Framework - 从视图脚本中清除自定义占位符

将自定义路由添加到 Zend REST 控制器