mongodb — PHP Monolog не хранит дату и время в формате ISODate

Система 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")

Я смотрю на класс Mongo в \Expose\Log\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?

1

Решение

Вы правильно используете 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

0

Другие решения

У меня была такая же проблема в конфигурации Symfony2. Я решил, установив пользовательский форматер, который в принципе ничего не делает. В моем случае это работало довольно хорошо, так как я хранил только скалярные данные, единственным исключением было MongoDate это не должно быть отформатировано. Так что может быть, что вам нужно сделать некоторые настройки на вашей стороне.

Вот пользовательский форматтер:

<?php

namespace AppBundle\Service\Formatter;

use Monolog\Formatter\FormatterInterface;

/**
* Class MongoLoggerFormatter
*
* @package AppBundle\Service
* @author  Francesco Casula <[email protected]>
*/
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;
}
0

По вопросам рекламы [email protected]