A flexible and extensible service health monitoring package for Laravel.
This package helps you monitor the health of your application's critical services such as:
- Database connections
- Cache stores
- Queue connections
- Filesystem disks
- Redis connections
- External/internal HTTP endpoints
It includes:
- A web-based dashboard
- A JSON API endpoint
- An Artisan command for CLI / CI usage
- Built-in authorization layer
- Extensible architecture for adding custom inspectors
- Features
- Requirements
- Installation
- Publishing Assets
- Quick Start
- Routes
- Configuration
- Usage Examples
- Dashboard
- JSON API
- Artisan Command
- Authorization
- Custom Inspectors for Developers
- Status Model
- CI Ideas
- Testing
- Contributing
- License
- Monitor important Laravel services in one place
- Detect:
- healthy services
- degraded services
- failed services
- Measure response duration in milliseconds
- Configure slow thresholds per monitor
- Expose health results through:
- Dashboard page
- API endpoint
- CLI command
- Protect access using authorization middleware
- Add your own custom service inspectors
- Works with Laravel auto-discovery
- PHP
>= 8.2 - Laravel
11,12, or13
Package dependencies include:
illuminate/supportilluminate/httpilluminate/cacheilluminate/queueilluminate/filesystemilluminate/database
Install the package via Composer:
composer require mrtolouei/laravel-service-healthLaravel will automatically discover and register the package service provider.
Publish the package configuration file:
php artisan vendor:publish --tag=service-health-configThis creates:
config/service-health.php
If you want to define who can access the dashboard and API, publish the authorization provider stub:
php artisan vendor:publish --tag=service-health-providerThis creates:
app/Providers/HealthServiceServiceProvider.php
You can then register your own gate logic there.
If you want to customize the dashboard UI:
php artisan vendor:publish --tag=service-health-views composer require mrtolouei/laravel-service-health php artisan vendor:publish --tag=service-health-config
php artisan vendor:publish --tag=service-health-provider
php artisan vendor:publish --tag=service-health-views- Dashboard:
/service-health - API:
/service-health-api
php artisan service-health:checkPublish the authorization provider and define your gate rules.
By default, the package registers two routes:
GET /service-health
GET /service-health-api
These are configurable via:
'route' => [
'prefix' => env('SERVICE_HEALTH_ROUTE_PREFIX', ''),
'dashboard' => env('SERVICE_HEALTH_ROUTE_DASHBOARD', 'service-health'),
'api' => env('SERVICE_HEALTH_ROUTE_API', 'service-health-api'),
'middleware' => [
'web',
MrTolouei\ServiceHealth\Http\Middleware\Authorize::class,
],
],If you set:
SERVICE_HEALTH_ROUTE_PREFIX=admin/tools
SERVICE_HEALTH_ROUTE_DASHBOARD=health
SERVICE_HEALTH_ROUTE_API=health-apiRoutes become:
/admin/tools/health/admin/tools/health-api
Main config file:
config/service-health.php
'enabled' => env('SERVICE_HEALTH_ENABLED', true),Globally enables or disables the package routes.
If set to false, routes will not be registered.
'route' => [
'prefix' => env('SERVICE_HEALTH_ROUTE_PREFIX', ''),
'dashboard' => env('SERVICE_HEALTH_ROUTE_DASHBOARD', 'service-health'),
'api' => env('SERVICE_HEALTH_ROUTE_API', 'service-health-api'),
'middleware' => [
'web',
MrTolouei\ServiceHealth\Http\Middleware\Authorize::class,
],
],Controls route URLs and middleware.
'history_limit' => env('SERVICE_HEALTH_LIMIT_HISTORY', 20),Used by the dashboard for limiting displayed history items.
'refresh_interval' => env('SERVICE_HEALTH_REFRESH_INTERVAL', 3000),Dashboard refresh interval in milliseconds.
Example:
- 3000 = every 3 seconds
- 10000 = every 10 seconds
'expose_exception_messages' => env('SERVICE_HEALTH_EXPOSE_EXCEPTION_MESSAGES', true),Controls whether raw exception messages should be shown in results.
true: actual exception messages are exposedfalse: generic safe messages are returned
For production environments, you may prefer setting this to false.
Each monitor has a structure similar to this:
'monitor_name' => [
'enabled' => true,
'inspector' => SomeInspector::class,
'slow_threshold' => 20,
'connections' => [
...
],
],enabled
Whether this monitor is active.
inspector
The class responsible for performing the health check.
slow_threshold
If the check completes successfully but takes longer than this threshold (ms), the result becomes degraded instead of healthy.
connections
The list of things to inspect.
For some inspectors, each item is a string connection name.
For HttpInspector, each item is a full config array.
'database' => [
'enabled' => true,
'inspector' => MrTolouei\ServiceHealth\Inspectors\DatabaseInspector::class,
'slow_threshold' => 50,
'connections' => [
'mysql',
'analytics',
'tenant',
],
],This will create separate health results for each configured database connection.
'http' => [
'enabled' => true,
'inspector' => MrTolouei\ServiceHealth\Inspectors\HttpInspector::class,
'connections' => [
[
'name' => 'GitHub API',
'endpoint' => 'https://api.github.com',
'method' => 'GET',
'expected_status' => 200,
'headers' => [
'Accept' => 'application/json',
'User-Agent' => 'LaravelServiceHealth',
],
'timeout' => 5,
'slow_threshold' => 2000,
],
[
'name' => 'Payment Gateway Health',
'endpoint' => 'https://payments.example.com/health',
'method' => 'GET',
'expected_status' => 200,
'auth' => [
'type' => 'bearer',
'token' => env('PAYMENT_GATEWAY_TOKEN'),
],
'timeout' => 5,
'slow_threshold' => 1000,
],
],
],'http' => [
'enabled' => true,
'inspector' => MrTolouei\ServiceHealth\Inspectors\HttpInspector::class,
'connections' => [
[
'name' => 'Internal Admin API',
'endpoint' => 'https://internal.example.com/api/health',
'method' => 'GET',
'expected_status' => 200,
'headers' => [
'Accept' => 'application/json',
],
'auth' => [
'type' => 'basic',
'username' => env('INTERNAL_API_USER'),
'password' => env('INTERNAL_API_PASSWORD'),
],
'timeout' => 3,
'slow_threshold' => 800,
],
],
],The dashboard route renders a Blade view:
return view('service-health::dashboard');By default, it is available at:
/service-health
This dashboard is intended to give a quick visual overview of:
- service statuses
- degraded/failed services
- timings
- refresh-based updates
You may publish and customize the view if needed.
The API endpoint returns a structured JSON response including:
- checked_at
- summary
- services
Default route:
/service-health-api
- total
- healthy
- degraded
- failed
- average_duration
- slowest_service
- slowest_duration
- overall_status
- name
- status
- is_healthy
- is_degraded
- is_failed
- is_up
- message
- duration
- metadata
- type
- connection
Run checks via CLI:
php artisan service-health:check php artisan service-health:check --json- Prints a table of all services
- Returns failure exit code if any service has failed
- Returns success if all services are either healthy or degraded
This makes it useful for:
- deployment pipelines
- cron jobs
- uptime scripts
- container health checks
- infrastructure monitoring
The package uses this middleware by default:
MrTolouei\ServiceHealth\Http\Middleware\Authorize::classThat middleware delegates authorization to:
ServiceHealth::check($request)By default, if no custom auth callback is defined, access is only allowed in the local environment.
To customize this, publish the provider stub:
php artisan vendor:publish --tag=service-health-providerThen define your gate in the generated provider.
Example:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use MrTolouei\ServiceHealth\HealthServiceApplicationServiceProvider;
class HealthServiceServiceProvider extends HealthServiceApplicationServiceProvider
{
protected function gate(): void
{
Gate::define('viewHealthService', function ($user = null) {
return $user && $user->is_admin;
});
}
}You can also make access conditional by email, role, permission, environment, IP, or any custom logic.
One of the main strengths of this package is that you can create your own inspectors.
Every custom inspector must implement:
MrTolouei\ServiceHealth\Inspectors\InspectorInterfaceWhich requires:
public function monitor(): InspectorResult;Example: checking a third-party SDK, external service state, or internal app condition.
<?php
namespace App\Health;
use MrTolouei\ServiceHealth\DTOs\InspectorResult;
use MrTolouei\ServiceHealth\Inspectors\InspectorInterface;
use Throwable;
class MailProviderInspector implements InspectorInterface
{
public function __construct(protected string $connection)
{
}
public function monitor(): InspectorResult
{
$startedAt = microtime(true);
try {
// Example custom logic
$healthy = true;
$duration = round((microtime(true) - $startedAt) * 1000, 2);
return new InspectorResult(
name: "mail-provider:{$this->connection}",
status: $healthy
? InspectorResult::STATUS_HEALTHY
: InspectorResult::STATUS_FAILED,
message: $healthy
? 'Mail provider is healthy.'
: 'Mail provider is unavailable.',
duration: $duration,
metadata: [
'provider' => $this->connection,
],
type: 'mail',
connection: $this->connection,
);
} catch (Throwable $e) {
$duration = round((microtime(true) - $startedAt) * 1000, 2);
return new InspectorResult(
name: "mail-provider:{$this->connection}",
status: InspectorResult::STATUS_FAILED,
message: config('service-health.expose_exception_messages', true)
? $e->getMessage()
: 'Mail provider health check failed.',
duration: $duration,
metadata: [],
type: 'mail',
connection: $this->connection,
);
}
}
}Add it to your config:
'mail_provider' => [
'enabled' => true,
'inspector' => App\Health\MailProviderInspector::class,
'connections' => [
'postmark',
'ses',
],
],The package manager will automatically instantiate the inspector for each connection and include its results in:
- dashboard
- API
- Artisan command
You can include extra details in metadata:
metadata: [
'region' => 'eu-central-1',
'quota_remaining' => 1240,
'response_code' => 200,
],This is useful if you want the API consumers to understand more about the service state.
The package supports three statuses:
The service is available and responding within the acceptable threshold.
The service is working, but slower than expected.
The service is unavailable, returned unexpected results, or threw an exception.
You can use this package in CI/CD pipelines like this:
php artisan service-health:check --jsonPossible use cases:
- fail deployment if a critical dependency is down
- verify environment readiness after deployment
- expose health checks to orchestration systems
- monitor external API dependencies
You can also wrap the command inside cron or supervisor-based scripts.
Run tests using PHPUnit:
vendor/bin/phpunit- Fork the repository
- Create a feature branch (
feature/awesome-feature) - Commit your changes (
git commit -m 'Add new feature') - Push to the branch (
git push origin feature/awesome-feature) - Open a Pull Request
This package is open-sourced software licensed under the MIT license.
