1

PHP IDS システム公開では、 Monologを使用してログを 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 形式で保存する方法を教えてもらえますか?

4

2 に答える 2

0

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を設定してコレクションからデータを期限切れにする

于 2015-11-24T01:38:17.923 に答える
0

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;
}
于 2016-03-21T13:34:52.240 に答える