Installation:
composer require liip/monitor-bundle
Add the bundle to config/bundles.php:
return [
// ...
Liip\MonitorBundle\LiipMonitorBundle::class => ['all' => true],
];
First Health Check:
Create a custom check class (e.g., src/Monitor/Check/DatabaseCheck.php):
namespace App\Monitor\Check;
use Liip\MonitorBundle\Check\CheckInterface;
use Liip\MonitorBundle\Check\CheckResult;
use Doctrine\DBAL\Connection;
class DatabaseCheck implements CheckInterface
{
public function __construct(private Connection $connection) {}
public function check(): CheckResult
{
return $this->connection->getSchemaManager()->listTableNames()
? CheckResult::ok()
: CheckResult::fail('Database connection failed');
}
}
Register the Check:
Tag the service in config/services.yaml:
services:
App\Monitor\Check\DatabaseCheck:
tags: ['liip_monitor.check']
Run Checks:
Access the monitor endpoint at /_monitor (or configure a custom route).
CacheCheck to validate Redis/Memcached connectivity:
use Liip\MonitorBundle\Check\CheckResult;
use Psr\Cache\CacheItemPoolInterface;
class CacheCheck implements CheckInterface
{
public function __construct(private CacheItemPoolInterface $cache) {}
public function check(): CheckResult
{
$item = $this->cache->getItem('monitor_test');
return $item->isHit() ? CheckResult::ok() : CheckResult::fail('Cache unavailable');
}
}
Dependency Validation:
PaymentGatewayCheck that pings Stripe/PayPal APIs.class PaymentGatewayCheck implements CheckInterface
{
public function check(): CheckResult
{
try {
\Stripe\Stripe::testMode();
\Stripe\PaymentIntent::create(['amount' => 100, 'currency' => 'usd']);
return CheckResult::ok();
} catch (\Exception $e) {
return CheckResult::fail($e->getMessage());
}
}
}
Environment-Specific Checks:
APP_ENV=prod).# config/packages/liip_monitor.yaml
liip_monitor:
checks:
- App\Monitor\Check\SentryCheck # Only enabled in prod
Composite Checks:
Liip\MonitorBundle\Check\CompositeCheckInterface:class DatabaseClusterCheck implements CompositeCheckInterface
{
public function check(): CheckResult
{
$results = [];
foreach ($this->getChecks() as $check) {
$results[] = $check->check();
}
return CheckResult::composite($results);
}
}
Scheduled Checks:
php bin/console liip:monitor:run --format=json > /var/log/monitor.json
Symfony Messenger:
use Liip\MonitorBundle\Check\CheckResult;
use Symfony\Component\Messenger\MessageBusInterface;
class AsyncMonitorCheck implements CheckInterface
{
public function __construct(private MessageBusInterface $bus) {}
public function check(): CheckResult
{
$this->bus->dispatch(new MonitorResultMessage(CheckResult::ok()));
return CheckResult::ok();
}
}
Prometheus Metrics:
use Liip\MonitorBundle\Check\CheckResult;
use Prometheus\CollectorRegistry;
class PrometheusCheck implements CheckInterface
{
public function __construct(private CollectorRegistry $registry) {}
public function check(): CheckResult
{
$result = $this->registry->getOrRegisterCounter('app_health_checks_total', '...');
$result->inc();
return CheckResult::ok();
}
}
Slack/Email Alerts:
liip/monitor-bundle's events to trigger alerts:// src/EventListener/MonitorListener.php
use Liip\MonitorBundle\Event\CheckResultEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MonitorListener implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [CheckResultEvent::NAME => 'onCheckResult'];
}
public function onCheckResult(CheckResultEvent $event): void
{
if (!$event->getResult()->isOk()) {
// Send Slack/email alert
}
}
}
Performance Overhead:
checkTimeout in config to limit execution time:
liip_monitor:
check_timeout: 2.0 # 2 seconds
Stateful Checks:
$item = $this->cache->getItem('monitor_test_' . uniqid());
Dependency Injection:
use Liip\MonitorBundle\Check\CheckResult;
class DatabaseCheckTest extends \PHPUnit\Framework\TestCase
{
public function testCheck()
{
$check = new DatabaseCheck($this->createMock(Connection::class));
$this->assertTrue($check->check()->isOk());
}
}
Caching Results:
liip_monitor:
cache_results: true
cache_ttl: 30 # 30 seconds
Verbose Output:
php bin/console debug:monitor
config/packages/dev/liip_monitor.yaml:
liip_monitor:
debug: true
Check-Specific Logging:
public function check(): CheckResult
{
try {
// Risky operation
return CheckResult::ok();
} catch (\Exception $e) {
\Monolog\Logger::getInstance('monitor')->error('Check failed', ['exception' => $e]);
return CheckResult::fail($e->getMessage());
}
}
Environment Mismatches:
APP_ENV-aware checks:if ('prod' !== $_ENV['APP_ENV']) {
return CheckResult::ok('Skipped in non-prod');
}
Custom Check Result Formats:
CheckResult to add custom metadata:class ExtendedCheckResult extends CheckResult
{
public static function okWithData(array $data): self
{
return new self(true, 'OK', $data);
}
}
Dynamic Check Registration:
use Liip\MonitorBundle\DependencyInjection\Compiler\RegisterChecksPass;
class CustomCheckPass extends RegisterChecksPass
{
public function process(\Symfony\Component\DependencyInjection\ContainerBuilder $container)
{
$definition = $container->findDefinition('app.custom_check');
$definition->addTag('liip_monitor.check');
}
How can I help you explore Laravel packages today?