jmonitor / easyadmin-bundle
Live monitoring pages inside EasyAdmin: system, PHP, FrankenPHP, Apache, Nginx, MySQL, PostgreSQL, Redis and Symfony metrics collected when you open the page, no worker required.
Package info
github.com/jmonitor/easyadmin-bundle
Type:symfony-bundle
pkg:composer/jmonitor/easyadmin-bundle
Requires
- php: ^8.2
- composer-runtime-api: ^2.0
- easycorp/easyadmin-bundle: ^5.2
- jmonitor/collector: ^2.4.0
- psr/cache: ^1.0|^2.0|^3.0
- psr/container: ^1.1|^2.0
- psr/log: ^2.0|^3.0
- symfony/asset: ^6.4|^7.0|^8.0
- symfony/cache: ^6.4|^7.0|^8.0
- symfony/clock: ^6.4|^7.0|^8.0
- symfony/config: ^6.4|^7.0|^8.0
- symfony/console: ^6.4|^7.0|^8.0
- symfony/dependency-injection: ^6.4|^7.0|^8.0
- symfony/framework-bundle: ^6.4|^7.0|^8.0
- symfony/http-foundation: ^6.4|^7.0|^8.0
- symfony/http-kernel: ^6.4|^7.0|^8.0
- symfony/process: ^6.4|^7.0|^8.0
- symfony/routing: ^6.4|^7.0|^8.0
- symfony/security-csrf: ^6.4|^7.0|^8.0
- symfony/service-contracts: ^2.5|^3.0
- symfony/twig-bundle: ^6.4|^7.0|^8.0
- twig/twig: ^3.15
Requires (Dev)
- doctrine/doctrine-bundle: ^2.13|^3.0
- friendsofphp/php-cs-fixer: ^3.86
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.5
- predis/predis: ^2.0|^3.0
- symfony/browser-kit: ^6.4|^7.0|^8.0
- symfony/css-selector: ^6.4|^7.0|^8.0
- symfony/ux-twig-component: ^2.20|^3.0
- symfony/yaml: ^6.4|^7.0|^8.0
- twig/extra-bundle: ^3.15
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
This bundle adds live monitoring pages to your EasyAdmin backend: system, PHP, FrankenPHP, Apache, Nginx, MySQL, PostgreSQL, Redis and Symfony metrics, collected when you open the page and refreshed while it stays open.
No worker to run, nothing to store.
| jmonitor/jmonitor |
jmonitor/collector |
jmonitor/jmonitor-bundle |
|---|---|---|
| Self-hostable backend — not needed with the cloud version | The collectors — install them in the project to monitor | Symfony-specific integration of the collectors |
|
jmonitor/easyadmin-bundle Live monitoring pages inside EasyAdmin — no backend, no worker |
||
| https://jmonitor.io | ||
Supported components
| Category | Components |
|---|---|
| Runtime | |
| Web server | |
| Framework | |
| Databases & cache | |
| System |
Requirements
Getting started
1. Install the bundle
composer require jmonitor/easyadmin-bundle
If you do not use Symfony Flex, add the bundle to config/bundles.php and install its assets:
return [ // ... Jmonitor\EasyAdminBundle\JmonitorEasyAdminBundle::class => ['all' => true], ];
php bin/console assets:install
2. Add a menu link
In your dashboard controller, link to the <dashboard route>_jmonitor_index route (admin is the route name of your dashboard, adapt it):
public function configureMenuItems(): iterable { // ... yield MenuItem::linkToRoute('Monitoring', 'internal:desktop', 'admin_jmonitor_index'); }
The pages live under the path of your dashboard (/admin/jmonitor for a dashboard at /admin), so the access_control rule protecting your backend covers them.
Configuration
Everything is optional. Components are detected from your application.
# config/packages/jmonitor_easyadmin.yaml jmonitor_easyadmin: cache_pool: cache.app # PSR-6 pool keeping the collected metrics polling_interval: 10 # seconds between two live refreshes, 0 disables them static_ttl: 3600 # seconds during which versions, configuration and OS data are kept permission: ~ # role or voter attribute required to see the pages, e.g. ROLE_SUPER_ADMIN exclude_connections: [] # Doctrine connections the MySQL and PostgreSQL tabs leave out, e.g. '*_backup' components: system: auto # auto | true | false php: auto frankenphp: enabled: auto endpoint: http://localhost:2019/metrics # Prometheus endpoint of the Caddy admin API apache: enabled: auto endpoint: http://localhost/server-status # mod_status page, read as ?auto nginx: enabled: auto endpoint: http://localhost/nginx_status # stub_status page symfony: enabled: auto messenger: true # runs "messenger:stats", defaults to true when Messenger is installed on Symfony 7.2+ scheduler: true # runs "debug:scheduler", defaults to true when Scheduler is installed flex: true # runs "composer recipes", defaults to true when Flex is installed mysql: enabled: auto connections: [] # Doctrine connection names, empty = every MySQL/MariaDB connection postgresql: enabled: auto connections: [] # Doctrine connection names, empty = every PostgreSQL connection schema: public # schema whose tables feed the storage, scans and dead rows cards redis: enabled: auto connections: [] # id => DSN, {dsn} or {service}; empty = the Symfony cache provider or REDIS_URL
auto shows the component when it is detected. true always shows it, with the detection error when it fails. false removes it.
permission restricts the pages to the users granted that role or voter attribute, on every dashboard, on top of the security of the dashboard itself; the others get a 403. Hide the menu link the same way: MenuItem::linkToRoute(...)->setPermission('ROLE_SUPER_ADMIN').
connections lists the Doctrine connections to show, each one becoming a pill under the tabs (MySQL groups them by server: a pill per server, then the databases of the selected server); a connection named here is always shown, with its error when it cannot be read. A PostgreSQL connection may have its own schema: connections: { default: ~, dwh: { schema: analytics } }. The former connection option still works and is deprecated.
exclude_connections leaves out of the MySQL and PostgreSQL tabs the Doctrine connections whose name matches one of its patterns, with the * and ? wildcards: the connections your application declares but does not serve, for instance exclude_connections: ['*_backup']. A connection listed in connections cannot match it.
For Redis, connections maps an id to a DSN, { dsn: ... } or { service: ... } (a \Redis, \Predis\Client or \Relay\Relay service), each one becoming a pill: connections: { cache: 'redis://localhost', sessions: { dsn: 'redis://sessions:6379/1' }, queue: { service: app.redis_queue } }.
Compared to jmonitor.io
This bundle shows the present only: nothing is collected while nobody looks at the page, and nothing is kept.
jmonitor.io, the cloud edition, collects your metrics continuously with a worker and keeps their history: the dashboards draw their charts, and alerts notify you by email when a threshold is crossed or a version reaches its end of life.
Both use the same collectors and run side by side: install jmonitor/jmonitor-bundle, fill its API key and run its worker to send the same metrics to jmonitor.io.
Good to know
- System: Linux only.
- FrankenPHP: needs the
metricsglobal option in the Caddyfile ({ metrics }), andfrankenphpin thePATHof the web process for the version. - Apache: needs a
mod_statuspage at/server-status(SetHandler server-status,Require local), left out of the rewrite toindex.php. When Apache runs in another container than PHP, pointcomponents.apache.endpointat it. - Nginx: needs
location = /nginx_status { stub_status; allow 127.0.0.1; deny all; }in the server block answeringlocalhost. When Nginx runs in another container than PHP, pointcomponents.nginx.endpointat it. - MySQL: the slow queries need read access to the
performance_schema. - PostgreSQL: the slow queries need the
pg_stat_statementsextension andGRANT pg_monitor TO <your role>. - Symfony: the Messenger stats need Symfony 7.2+, the Flex recipes
composerin thePATHof the web process. - Load balancer: the System, PHP, web server and Symfony tabs show the server that answered; in containers, give each one its own
hostname. - Outbound requests: the version badges come from endoflife.date and the update badges of the Overview from GitHub, once a day; the requests carry no data about your application.
Security
- The pages show data meant for administrators, such as query texts, which may hold personal data.
- They answer under every dashboard of the application, linked from its menu or not: with a dashboard for less trusted users, set
permissionor add anaccess_controlrule on^/<dashboard path>/jmonitor. - A dashboard
hostdoes not apply to these pages: restrict the host in the firewall or inaccess_control. - Keep the Caddy admin API, the
mod_statuspage and thestub_statuspage reachable from the web host only. - With a Content-Security-Policy, allow
https://dash.jmonitor.ioinframe-srcfor the help panel.
Need help?
- Anything about this bundle — installation, configuration, the pages in EasyAdmin: open an issue on this repo https://github.com/jmonitor/easyadmin-bundle/issues
- Anything about a metric — a missing or wrong value, a collector that does not gather what you expect: open an issue on https://github.com/jmonitor/collector/issues
- Anything about the help pages or jmonitor.io itself: open an issue on https://github.com/jmonitor/jmonitor/issues
- To report a vulnerability, see SECURITY.md.

