Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstraction for logstash introduced, better error handling #13

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 14 additions & 15 deletions src/CommandBus/LogEventMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,38 @@

namespace Clearcode\SimpleBusElkBundle\CommandBus;

use Clearcode\SimpleBusElkBundle\Converter\ObjectToArrayConverterInterface;
use Clearcode\SimpleBusElkBundle\Logstash\CannotWriteToLogstash;
use Clearcode\SimpleBusElkBundle\Logstash\Logstash;
use Psr\Log\LoggerInterface;
use SimpleBus\Message\Bus\Middleware\MessageBusMiddleware;

class LogEventMiddleware implements MessageBusMiddleware
{
/**
* @var LoggerInterface
*/
/** @var Logstash */
private $logstash;
/** @var LoggerInterface */
private $logger;

/**
* @var ObjectToArrayConverterInterface
*/
private $converter;

/**
* LogEventMiddleware constructor.
*
* @param Logstash $logstash
* @param LoggerInterface $logger
*/
public function __construct(LoggerInterface $logger, ObjectToArrayConverterInterface $converter)
public function __construct(Logstash $logstash, LoggerInterface $logger)
{
$this->logger = $logger;
$this->converter = $converter;
$this->logstash = $logstash;
$this->logger = $logger;
}

/**
* {@inheritdoc}
*/
public function handle($message, callable $next)
{
$this->logger->info('Event recorded', $this->converter->toArray($message));
try {
$this->logstash->write($message);
} catch (CannotWriteToLogstash $e) {
$this->logger->error($e->getMessage());
}

$next($message);
}
Expand Down
3 changes: 2 additions & 1 deletion src/DependencyInjection/ElkBridgeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public function load(array $config, ContainerBuilder $container)
$container->setParameter('simple_bus_elk.middleware', $config['middleware']);

if ($config['middleware']) {
$loader->load('event_bus.yml');
$loader->load('logstash.yml');
$loader->load('middlewares.yml');
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/Logstash/CannotWriteToLogstash.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Clearcode\SimpleBusElkBundle\Logstash;

class CannotWriteToLogstash extends \Exception
{

}
47 changes: 47 additions & 0 deletions src/Logstash/Logstash.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Clearcode\SimpleBusElkBundle\Logstash;

use Clearcode\SimpleBusElkBundle\Converter\DataToConvertIsNotAnObject;
use Clearcode\SimpleBusElkBundle\Converter\ObjectToArrayConverterInterface;
use Psr\Log\LoggerInterface;

class Logstash
{
/** @var LoggerInterface */
private $logger;
/** @var ObjectToArrayConverterInterface */
private $converter;

/**
* @param LoggerInterface $logger
* @param ObjectToArrayConverterInterface $converter
*/
public function __construct(LoggerInterface $logger, ObjectToArrayConverterInterface $converter)
{
$this->logger = $logger;
$this->converter = $converter;
}

/**
* @param $object
*
* @throws CannotWriteToLogstash
*/
public function write($object)
{
try {
$this->logger->info('Event recorded', $this->converter->toArray($object));

} catch (DataToConvertIsNotAnObject $e) {
$this->handleError(sprintf('Data conversion problem during writing to logstash: %s', $e->getMessage()));
} catch (\Exception $e) {
$this->handleError(sprintf('Connection with logstash error: %s', $e->getMessage()));
}
}

private function handleError($message)
{
throw new CannotWriteToLogstash($message);
}
}
8 changes: 8 additions & 0 deletions src/Resources/config/logstash.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
simple_bus_elk.logstash:
class: Clearcode\SimpleBusElkBundle\Logstash\Logstash
arguments:
- @logger
- @simple_bus_elk.converter.to_array_converter
tags:
- { name: monolog.logger, channel: '%simple_bus_elk.monolog_channel%' }
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ services:
simple_bus_elk.event_bus.log_event:
class: Clearcode\SimpleBusElkBundle\CommandBus\LogEventMiddleware
arguments:
- @simple_bus_elk.logstash
- @logger
- @simple_bus_elk.converter.to_array_converter
tags:
- { name: event_bus_middleware, priority: 999 }
- { name: monolog.logger, channel: '%simple_bus_elk.monolog_channel%' }
3 changes: 2 additions & 1 deletion src/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ services:
simple_bus_elk.converter.to_array_converter:
class: Clearcode\SimpleBusElkBundle\Converter\ObjectToArrayConverter
arguments:
- @jms_serializer
- "@jms_serializer"

simple_bus_elk.monolog.logstash_formatter:
class: Monolog\Formatter\LogstashFormatter
arguments: [ "%simple_bus_elk.logstash_namespace%" ]
60 changes: 37 additions & 23 deletions tests/CommandBus/LogEventMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,41 @@
namespace tests\Clearcode\SimpleBusElkBundle\CommandBus;

use Clearcode\SimpleBusElkBundle\CommandBus\LogEventMiddleware;
use Clearcode\SimpleBusElkBundle\Converter\ObjectToArrayConverter;
use Clearcode\SimpleBusElkBundle\Logstash\CannotWriteToLogstash;
use Clearcode\SimpleBusElkBundle\Logstash\Logstash;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
use Psr\Log\LoggerInterface;

class LogEventMiddlewareTest extends \PHPUnit_Framework_TestCase
{
/**
* @var LogEventMiddleware
*/
private $sut;
/**
* @var ObjectProphecy|LoggerInterface
*/
/** @var ObjectProphecy|LoggerInterface */
private $logger;
/**
* @var ObjectProphecy|ObjectToArrayConverter
*/
private $converter;

/**
* @test
*/
/** @var Logstash|ObjectProphecy */
private $logstash;
/** @var LogEventMiddleware */
private $middleware;

/** @test */
public function it_logs_message_when_it_is_event()
{
$this->logger->info(Argument::cetera())->shouldBeCalled();
$this->converter->toArray(Argument::any())->willReturn([]);
$object = new \stdClass();

$this->middleware->handle($object, $this->dummyCallable());

$this->logstash->write($object)->shouldBeCalled();
$this->logger->error(Argument::cetera())->shouldNotBeCalled();
}

/** @test */
public function it_catches_exception_from_logstash_and_logs_erros()
{
$object = new \stdClass();
$this->logstash->write($object)->willThrow(CannotWriteToLogstash::class);

$this->sut->handle(new \stdClass(), $this->dummyCallable());
$this->middleware->handle($object, $this->dummyCallable());

$this->logger->error(Argument::cetera())->shouldBeCalled();
}

private function dummyCallable()
Expand All @@ -40,12 +46,20 @@ private function dummyCallable()
};
}

/** {@inheritdoc} */
protected function setUp()
{
parent::setUp();

$this->logger = $this->prophesize(LoggerInterface::class);
$this->converter = $this->prophesize(ObjectToArrayConverter::class);
$this->sut = new LogEventMiddleware($this->logger->reveal(), $this->converter->reveal());
$this->logstash = $this->prophesize(Logstash::class);

$this->middleware = new LogEventMiddleware($this->logstash->reveal(), $this->logger->reveal());
}

/** {@inheritdoc} */
protected function tearDown()
{
$this->logger = $this->prophesize(LoggerInterface::class);
$this->logstash = $this->prophesize(Logstash::class);
$this->middleware = null;
}
}
13 changes: 9 additions & 4 deletions tests/Converter/ObjectToArrayConverterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class ObjectToArrayConverterTest extends \PHPUnit_Framework_TestCase
{
/** @var ObjectToArrayConverter */
private $converter;

/** @var ObjectProphecy|Serializer */
private $serializer;

Expand All @@ -24,9 +23,7 @@ public function it_throws_exception_when_data_to_convert_is_not_object()
$this->converter->toArray('not-an-object');
}

/**
* @test
*/
/** @test */
public function it_serializes_objects()
{
$object = new \stdClass();
Expand All @@ -47,9 +44,17 @@ public function it_serializes_objects()
);
}

/** {@inheritdoc} */
public function setUp()
{
$this->serializer = $this->prophesize(Serializer::class);
$this->converter = new ObjectToArrayConverter($this->serializer->reveal());
}

/** {@inheritdoc} */
protected function tearDown()
{
$this->serializer = null;
$this->converter = null;
}
}
72 changes: 72 additions & 0 deletions tests/Logstash/LogstashTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace tests\Clearcode\SimpleBusElkBundle\Logstash;

use Clearcode\SimpleBusElkBundle\Converter\DataToConvertIsNotAnObject;
use Clearcode\SimpleBusElkBundle\Converter\ObjectToArrayConverterInterface;
use Clearcode\SimpleBusElkBundle\Logstash\Logstash;
use Prophecy\Prophecy\ObjectProphecy;
use Psr\Log\LoggerInterface;

class LogstashTest extends \PHPUnit_Framework_TestCase
{
/** @var LoggerInterface|ObjectProphecy */
private $logger;
/** @var ObjectToArrayConverterInterface|ObjectProphecy */
private $converter;
/** @var Logstash */
private $logstash;

/** @test */
public function it_can_write_log()
{
$object = new \stdClass();
$this->converter->toArray($object)->willReturn(['message' => 'hello world!']);

$this->logstash->write($object);

$this->logger->info('Event recorded', ['message' => 'hello world!'])->shouldBeCalled();
}

/**
* @test
* @expectedException \Clearcode\SimpleBusElkBundle\Logstash\CannotWriteToLogstash
*/
public function it_fails_when_connection_failed()
{
$object = new \stdClass();
$this->converter->toArray($object)->willReturn(['message' => 'hello world!']);
$this->logger->info('Event recorded', ['message' => 'hello world!'])->willThrow(\UnexpectedValueException::class);

$this->logstash->write($object);
}

/**
* @test
* @expectedException \Clearcode\SimpleBusElkBundle\Logstash\CannotWriteToLogstash
*/
public function it_fails_when_data_conversion_failed()
{
$object = new \stdClass();
$this->converter->toArray($object)->willThrow(DataToConvertIsNotAnObject::class);

$this->logstash->write($object);
}

/** {@inheritdoc} */
protected function setUp()
{
$this->logger = $this->prophesize(LoggerInterface::class);
$this->converter = $this->prophesize(ObjectToArrayConverterInterface::class);

$this->logstash = new Logstash($this->logger->reveal(), $this->converter->reveal());
}

/** {@inheritdoc} */
protected function tearDown()
{
$this->logger = null;
$this->converter = null;
$this->logstash = null;
}
}