Sfoglia il codice sorgente

Merge remote-tracking branch 'giosh94mhz/phpamqplib_handler'

Jordi Boggiano 11 anni fa
parent
commit
2c1d1ded9e

+ 3 - 1
composer.json

@@ -22,13 +22,15 @@
         "raven/raven": "~0.5",
         "ruflin/elastica": "0.90.*",
         "doctrine/couchdb": "~1.0@dev",
-        "aws/aws-sdk-php": "~2.4, >2.4.8"
+        "aws/aws-sdk-php": "~2.4, >2.4.8",
+        "videlalvaro/php-amqplib": "~2.4"
     },
     "suggest": {
         "graylog2/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",
         "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
+        "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
         "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
         "ext-mongo": "Allow sending log messages to a MongoDB server",
         "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",

+ 84 - 0
src/Monolog/Handler/PhpAmqpLibHandler.php

@@ -0,0 +1,84 @@
+<?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\Logger;
+use Monolog\Formatter\JsonFormatter;
+use PhpAmqpLib\Message\AMQPMessage;
+use PhpAmqpLib\Channel\AMQPChannel;
+
+/**
+ * Handler to send messages to AMQP using php-amqplib
+ *
+ * @author Giorgio Premi <giosh94mhz@gmail.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class PhpAmqpLibHandler extends AbstractProcessingHandler
+{
+    /**
+     * @var \PhpAmqpLib\Channel\AMQPChannel $channel
+     */
+    protected $channel;
+
+    /**
+     * @var string $exchangeName
+     */
+    protected $exchangeName;
+
+    /**
+     * @param AMQPChannel $channel      AMQP channel, ready for use
+     * @param string      $exchangeName
+     * @param int         $level
+     * @param bool        $bubble       Whether the messages that are handled can bubble up the stack or not
+     */
+    public function __construct(AMQPChannel $channel, $exchangeName = 'log', $level = Logger::DEBUG, $bubble = true)
+    {
+        $this->channel = $channel;
+        $this->exchangeName = $exchangeName;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record)
+    {
+        $data = $record["formatted"];
+
+        $routingKey = sprintf(
+            '%s.%s',
+            substr($record['level_name'], 0, 4),
+            $record['channel']
+        );
+
+        $this->channel->basic_publish(
+            new AMQPMessage(
+                (string) $data,
+                array(
+                    'delivery_mode' => 2,
+                    'content_type' => 'application/json'
+                )
+            ),
+            $this->exchangeName,
+            strtolower($routingKey)
+        );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter()
+    {
+        return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
+    }
+}

+ 82 - 0
tests/Monolog/Handler/PhpAmqpLibHandlerTest.php

@@ -0,0 +1,82 @@
+<?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;
+use Monolog\Logger;
+use PhpAmqpLib\Message\AMQPMessage;
+
+/**
+ * @covers Monolog\Handler\RotatingFileHandler
+ */
+class PhpAmqpLibHandlerTest extends TestCase
+{
+    public function setUp()
+    {
+        if (!class_exists('PhpAmqpLib\Connection\AMQPConnection')) {
+            $this->markTestSkipped("php-amqplib not installed");
+        }
+    }
+
+    public function testHandle()
+    {
+        $messages = array();
+
+        $exchange = $this->getMock('PhpAmqpLib\Channel\AMQPChannel', array('basic_publish', '__destruct'), array(), '', false);
+
+        $exchange->expects($this->any())
+            ->method('basic_publish')
+            ->will($this->returnCallback(function (AMQPMessage $msg, $exchange = "", $routing_key = "", $mandatory = false, $immediate = false, $ticket = null) use (&$messages) {
+                $messages[] = array($msg, $exchange, $routing_key, $mandatory, $immediate, $ticket);
+            }))
+        ;
+
+        $handler = new PhpAmqpLibHandler($exchange, 'log');
+
+        $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
+
+        $expected = array(
+            array(
+                'message' => 'test',
+                'context' => array(
+                    'data' => array(),
+                    'foo' => 34,
+                ),
+                'level' => 300,
+                'level_name' => 'WARNING',
+                'channel' => 'test',
+                'extra' => array(),
+            ),
+            'log',
+            'warn.test',
+            false,
+            false,
+            null,
+            array(
+                'delivery_mode' => 2,
+                'content_type' => 'application/json'
+            )
+        );
+
+        $handler->handle($record);
+
+        $this->assertCount(1, $messages);
+
+        /* @var $msg AMQPMessage */
+        $msg = $messages[0][0];
+        $messages[0][0] = json_decode($msg->body, true);
+        $messages[0][] = $msg->get_properties();
+        unset($messages[0][0]['datetime']);
+
+        $this->assertEquals($expected, $messages[0]);
+    }
+}