Переглянути джерело

Add AWS DynamoDB handler

This also adds the `aws/aws-sdk-php` dev dependency
adlawson 12 роки тому
батько
коміт
471bc7fa91

+ 1 - 0
README.mdown

@@ -148,6 +148,7 @@ Handlers
   [Mongo](http://pecl.php.net/package/mongo) extension connection.
 - _CouchDBHandler_: Logs records to a CouchDB server.
 - _DoctrineCouchDBHandler_: Logs records to a CouchDB server via the Doctrine CouchDB ODM.
+- _DynamoDbHandler_: Logs records to a DynamoDB table with the [AWS SDK](https://github.com/aws/aws-sdk-php).
 
 ### Wrappers / Special Handlers
 

+ 4 - 2
composer.json

@@ -20,14 +20,16 @@
         "phpunit/phpunit": "~3.7.0",
         "mlehner/gelf-php": "1.0.*",
         "raven/raven": "0.5.*",
-        "doctrine/couchdb": "dev-master"
+        "doctrine/couchdb": "dev-master",
+        "aws/aws-sdk-php": "~2.4.8"
     },
     "suggest": {
         "mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server",
         "raven/raven": "Allow sending log messages to a Sentry server",
         "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
         "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
-        "ext-mongo": "Allow sending log messages to a MongoDB server"
+        "ext-mongo": "Allow sending log messages to a MongoDB server",
+        "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB"
     },
     "autoload": {
         "psr-0": {"Monolog": "src/"}

+ 85 - 0
src/Monolog/Handler/DynamoDbHandler.php

@@ -0,0 +1,85 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Aws\DynamoDb\DynamoDbClient;
+use Monolog\Formatter\ScalarFormatter;
+use Monolog\Handler\AbstractProcessingHandler;
+use Monolog\Logger;
+
+/**
+ * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/)
+ *
+ * @link https://github.com/aws/aws-sdk-php/
+ * @author Andrew Lawson <adlawson@gmail.com>
+ */
+class DynamoDbHandler extends AbstractProcessingHandler
+{
+    const DATE_FORMAT = 'Y-m-d\TH:i:s.uO';
+
+    /**
+     * @var DynamoDbClient
+     */
+    protected $client;
+
+    /**
+     * @var string
+     */
+    protected $table;
+
+    /**
+     * @param DynamoDbClient $client
+     * @param string $table
+     * @param integer $level
+     * @param boolean $bubble
+     */
+    public function __construct(DynamoDbClient $client, $table, $level = Logger::DEBUG, $bubble = true)
+    {
+        $this->client = $client;
+        $this->table = $table;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function write(array $record)
+    {
+        $filtered = $this->filterEmptyFields($record['formatted']);
+        $formatted = $this->client->formatAttributes($filtered);
+
+        $this->client->putItem(array(
+            'TableName' => $this->table,
+            'Item' => $formatted
+        ));
+    }
+
+    /**
+     * @param array $record
+     * @return array
+     */
+    protected function filterEmptyFields(array $record)
+    {
+        return array_filter($record, function($value) {
+            return !empty($value) || false === $value || 0 === $value;
+        });
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getDefaultFormatter()
+    {
+        return new ScalarFormatter(self::DATE_FORMAT);
+    }
+}

+ 71 - 0
tests/Monolog/Handler/DynamoDbHandlerTest.php

@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+
+class DynamoDbHandlerTest extends TestCase
+{
+    public function setUp()
+    {
+        if (!class_exists('Aws\DynamoDb\DynamoDbClient')) {
+            $this->markTestSkipped('aws/aws-sdk-php not installed');
+        }
+
+        $this->client = $this->getMockBuilder('Aws\DynamoDb\DynamoDbClient')->disableOriginalConstructor()->getMock();
+    }
+
+    public function testConstruct()
+    {
+        $this->assertInstanceOf('Monolog\Handler\DynamoDbHandler', new DynamoDbHandler($this->client, 'foo'));
+    }
+
+    public function testInterface()
+    {
+        $this->assertInstanceOf('Monolog\Handler\HandlerInterface', new DynamoDbHandler($this->client, 'foo'));
+    }
+
+    public function testGetFormatter()
+    {
+        $handler = new DynamoDbHandler($this->client, 'foo');
+        $this->assertInstanceOf('Monolog\Formatter\ScalarFormatter', $handler->getFormatter());
+    }
+
+    public function testHandle()
+    {
+        $record = $this->getRecord();
+        $formatter = $this->getMock('Monolog\Formatter\FormatterInterface');
+        $formatted = array('foo' => 1, 'bar' => 2);
+        $handler = new DynamoDbHandler($this->client, 'foo');
+        $handler->setFormatter($formatter);
+
+        $formatter
+             ->expects($this->once())
+             ->method('format')
+             ->with($record)
+             ->will($this->returnValue($formatted));
+        $this->client
+             ->expects($this->once())
+             ->method('formatAttributes')
+             ->with($this->isType('array'))
+             ->will($this->returnValue($formatted));
+        $this->client
+             ->expects($this->once())
+             ->method('__call')
+             ->with('putItem', array(array(
+                 'TableName' => 'foo',
+                 'Item' => $formatted
+             )));
+
+        $handler->handle($record);
+    }
+}