PHP独白不以ISODate格式存储日期时间


PHP Monolog doesn't store datetime in ISODate format

PHP IDS系统使用独白将日志存储到MongoDB中。下面是它存储日志的方式:

{
  "message": "Executing on data 4f2793132469524563fa9b46207b21ee",
  "context": [
  ],
  "level": NumberLong(200),
  "level_name": "INFO",
  "channel": "audit",
  "datetime": "1441721696",
  "extra": [
  ]
}

我想使用Mongo中的自动删除功能,并且我需要datetime字段以ISOdate格式存储,如下所示:

"datetime":ISODate("2015-09-08T17:43:25.678Z")

我看'Expose'Log'Mongo();中的Mongo类,这是负责以秒格式存储datetime的部分

public function log($level, $message, array $context = array())
{
    $logger = new 'Monolog'Logger('audit');
    try {
        $handler = new 'Monolog'Handler'MongoDBHandler(
            new 'MongoClient($this->getConnectString()),
            $this->getDbName(),
            $this->getDbCollection()
        );
    } catch ('MongoConnectionException $e) {
        throw new 'Exception('Cannot connect to Mongo - please check your server');
    }
    $logger->pushHandler($handler);
    $logger->pushProcessor(function ($record) {
        $record['datetime'] = $record['datetime']->format('U');            
        return $record;
    });
    return $logger->$level($message, $context);
}

我已经把$record['datetime']改成了这个

//$record['datetime'] = $record['datetime']->format('U');
$record['datetime'] =  new 'MongoDate();;

但是时间不是存储为ISOdate,而是这样:

"datetime": "[object] (MongoDate: 0.84500000 1441721683)"

谁能告诉我如何存储datetime在ISODate格式?

使用MongoDate来生成datetime对象是正确的。如:

$date = new MongoDate(strtotime("2015-11-23 00:00:00"));

如果你回显这个,你将得到你所描述的格式,但内部Mongo应该正确存储它。要检查,您可以测试:

echo date(DATE_ISO8601, ($date->sec);

应该以ISO可读格式返回。

然后您可以编写自己的PSR-3兼容的记录器,以这种方式存储数据。

$filters = new 'Expose'FilterCollection();
$filters->load();
$logger = new 'YourCustom'PSR3Logger();
$manager = new 'Expose'Manager($filters, $logger);

在您的Mongo实例中,您将希望像这样设置字段的TTL:

db.log.ensureIndex( { "datetime": 1 }, { expireAfterSeconds: 3600 } )

有关TTL设置的更多信息,请参阅Mongo文档:通过设置TTL来使集合中的数据过期

我在Symfony2配置上遇到了同样的问题。我通过设置一个基本上什么都不做的自定义格式化器来解决这个问题。它在我的情况下工作得很好,因为我只是存储标量的东西,唯一的例外是MongoDate,它不需要格式化。所以你可能需要在你这边做一些调整。

这是自定义格式化器:

<?php
namespace AppBundle'Service'Formatter;
use Monolog'Formatter'FormatterInterface;
/**
 * Class MongoLoggerFormatter
 *
 * @package AppBundle'Service
 * @author  Francesco Casula <fra.casula@gmail.com>
 */
class MongoLoggerFormatter implements FormatterInterface
{
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        return $record;
    }
    /**
     * {@inheritdoc}
     */
    public function formatBatch(array $records)
    {
        return $records;
    }
}

下面是我的异常监听器的摘录:

/**
 * @return 'Symfony'Bridge'Monolog'Logger
 */
public function getLogger()
{
    return $this->logger;
}
/**
 * @return 'Monolog'Handler'HandlerInterface|null
 */
private function getMongoHandler()
{
    foreach ($this->getLogger()->getHandlers() as $handler) {
        if ($handler instanceof MongoDBHandler) {
            return $handler;
        }
    }
    return null;
}
/**
 * @return 'Monolog'Handler'HandlerInterface|null
 */
private function addDefaultMongoHandlerSettings()
{
    $mongoHandler = $this->getMongoHandler();
    if ($mongoHandler) {
        $mongoHandler->setFormatter(new MongoLoggerFormatter());
        $mongoHandler->pushProcessor(function (array $record) {
            $record['created_at'] = new 'MongoDate(time());
            return $record;
        });
    }
    return $mongoHandler;
}