Skip to content

Commit

Permalink
feat: add email support
Browse files Browse the repository at this point in the history
  • Loading branch information
kbond committed Nov 24, 2023
1 parent 5c06b0e commit 64151f8
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 3 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,14 @@ liip_monitor:
default_ttl: null
logging:
enabled: false
mailer:
enabled: false
recipient: [] # Required
sender: null
subject: 'Health Check Failed'
send_on_warning: false
send_on_skip: false
send_on_unknown: false
checks:
# fails/warns if system memory usage % is above thresholds
Expand Down
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
"phpstan/phpstan": "^1.4",
"phpunit/phpunit": "^9.5.0",
"symfony/http-client": "^6.3",
"symfony/mailer": "^6.3|^7.0",
"symfony/messenger": "^6.3|^7.0",
"symfony/phpunit-bridge": "^6.3|^7.0",
"symfony/process": "^6.3|^7.0",
"symfony/var-dumper": "^6.0|^7.0",
"zenstruck/console-test": "^1.4"
"zenstruck/console-test": "^1.4",
"zenstruck/mailer-test": "^1.4"
},
"config": {
"preferred-install": "dist",
Expand Down
14 changes: 14 additions & 0 deletions config/mailer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Liip\Monitor\Event\PostRunCheckSuiteEvent;
use Liip\Monitor\EventListener\MailerSubscriber;

return static function (ContainerConfigurator $container): void {
$container->services()
->set('.liip_monitor.mailer_subscriber', MailerSubscriber::class)
->args([service('mailer')])
->tag('kernel.event_listener', ['event' => PostRunCheckSuiteEvent::class, 'method' => 'afterSuite'])
;
};
24 changes: 24 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@ public function getConfigTreeBuilder(): TreeBuilder
->arrayNode('logging')
->canBeEnabled()
->end()
->arrayNode('mailer')
->canBeEnabled()
->children()
->arrayNode('recipient')
->isRequired()
->requiresAtLeastOneElement()
->scalarPrototype()->end()
->beforeNormalization()
->ifString()
->then(fn($v) => [$v])
->end()
->end()
->scalarNode('sender')
->defaultNull()
->end()
->scalarNode('subject')
->defaultValue('Health Check Failed')
->cannotBeEmpty()
->end()
->booleanNode('send_on_warning')->defaultFalse()->end()
->booleanNode('send_on_skip')->defaultFalse()->end()
->booleanNode('send_on_unknown')->defaultFalse()->end()
->end()
->end()
->arrayNode('checks')
->children()
;
Expand Down
7 changes: 7 additions & 0 deletions src/DependencyInjection/LiipMonitorExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
$loader->load('logging.php');
}

if ($mergedConfig['mailer']['enabled']) {
$loader->load('mailer.php');
$container->getDefinition('.liip_monitor.mailer_subscriber')
->setArgument('$config', $mergedConfig['mailer'])
;
}

$container->getDefinition('liip_monitor.check_registry')
->setArgument('$defaultTtl', $mergedConfig['default_ttl'])
;
Expand Down
88 changes: 88 additions & 0 deletions src/EventListener/MailerSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

/*
* This file is part of the liip/monitor-bundle package.
*
* (c) Liip
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Liip\Monitor\EventListener;

use Liip\Monitor\Event\PostRunCheckSuiteEvent;
use Liip\Monitor\Result\ResultContext;
use Liip\Monitor\Result\Status;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;

/**
* @author Kevin Bond <[email protected]>
*
* @internal
*/
final class MailerSubscriber
{
/**
* @param array{
* recipient: string[],
* sender: ?string,
* subject: string,
* send_on_warning: bool,
* send_on_skip: bool,
* send_on_unknown: bool,
* } $config
*/
public function __construct(private MailerInterface $mailer, private array $config)
{
}

public function afterSuite(PostRunCheckSuiteEvent $event): void
{
$results = $event->results();
$failureStatuses = [];

if ($this->config['send_on_warning']) {
$failureStatuses[] = Status::WARNING;
}

if ($this->config['send_on_skip']) {
$failureStatuses[] = Status::SKIP;
}

if ($this->config['send_on_unknown']) {
$failureStatuses[] = Status::UNKNOWN;
}

$defects = $results->defects(...$failureStatuses);

if (0 === $defects->count()) {
return;
}

$body = \implode(
"\n",
\array_map(
static fn(ResultContext $result) => \sprintf(
'[%s] %s',
$result->check(),
$result,
),
$defects->all(),
),
);

$message = (new Email())
->to(...$this->config['recipient'])
->subject($this->config['subject'])
->text($body)
;

if ($this->config['sender']) {
$message->from($this->config['sender']);
}

$this->mailer->send($message);
}
}
2 changes: 1 addition & 1 deletion tests/Fixture/CheckService2.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ public function __toString(): string

public function run(): Result
{
return Result::success();
return Result::failure('failed');
}
}
9 changes: 9 additions & 0 deletions tests/Fixture/TestKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
use Zenstruck\Mailer\Test\ZenstruckMailerTestBundle;

/**
* @author Kevin Bond <[email protected]>
Expand All @@ -32,6 +33,7 @@ public function registerBundles(): iterable
{
yield new FrameworkBundle();
yield new DoctrineBundle();
yield new ZenstruckMailerTestBundle();
yield new LiipMonitorBundle();
}

Expand All @@ -43,6 +45,9 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load
'router' => ['utf8' => true],
'test' => true,
'messenger' => true,
'mailer' => [
'dsn' => 'null://null',
],
]);

$c->loadFromExtension('doctrine', [
Expand All @@ -56,6 +61,10 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load

$c->loadFromExtension('liip_monitor', [
'logging' => true,
'mailer' => [
'sender' => '[email protected]',
'recipient' => '[email protected]',
],
'checks' => [
'system_memory_usage' => true,
'system_disk_usage' => true,
Expand Down
16 changes: 15 additions & 1 deletion tests/LiipMonitorBundleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
use Symfony\Component\Messenger\HandleTrait;
use Symfony\Component\Messenger\MessageBusInterface;
use Zenstruck\Console\Test\InteractsWithConsole;
use Zenstruck\Mailer\Test\InteractsWithMailer;
use Zenstruck\Mailer\Test\TestEmail;

/**
* @author Kevin Bond <[email protected]>
*/
final class LiipMonitorBundleTest extends KernelTestCase
{
use HandleTrait, InteractsWithConsole;
use HandleTrait, InteractsWithConsole, InteractsWithMailer;

/**
* @test
Expand Down Expand Up @@ -73,6 +75,18 @@ public function execute_health_command(): void
->assertOutputContains('OK Check Service 1: Success')
;

$this->mailer()
->assertEmailSentTo('[email protected]', function(TestEmail $email) {
$email
->assertFrom('[email protected]')
->assertSubjectContains('Health Check Failed')
->assertTextContains('[Custom Check Service 2] failed')
;
})
->sentEmails()
->assertCount(1)
;

$this->executeConsoleCommand('monitor:health -v') // verbose
->assertOutputContains('19 check executed')
;
Expand Down

0 comments on commit 64151f8

Please sign in to comment.