From c82120fea361c3ec709d0041494b88e2871f8057 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 28 Jul 2014 20:37:39 +0200 Subject: [PATCH] Merge PhpAmqlLibHandler into the AmqpHandler, refs #389 --- src/Monolog/Handler/AmqpHandler.php | 61 ++++++++++---- src/Monolog/Handler/PhpAmqpLibHandler.php | 84 ------------------- tests/Monolog/Handler/AmqpHandlerTest.php | 65 +++++++++++++- .../Monolog/Handler/PhpAmqpLibHandlerTest.php | 82 ------------------ 4 files changed, 106 insertions(+), 186 deletions(-) delete mode 100644 src/Monolog/Handler/PhpAmqpLibHandler.php delete mode 100644 tests/Monolog/Handler/PhpAmqpLibHandlerTest.php diff --git a/src/Monolog/Handler/AmqpHandler.php b/src/Monolog/Handler/AmqpHandler.php index 2db0d08d..b8dbfc0b 100644 --- a/src/Monolog/Handler/AmqpHandler.php +++ b/src/Monolog/Handler/AmqpHandler.php @@ -13,24 +13,38 @@ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Formatter\JsonFormatter; +use PhpAmqpLib\Message\AMQPMessage; +use PhpAmqpLib\Channel\AMQPChannel; +use AMQPExchange; class AmqpHandler extends AbstractProcessingHandler { /** - * @var \AMQPExchange $exchange + * @var AMQPExchange|AMQPChannel $exchange */ protected $exchange; /** - * @param \AMQPExchange $exchange AMQP exchange, 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 + * @var string */ - public function __construct(\AMQPExchange $exchange, $exchangeName = 'log', $level = Logger::DEBUG, $bubble = true) + protected $exchangeName; + + /** + * @param AMQPExchange|AMQPChannel $exchange AMQPExchange (php AMQP ext) or PHP AMQP lib 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($exchange, $exchangeName = 'log', $level = Logger::DEBUG, $bubble = true) { + if ($exchange instanceof AMQPExchange) { + $this->exchange->setName($exchangeName); + } elseif ($exchange instanceof AMQPChannel) { + $this->exchangeName = $exchangeName; + } else { + throw new \InvalidArgumentException('PhpAmqpLib\Channel\AMQPChannel or AMQPExchange instance required'); + } $this->exchange = $exchange; - $this->exchange->setName($exchangeName); parent::__construct($level, $bubble); } @@ -44,19 +58,34 @@ class AmqpHandler extends AbstractProcessingHandler $routingKey = sprintf( '%s.%s', + // TODO 2.0 remove substr call substr($record['level_name'], 0, 4), $record['channel'] ); - $this->exchange->publish( - $data, - strtolower($routingKey), - 0, - array( - 'delivery_mode' => 2, - 'Content-type' => 'application/json' - ) - ); + if ($this->exchange instanceof AMQPExchange) { + $this->exchange->publish( + $data, + strtolower($routingKey), + 0, + array( + 'delivery_mode' => 2, + 'Content-type' => 'application/json' + ) + ); + } else { + $this->exchange->basic_publish( + new AMQPMessage( + (string) $data, + array( + 'delivery_mode' => 2, + 'content_type' => 'application/json' + ) + ), + $this->exchangeName, + strtolower($routingKey) + ); + } } /** diff --git a/src/Monolog/Handler/PhpAmqpLibHandler.php b/src/Monolog/Handler/PhpAmqpLibHandler.php deleted file mode 100644 index c2a1d06e..00000000 --- a/src/Monolog/Handler/PhpAmqpLibHandler.php +++ /dev/null @@ -1,84 +0,0 @@ - - * - * 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 - * @author Jordi Boggiano - */ -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); - } -} diff --git a/tests/Monolog/Handler/AmqpHandlerTest.php b/tests/Monolog/Handler/AmqpHandlerTest.php index 249f2b72..074d50c6 100644 --- a/tests/Monolog/Handler/AmqpHandlerTest.php +++ b/tests/Monolog/Handler/AmqpHandlerTest.php @@ -13,13 +13,16 @@ namespace Monolog\Handler; use Monolog\TestCase; use Monolog\Logger; +use PhpAmqpLib\Message\AMQPMessage; +use PhpAmqpLib\Channel\AMQPChannel; +use PhpAmqpLib\Connection\AMQPConnection; /** * @covers Monolog\Handler\RotatingFileHandler */ class AmqpHandlerTest extends TestCase { - public function setUp() + public function testHandleAmqpExt() { if (!class_exists('AMQPConnection') || !class_exists('AMQPExchange')) { $this->markTestSkipped("amqp-php not installed"); @@ -28,10 +31,7 @@ class AmqpHandlerTest extends TestCase if (!class_exists('AMQPChannel')) { $this->markTestSkipped("Please update AMQP to version >= 1.0"); } - } - public function testHandle() - { $messages = array(); $exchange = $this->getMock('AMQPExchange', array('publish', 'setName'), array(), '', false); @@ -77,4 +77,61 @@ class AmqpHandlerTest extends TestCase unset($messages[0][0]['datetime']); $this->assertEquals($expected, $messages[0]); } + + public function testHandlePhpAmqpLib() + { + if (!class_exists('PhpAmqpLib\Connection\AMQPConnection')) { + $this->markTestSkipped("php-amqplib not installed"); + } + + $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 AmqpHandler($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]); + } } diff --git a/tests/Monolog/Handler/PhpAmqpLibHandlerTest.php b/tests/Monolog/Handler/PhpAmqpLibHandlerTest.php deleted file mode 100644 index b5996edd..00000000 --- a/tests/Monolog/Handler/PhpAmqpLibHandlerTest.php +++ /dev/null @@ -1,82 +0,0 @@ - - * - * 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]); - } -}