michallkanak/symfony-open-system-monitor

Flexible monitoring bundle for Symfony applications with multi-channel notifications

Maintainers

Package info

github.com/michallkanak/symfony-open-system-monitor

Type:symfony-bundle

pkg:composer/michallkanak/symfony-open-system-monitor

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.1.0 2026-04-14 08:48 UTC

This package is not auto-updated.

Last update: 2026-04-15 20:09:08 UTC


README

Tests PHPStan Code Style Packagist Version Symfony Version PHP Version License

A flexible, extensible monitoring bundle for Symfony applications. Monitor URLs, routes, database entities, and custom metrics with configurable rules and multi-channel notifications.

Symfony Open System Monitor is a tool that watches over your website or application around the clock and instantly alerts you the moment something goes wrong β€” whether it's a page that stopped loading, a service that went down, or an unusual spike in errors or orders.

It goes far beyond simple URL checks. Unlike basic uptime monitors, this tool can look inside your system β€” monitoring database records, business processes, background services, and specific application behaviors. If payments stop being processed, invoices stop being sent, or a queue starts backing up, you'll know immediately β€” not hours later.

What Does It Do for You?

Problem How This Tool Helps
Your website goes down at night You get an instant alert via email, SMS, Telegram, or Slack
A critical page returns an error Automatic notification before customers notice
Orders stop being placed (but the site looks fine) Monitor your database β€” alert when no new orders arrive in X minutes
Payment processing silently fails Detect failed payment records and notify your team immediately
Emails or invoices stop being sent Track queue activity and catch issues before they pile up
A background job (cron) stops running Detect missing activity and alert before data gets stale
Inventory or stock data stops updating Monitor specific fields or record counts in your database
You want a status overview A secure, real-time dashboard shows everything at a glance

πŸ’¬ Got questions or need help getting started? Reach out β€” we're happy to discuss your needs, provide a custom setup, or simply answer any questions. Contact: kanakmichal[at]gmail.com

Status Dashboard

Compact table view with expandable activity logs:

Light mode: Light mode

Dark mode: Dark mode

Features

  • πŸ” Multiple Monitor Types: URL, routing, entity monitoring, custom query and extensible
  • πŸ“Š Flexible Storage: Database, filesystem, or Redis for logs and alert states
  • πŸ“§ Multi-Channel Notifications: Email, SMS, Telegram, Slack, Discord, webhooks, and extensible
  • πŸ”” Notification Profiles: Define channels once and reuse them across rules β€” no repetition
  • ⏰ Cron-Based Scheduling: Single cron entry with built-in frequency management
  • ⏰ Request-Based Scheduling: Execute monitoring every X requests
  • πŸ”§ Highly Extensible: Interface-based design for custom monitor types, conditions, and channels
  • πŸ“ˆ Status Dashboard: Optional password-protected monitoring overview
  • 🎯 Smart Alerting: Prevent duplicate notifications, recovery alerts, and reminders
  • πŸš€ Framework Support: Symfony 6.4-7.x (PHP >= 8.2)

Quick Start

Installation

composer require michallkanak/symfony-open-system-monitor

The bundle will be automatically registered via Symfony Flex.

Basic Configuration

Create config/packages/symfony_open_system_monitor.yaml:

symfony_open_system_monitor:
  storage:
    log_storage: database
    alert_state_storage: database

  status_page:
    enabled: true
    password: "%env(MONITOR_STATUS_PASSWORD)%"

  # Define notification profiles once β€” reuse across all rules
  notification_profiles:
    admin_email:
      channel: email
      config:
        to: "%env(MONITOR_EMAIL_TO)%"

  rules:
    - name: "Website Health Check"
      type: url
      config:
        url: "https://example.com/health"
        expected_status: 200
      schedule:
        cron: "*/5 * * * *"
      notifications:
        - use: admin_email # ← profile reference (or use inline: channel: email)

Environment Variables

Copy keys from .env.example to .env.local and configure:

# .env.local
MONITOR_STATUS_PASSWORD=your-secret-password-change-it
MONITOR_EMAIL_TO=admin@example.com

See .env.example for all available options (Telegram, Slack, Discord, SMS, webhooks).

Cron Setup

* * * * * php /path/to/project/bin/console monitor:run >> /dev/null 2>&1

Database Migration (Database Storage Only)

php bin/console doctrine:migrations:migrate

Access Status Page

Navigate to: https://your-domain.com/monitoring/status

Maintenance

Log Cleanup

Clean up old monitoring logs to prevent database/storage growth:

# Delete logs older than 30 days (default)
php bin/console monitor:logs:cleanup

# Delete logs older than 7 days
php bin/console monitor:logs:cleanup --days=7

# Preview what would be deleted (dry-run)
php bin/console monitor:logs:cleanup --dry-run

Recommended: Add to cron for automatic cleanup:

0 2 * * * php /path/to/project/bin/console monitor:logs:cleanup --days=30

Availability Statistics

Availability percentages are cached in AlertState and updated incrementally with each check run. This ensures optimal performance on the status page without recalculating stats on every request.

Documentation

Translations

The status dashboard supports multiple languages out of the box:

Language Code File
English en messages.en.yaml
Polish pl messages.pl.yaml
German de messages.de.yaml
Spanish es messages.es.yaml
French fr messages.fr.yaml
Italian it messages.it.yaml
Czech cs messages.cs.yaml
Slovak sk messages.sk.yaml

Configure in config/packages/translation.yaml:

framework:
  default_locale: en # or pl, de, es, fr, it, cs, sk

Monitor Types

URL Monitoring

type: url
config:
  url: "https://api.example.com/status"
  method: GET
  expected_status: 200
  timeout: 10

Entity Monitoring

type: entity
config:
  entity_class: "App\\Entity\\Order"
  field: "createdAt"
  conditions:
    - type: "count_new"
      time_period: "1 hour"
      operator: ">"
      threshold: 100

Available condition types: count_new, count_modified, avg_value, sum_value, min_max_value, distinct_count, exists, percentage_change, custom_query.

Routing Monitoring

type: routing
config:
  route: "app_api_health"
  expected_status: 200

Custom Query Monitoring

type: entity
config:
  entity_class: "App\\Entity\\Order"
  conditions:
    - type: "custom_query"
      dql: "SELECT COUNT(o) FROM App\\Entity\\Order o WHERE o.status = :status"
      parameters:
        status: "failed"
      operator: ">"
      threshold: 0
      description: "Failed orders exist"

Schedule & Alerting Options

Per-rule options for smart alerting:

schedule:
  cron: "*/5 * * * *"
  notify_on_recovery: true # alert when service recovers
  remind_on_failure: true # repeat alert while still failing
  remind_interval: 3600 # reminder repeat interval in seconds (default: 3600)

Notification Channels

  • Email - Symfony Mailer
  • SMS - SMSAPI integration
  • Telegram - Bot API
  • Slack - Webhooks
  • Webhook - Generic HTTP POST
  • Discord - Webhooks

Storage Options

  • Database - Doctrine ORM (MySQL, PostgreSQL, SQLite, etc.)
  • Filesystem - JSON files (default, zero dependencies)
  • Redis - High-performance via Predis
  • Custom - Implement LogStorageInterface / AlertStateStorageInterface and register as a service

Advanced Configuration

Request-Based Monitoring

Alternative to cron β€” runs checks every X HTTP requests via the kernel.terminate event:

symfony_open_system_monitor:
  request_based:
    enabled: true
    execute_every: 100

Notification Rate Limiting

Limit notifications per channel per hour to prevent alert spam:

symfony_open_system_monitor:
  rate_limits:
    email: 50
    sms: 10
    telegram: 100
    slack: 100
    discord: 100
    webhook: 100

Custom Notification Templates

Override built-in Twig templates with your own:

symfony_open_system_monitor:
  template_paths:
    - "%kernel.project_dir%/templates/monitoring"

Scheduler Tuning

symfony_open_system_monitor:
  scheduler:
    lock_timeout: 3600 # max seconds a lock is held (default: 3600)
    max_execution_time: 300 # max seconds per monitor run (default: 300)

Database-Stored Rules

Enable rules defined in the database in addition to YAML config:

symfony_open_system_monitor:
  enable_database_rules: true

Custom Status Page Path

symfony_open_system_monitor:
  status_page:
    enabled: true
    path: "/admin/monitor" # default: /monitoring/status
    password: "%env(MONITOR_STATUS_PASSWORD)%"

License

Free for personal projects and small companies (<100 employees) with attribution.

Commercial license required for organizations with 100+ employees.

See LICENSE for details. Contact: kanakmichal[at]gmail.com

Author

MichaΕ‚ Kanak - GitHub kanakmichal[at]gmail.com

Contributing

Contributions are welcome! Please read the contributing guidelines before submitting PRs.

Support