PHPackages                             outlined/laravel-sentinel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. outlined/laravel-sentinel

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

outlined/laravel-sentinel
=========================

Centralized application monitoring with Slack/Discord notifications for Laravel

v1.2.1(1mo ago)0536MITPHPPHP ^8.1

Since Dec 9Pushed 5mo agoCompare

[ Source](https://github.com/outlined-agence/laravel-sentinel)[ Packagist](https://packagist.org/packages/outlined/laravel-sentinel)[ Docs](https://github.com/outlined/laravel-sentinel)[ RSS](/packages/outlined-laravel-sentinel/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (29)Versions (9)Used By (0)

Laravel Sentinel
================

[](#laravel-sentinel)

[![Latest Version on Packagist](https://camo.githubusercontent.com/1205ebb61ff60ecbe2a84bb7c1175369b0580a39dc40a0fb3b174d48c5bbce58/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f75746c696e65642f6c61726176656c2d73656e74696e656c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/outlined/laravel-sentinel)[![Total Downloads](https://camo.githubusercontent.com/c151e1374dd82191b9904680c6c3bb180815b5f7238fc3e833b600b15ce920c3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6f75746c696e65642f6c61726176656c2d73656e74696e656c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/outlined/laravel-sentinel)[![License](https://camo.githubusercontent.com/65bef7d21b2f603a14527064590845ac2905f8dbad61e2d7c2117e2a1663fece/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6f75746c696e65642f6c61726176656c2d73656e74696e656c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/outlined/laravel-sentinel)

A comprehensive Laravel package for centralized application monitoring with Slack/Discord notifications, exception tracking, resource monitoring, and metrics collection.

Features
--------

[](#features)

- **Centralized Monitoring Service** - Injectable service for logging errors, business events, provider errors, and threshold alerts
- **Slack &amp; Discord Notifications** - Beautiful, formatted messages with colors, emojis, and attachments
- **Alert Deduplication** - Prevent alert spam by suppressing duplicate notifications
- **Rate Limiting** - Global rate limiting for notifications per channel
- **Exception Filtering** - Automatically filter common exceptions (404s, validation errors, etc.)
- **Sentry Integration** - Optional integration with Sentry for additional error tracking
- **Resource Monitoring** - Extensible system for monitoring external resources with threshold alerts
- **Prometheus/StatsD Metrics** - Export metrics for monitoring dashboards
- **Filament Dashboard** - Beautiful admin panel for viewing monitoring events
- **Database Storage** - Optional persistence of monitoring events

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10.0+ or 11.0+

Installation
------------

[](#installation)

Install via Composer:

```
composer require outlined/laravel-sentinel
```

Publish the configuration:

```
php artisan vendor:publish --tag=sentinel-config
```

(Optional) Publish and run migrations for database storage:

```
php artisan vendor:publish --tag=sentinel-migrations
php artisan migrate
```

Configuration
-------------

[](#configuration)

Add the following to your `.env` file:

```
# Enable/disable Sentinel
SENTINEL_ENABLED=true

# Slack configuration
SENTINEL_SLACK_ENABLED=true
SENTINEL_SLACK_WEBHOOK=https://hooks.slack.com/services/...
SENTINEL_SLACK_CHANNEL=#monitoring
SENTINEL_SLACK_MENTION_ID=U12345678

# Discord configuration (optional)
SENTINEL_DISCORD_ENABLED=false
SENTINEL_DISCORD_WEBHOOK=https://discord.com/api/webhooks/...

# Sentry integration
SENTINEL_SENTRY_ENABLED=true

# Database storage
SENTINEL_DATABASE_ENABLED=true
SENTINEL_RETENTION_DAYS=30

# Deduplication
SENTINEL_DEDUP_ENABLED=true
SENTINEL_DEDUP_TTL=3600

# Rate limiting
SENTINEL_RATE_LIMIT_ENABLED=true
SENTINEL_RATE_LIMIT_PER_MINUTE=30
SENTINEL_RATE_LIMIT_PER_HOUR=200

# Metrics (Prometheus/StatsD)
SENTINEL_METRICS_ENABLED=false
SENTINEL_METRICS_DRIVER=prometheus
```

Usage
-----

[](#usage)

### Via Facade

[](#via-facade)

```
use Outlined\Sentinel\Facades\Sentinel;

// Log an exception
Sentinel::logError($exception);
Sentinel::logError($exception, auth()->user(), ['order_id' => $order->id]);

// Log business events
Sentinel::logBusinessEvent('payment', false, 'Payment failed', [
    'order_id' => 123,
    'amount' => 99.99,
    'reason' => 'Card declined',
]);

Sentinel::logBusinessEvent('registration', true, 'New user registered', [
    'user_id' => $user->id,
    'source' => 'organic',
]);

// Log provider errors
Sentinel::logProviderError('Stripe', 'Card declined', [
    'customer_id' => 456,
    'error_code' => 'card_declined',
]);

// Log threshold alerts
Sentinel::logThresholdAlert(
    type: 'balance',
    message: 'Account balance is low',
    currentValue: 50.00,
    threshold: 100.00,
    critical: false
);
```

### Via Dependency Injection

[](#via-dependency-injection)

```
use Outlined\Sentinel\Services\MonitoringService;

class PaymentController
{
    public function __construct(
        private MonitoringService $monitoring
    ) {}

    public function process(Request $request)
    {
        try {
            // Process payment...
        } catch (PaymentException $e) {
            $this->monitoring->logError($e, auth()->user(), [
                'order_id' => $request->order_id,
            ]);
            throw $e;
        }
    }
}
```

### Temporarily Disable Monitoring

[](#temporarily-disable-monitoring)

```
// Disable/enable manually
Sentinel::disable();
Sentinel::enable();

// Execute code without monitoring
$result = Sentinel::withoutMonitoring(function () {
    // This code won't trigger any monitoring alerts
    return performSensitiveOperation();
});
```

Exception Handling
------------------

[](#exception-handling)

### Option 1: Use the Sentinel Exception Handler

[](#option-1-use-the-sentinel-exception-handler)

Replace your exception handler in `bootstrap/app.php` (Laravel 11):

```
use Outlined\Sentinel\Exceptions\SentinelExceptionHandler;

return Application::configure(basePath: dirname(__DIR__))
    ->withExceptions(function (Exceptions $exceptions) {
        $exceptions->handler(SentinelExceptionHandler::class);
    })
    ->create();
```

### Option 2: Use the Trait

[](#option-2-use-the-trait)

Add the trait to your existing exception handler:

```
use Outlined\Sentinel\Exceptions\ReportsToSentinel;

class Handler extends ExceptionHandler
{
    use ReportsToSentinel;

    public function report(Throwable $e): void
    {
        $this->reportToSentinelIfNeeded($e);
        parent::report($e);
    }
}
```

### Ignored Exceptions

[](#ignored-exceptions)

By default, these exceptions are ignored:

- `ValidationException`
- `AuthenticationException`
- `NotFoundHttpException` (404)
- `MethodNotAllowedHttpException`
- `TokenMismatchException`

Customize in `config/sentinel.php`:

```
'ignore_exceptions' => [
    \Illuminate\Validation\ValidationException::class,
    \App\Exceptions\CustomIgnoredException::class,
],

'ignore_http_codes' => [
    400, 401, 403, 404, 405, 408, 419, 422, 429,
],
```

Resource Monitoring
-------------------

[](#resource-monitoring)

Create custom resources to monitor:

```
use Outlined\Sentinel\Contracts\MonitorableResource;
use Outlined\Sentinel\Resources\AbstractResource;
use Outlined\Sentinel\Resources\ResourceStatus;

class StripeBalanceResource extends AbstractResource
{
    protected float $warningThreshold = 1000;
    protected float $criticalThreshold = 100;
    protected bool $higherIsBetter = true;

    public function getIdentifier(): string
    {
        return 'stripe_balance';
    }

    public function getName(): string
    {
        return 'Stripe Balance';
    }

    public function check(): ResourceStatus
    {
        try {
            $balance = \Stripe\Balance::retrieve();
            $available = $balance->available[0]->amount / 100;

            return $this->healthy($available, "Balance: \${$available}");
        } catch (\Exception $e) {
            return $this->failed("Failed to check balance: {$e->getMessage()}");
        }
    }
}
```

Register in `config/sentinel.php`:

```
'resources' => [
    \App\Monitoring\Resources\StripeBalanceResource::class,
    \App\Monitoring\Resources\DiskSpaceResource::class,
],
```

Check resources manually or via CRON:

```
# Check all resources
php artisan sentinel:check-resources

# Check specific resource
php artisan sentinel:check-resources --resource=stripe_balance

# Check without alerting
php artisan sentinel:check-resources --no-alert

# JSON output
php artisan sentinel:check-resources --json
```

Schedule in `routes/console.php`:

```
Schedule::command('sentinel:check-resources')->everyFiveMinutes();
```

Context Extractors
------------------

[](#context-extractors)

Add custom context to monitoring events:

```
use Outlined\Sentinel\Contracts\ContextExtractor;

class TenantContextExtractor implements ContextExtractor
{
    public function shouldExtract(string $eventType, array $context, ?Throwable $exception = null): bool
    {
        return true; // Always extract
    }

    public function extract(string $eventType, array $context, ?Throwable $exception = null): array
    {
        return [
            'tenant' => [
                'id' => tenant()?->id,
                'name' => tenant()?->name,
            ],
        ];
    }

    public function priority(): int
    {
        return 100;
    }
}
```

Register in `config/sentinel.php`:

```
'context_extractors' => [
    \App\Monitoring\TenantContextExtractor::class,
],
```

Filament Dashboard
------------------

[](#filament-dashboard)

If you have Filament installed, register the plugin:

```
use Outlined\Sentinel\Filament\SentinelPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            SentinelPlugin::make(),
        ]);
}
```

Customize in `config/sentinel.php`:

```
'filament' => [
    'enabled' => true,
    'navigation_group' => 'Monitoring',
    'navigation_icon' => 'heroicon-o-shield-check',
    'navigation_sort' => 100,
],
```

Metrics
-------

[](#metrics)

### Prometheus

[](#prometheus)

Install the Prometheus client:

```
composer require promphp/prometheus_client_php
```

Configure in `.env`:

```
SENTINEL_METRICS_ENABLED=true
SENTINEL_METRICS_DRIVER=prometheus
SENTINEL_PROMETHEUS_STORAGE=redis
```

Expose metrics endpoint:

```
// routes/web.php
use Outlined\Sentinel\Contracts\MetricsCollector;

Route::get('/metrics', function (MetricsCollector $metrics) {
    return response($metrics->render(), 200, [
        'Content-Type' => 'text/plain; charset=utf-8',
    ]);
});
```

### StatsD

[](#statsd)

```
SENTINEL_METRICS_ENABLED=true
SENTINEL_METRICS_DRIVER=statsd
SENTINEL_STATSD_HOST=127.0.0.1
SENTINEL_STATSD_PORT=8125
```

Artisan Commands
----------------

[](#artisan-commands)

```
# Send a test notification
php artisan sentinel:test
php artisan sentinel:test --level=error --message="Test error"

# Check monitored resources
php artisan sentinel:check-resources

# Prune old events
php artisan sentinel:prune
php artisan sentinel:prune --days=7
php artisan sentinel:prune --dry-run
```

Message Formatting
------------------

[](#message-formatting)

Customize colors and emojis in `config/sentinel.php`:

```
'formatting' => [
    'colors' => [
        'debug' => '#808080',
        'info' => '#3498db',
        'warning' => '#f39c12',
        'error' => '#e74c3c',
        'critical' => '#9b59b6',
    ],
    'emojis' => [
        'debug' => ':mag:',
        'info' => ':information_source:',
        'warning' => ':warning:',
        'error' => ':x:',
        'critical' => ':fire:',
    ],
    'include_stack_trace' => true,
    'stack_trace_lines' => 10,
],
```

Events
------

[](#events)

Listen to monitoring events:

```
use Outlined\Sentinel\Events\MonitoringEventLogged;

Event::listen(MonitoringEventLogged::class, function ($event) {
    // $event->level
    // $event->message
    // $event->context
});
```

Testing
-------

[](#testing)

```
composer test
composer test-coverage
composer analyse
```

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) for more information.

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance80

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~27 days

Total

5

Last Release

52d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f601f16cb1e56f1fc023165b963a488e7ccbdd551d6f5bd9bcf11b66a44918fa?d=identicon)[cabalex-out](/maintainers/cabalex-out)

---

Top Contributors

[![cabalex-out](https://avatars.githubusercontent.com/u/181862173?v=4)](https://github.com/cabalex-out "cabalex-out (12 commits)")

---

Tags

laravelloggingmonitoringslackexceptionssentryalertsdiscord

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/outlined-laravel-sentinel/health.svg)

```
[![Health](https://phpackages.com/badges/outlined-laravel-sentinel/health.svg)](https://phpackages.com/packages/outlined-laravel-sentinel)
```

###  Alternatives

[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[spatie/laravel-health

Monitor the health of a Laravel application

86910.0M83](/packages/spatie-laravel-health)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[shaffe/laravel-mail-log-channel

A package to support logging via email in Laravel

1286.2k](/packages/shaffe-laravel-mail-log-channel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
