Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Monitor Bundle Laravel Package

liip/monitor-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to Begin

  1. Installation:

    composer require liip/monitor-bundle
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        Liip\MonitorBundle\LiipMonitorBundle::class => ['all' => true],
    ];
    
  2. 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');
        }
    }
    
  3. Register the Check: Tag the service in config/services.yaml:

    services:
        App\Monitor\Check\DatabaseCheck:
            tags: ['liip_monitor.check']
    
  4. Run Checks: Access the monitor endpoint at /_monitor (or configure a custom route).


First Use Case: Basic Application Health

  • Purpose: Verify core dependencies (database, cache, external APIs) are operational.
  • Example: A 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');
        }
    }
    

Implementation Patterns

Common Workflows

  1. Dependency Validation:

    • Use checks to validate external services (e.g., payment gateways, SMS providers).
    • Example: 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());
            }
        }
    }
    
  2. Environment-Specific Checks:

    • Conditionally enable checks based on environment (e.g., APP_ENV=prod).
    • Use Symfony’s parameter bag or environment variables:
    # config/packages/liip_monitor.yaml
    liip_monitor:
        checks:
            - App\Monitor\Check\SentryCheck  # Only enabled in prod
    
  3. Composite Checks:

    • Group checks into logical units (e.g., "Database Cluster Health").
    • Implement 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);
        }
    }
    
  4. Scheduled Checks:

    • Run checks on a cron job (e.g., via Symfony Messenger or a separate CLI command).
    • Example command:
    php bin/console liip:monitor:run --format=json > /var/log/monitor.json
    

Integration Tips

  1. Symfony Messenger:

    • Dispatch check results as messages for async processing:
    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();
        }
    }
    
  2. Prometheus Metrics:

    • Export check results to Prometheus for observability:
    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();
        }
    }
    
  3. Slack/Email Alerts:

    • Integrate with 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
            }
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Performance Overhead:

    • Issue: Heavy checks (e.g., full database queries) may slow down the monitor endpoint.
    • Fix: Use checkTimeout in config to limit execution time:
      liip_monitor:
          check_timeout: 2.0  # 2 seconds
      
    • Workaround: Offload checks to background jobs (e.g., Symfony Messenger).
  2. Stateful Checks:

    • Issue: Checks that modify state (e.g., writing to a cache) may cause flaky results.
    • Fix: Ensure checks are idempotent and use unique keys:
      $item = $this->cache->getItem('monitor_test_' . uniqid());
      
  3. Dependency Injection:

    • Issue: Checks may fail if dependencies (e.g., Doctrine, Redis) are misconfigured.
    • Fix: Test checks in isolation using PHPUnit:
      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());
          }
      }
      
  4. Caching Results:

    • Issue: Frequent checks (e.g., every request) may hit rate limits (e.g., external APIs).
    • Fix: Cache results with a short TTL:
      liip_monitor:
          cache_results: true
          cache_ttl: 30  # 30 seconds
      

Debugging

  1. Verbose Output:

    • Enable debug mode to see raw check results:
      php bin/console debug:monitor
      
    • Or configure in config/packages/dev/liip_monitor.yaml:
      liip_monitor:
          debug: true
      
  2. Check-Specific Logging:

    • Log detailed errors for failed checks:
    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());
        }
    }
    
  3. Environment Mismatches:

    • Issue: Checks pass locally but fail in production due to environment differences.
    • Fix: Use APP_ENV-aware checks:
    if ('prod' !== $_ENV['APP_ENV']) {
        return CheckResult::ok('Skipped in non-prod');
    }
    

Extension Points

  1. Custom Check Result Formats:

    • Extend CheckResult to add custom metadata:
    class ExtendedCheckResult extends CheckResult
    {
        public static function okWithData(array $data): self
        {
            return new self(true, 'OK', $data);
        }
    }
    
  2. Dynamic Check Registration:

    • Register checks programmatically (e.g., via compiler passes):
    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');
        }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor