How To Use Sentinel

A complete guide to setting up and using Sentinel for error tracking across your Laravel applications.

Getting Started

1. Create your account

Sentinel does not have public registration. An administrator creates your account via the command line:

php artisan sentinel:create-user

You'll be prompted for your name, email, and password. The command outputs your public status page URL — save it for later.

2. Create a project

Each Laravel application you want to monitor is a "project" in Sentinel. Create one from the dashboard by clicking "New Project", or via CLI:

php artisan sentinel:create-project "My Laravel App"

This generates a unique API token that identifies this project. The token is shown once — copy it immediately. You'll need it in the next step.

3. Install the package & verify

See the Install the Package section below for complete setup instructions. Once configured, verify it works:

4. Verify it works

php artisan tinker

# Check the connection
>>> app(\UpgradeLabs\SentinelLaravel\SentinelClient::class)->isConfigured()
=> true

# Send a test error
>>> $r = app(\UpgradeLabs\SentinelLaravel\SentinelClient::class)->testReport()
>>> $r->status()
=> 201

Open your Sentinel dashboard — you should see the test error appear immediately.

Install the Package

Requirements

  • PHP 7.4 or higher
  • Laravel 8, 9, 10, 11, 12, or 13
  • The Laravel scheduler must be running for heartbeats (most production apps already have this)

Installation

composer require upgradelabs/sentinel-laravel

Configuration

The only required config is the API token:

SENTINEL_TOKEN=your-project-api-token

Optional settings you can add to .env:

VariableDefaultDescription
SENTINEL_TOKENRequired. Your project API token.
SENTINEL_ENABLEDtrueSet to false to disable all reporting.
SENTINEL_ENVIRONMENTSallComma-separated list of environments to report from. Example: production,staging
SENTINEL_QUEUEnullQueue name for async reporting. Recommended for production: default
SENTINEL_HEARTBEATtrueSet to false to disable automatic heartbeat pings.

Publish config (optional)

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

This creates config/sentinel.php where you can customize ignored exceptions, filtered fields, breadcrumb settings, and more.

What gets captured automatically

Every unhandled exception in your Laravel app is sent to Sentinel with:

  • Exception class, message, file, and line number
  • Full stack trace
  • Severity (auto-detected: fatal for Error, warning for warnings, notice for notices)
  • Laravel version, PHP version, and environment
  • Request URL, method, headers, and body (sensitive fields redacted)
  • Authenticated user (ID, email, name)
  • Custom context and breadcrumbs (if configured)
  • Performance data (if middleware is active)

Data privacy

The following fields are automatically redacted from request data before sending:

  • password, password_confirmation
  • token, secret
  • credit_card, card_number, cvv, ssn
  • Authorization, Cookie, and CSRF headers

You can customize the filtered fields in config/sentinel.php.

Ignored exceptions

By default, these exceptions are not reported:

  • NotFoundHttpException (404 errors)
  • ValidationException
  • AuthenticationException
  • MethodNotAllowedHttpException

Customize in config/sentinel.php under ignored_exceptions.

Queue support

For production apps, send error reports via a queue to avoid blocking requests:

SENTINEL_QUEUE=default

Reports are dispatched as queued jobs with 3 retries and 10-second backoff. If all retries fail, the failure is silently discarded (no infinite loops).

Laravel 8/9 manual setup

For older Laravel versions where automatic reportable() registration may not work, add the trait to your exception handler:

// app/Exceptions/Handler.php
use UpgradeLabs\SentinelLaravel\ReportsToSentinel;

class Handler extends ExceptionHandler
{
    use ReportsToSentinel;

    public function register(): void
    {
        $this->reportable(function (\Throwable $e) {
            $this->reportToSentinel($e);
        });
    }
}

Dashboard

The dashboard is your control center. It shows a real-time overview of all your monitored applications.

Offline alert

A red banner appears at the top if any of your applications have stopped sending heartbeats for more than 10 minutes. Each offline project is listed with its last heartbeat time.

Stats cards

Four cards showing:

  • Projects — total number of monitored applications
  • Total Errors — all-time error count with total occurrences
  • Unresolved — errors that haven't been resolved or ignored
  • Today — errors seen today, plus all-time resolved count

Error trend chart

A 14-day line chart showing error occurrence volume. Hover over any point to see the exact count for that day.

Severity breakdown

A horizontal bar chart showing unresolved errors grouped by severity: Fatal, Error, Warning, Notice, Info.

Project cards

Quick-access cards for your top 6 projects, showing name, environment, Laravel version, error count, and a red/green badge for unresolved errors.

Recent errors table

The last 8 errors across all projects with status dot (pulsing red = unresolved, green = resolved, gray = ignored), project name, exception class, message, severity badge, occurrence count, and relative time.

Global search

The search bar in the sidebar searches across all your errors in all projects by exception class, message, or file name. Results appear in a dropdown with direct links to the error detail page.

Projects

Creating a project

Click "New Project" on the Projects page. Enter a name, and Sentinel generates a unique API token. The token is shown once in a yellow banner — copy it immediately.

Project detail page

Each project shows:

  • Header — project name, active/inactive badge, environment, Laravel version, PHP version, URL
  • AI Health Report — click "Generate Report" for a comprehensive 5-day AI analysis
  • Smart Grouping — AI suggests which unresolved errors might share a root cause
  • Error trend chart — 14-day chart specific to this project, with deploy markers below
  • Deploy timeline — vertical timeline of recent deployments with version, branch, deployer
  • Error table — full list with status, exception, message, file, severity, count, last seen

Filtering errors

The error table supports:

  • Search — filter by exception class, message, or file name
  • Status filter — Unresolved, Resolved, Ignored
  • Severity filter — Fatal, Error, Warning, Notice, Info

Batch actions

Select multiple errors using the checkboxes, then use the batch action bar to:

  • Resolve — mark all selected as resolved
  • Ignore — mark all selected as ignored
  • Unresolve — reopen all selected
  • Delete — permanently delete all selected and their occurrences

Use "Select All" checkbox in the header to select all errors on the current page.

Project settings

Click the gear icon to open settings:

  • API Endpoint — the URL your package sends errors to
  • Integration example — ready-to-copy code for manual integration
  • Read API Access — toggle to allow/deny external tools from reading this project's data via API
  • Regenerate API Token — invalidates the current token and generates a new one

Error Detail

Click any error to see the full detail page.

Header actions

  • Bookmark — pin this error for quick access (amber star icon)
  • Resolve — mark as fixed
  • Ignore — dismiss this error
  • Unresolve — reopen a resolved/ignored error
  • Delete — permanently remove the error and all occurrences

Error details card

Shows the full exception message, file:line, and a link back to the project.

Statistics card

Total occurrence count, first seen date, and last seen date with relative time.

AI Analysis

Click "Analyze Error" to get an AI-powered analysis streamed in real-time. Includes root cause, how to fix (with code examples), and prevention tips. Can be re-analyzed anytime.

Cross-project matches

If the same exception class appears in other projects, an amber banner shows which projects are affected — with links to each.

Notes

Add annotations that persist across occurrences. Use them for "known issue — waiting for vendor fix" or any context your team needs. Each note shows author and relative time.

Resolution history

Every status change (resolve, ignore, reopen) is logged with who did it and when. Shows as a timeline below the notes.

Occurrences

Each time the error happens, a new occurrence is recorded. Each occurrence shows:

  • Timestamp, environment, Laravel version, PHP version
  • Request URL and method (if applicable)
  • Stack trace — collapsible, syntax-highlighted
  • Request data — query params, body, headers (sensitive data redacted)
  • User data — authenticated user ID, email, name
  • Context — custom context data, breadcrumbs, performance metrics, previous exception chain

Individual occurrences can be deleted without affecting the error log itself.

AI Analysis

Sentinel integrates with Claude (by Anthropic) to provide AI-powered error analysis. You need an Anthropic API key — set it up in Settings > Integrations.

Error Analysis

On any error detail page, click "Analyze Error". Claude receives the full error context (exception, stack trace, request data, environment) and streams back:

  • Root Cause — why the error happened, referencing specific files and lines
  • How to Fix — concrete code changes with before/after examples
  • Prevention — best practices to avoid recurrence

Project Health Report

On any project page, click "Generate Report". Claude analyzes all errors from the last 5 days and produces:

  • Health Score (0-100 with color indicator)
  • Executive Summary
  • Critical Issues
  • Recurring Patterns
  • Trend Analysis
  • Prioritized Recommendations (immediate, short-term, long-term)
  • Architecture Insights

Smart Grouping

Click "Analyze" in the Smart Grouping card. Claude examines all unresolved errors and identifies ones that likely share the same root cause, even when the exception classes or files differ.

Weekly Digest

Every Monday at 8:00 AM, Sentinel generates an AI-powered weekly summary and emails it to all users. Includes error stats, top offenders, and the most important thing to fix.

Deploy Tracking

Record deployments so you can correlate errors with releases.

Artisan command (recommended)

# Auto-detect from git (tag, commit hash, branch)
php artisan sentinel:deploy --auto

# With explicit values
php artisan sentinel:deploy --tag=1.2.0 --deployer="GitHub Actions"

# All options
php artisan sentinel:deploy \
  --auto \
  --tag=1.2.0 \
  --environment=production \
  --deployer="Forge" \
  --description="Fix payment bug"

--auto detects the current git tag (as version), commit hash, and branch name automatically.

CI/CD integration

GitHub Actions:

- name: Notify Sentinel
  run: php artisan sentinel:deploy --auto --deployer="GitHub Actions"

Laravel Forge deploy script:

php artisan sentinel:deploy --auto --deployer="Forge"

Deploy timeline

Deploys appear on the project detail page in two places:

  • Chart markers — blue badges below the error trend chart showing the date and version of each deploy
  • Timeline sidebar — vertical timeline with version, environment, branch, deployer, description, and relative time

Heartbeat & Status

How heartbeats work

The Sentinel package automatically pings the dashboard every 5 minutes via the Laravel scheduler. This tells Sentinel your app is alive.

  • Requires the standard Laravel cron: * * * * * php artisan schedule:run
  • If no heartbeat is received for 10+ minutes, the project is marked as Offline
  • When the project recovers, it automatically returns to Online

Offline alerts

When a project goes offline:

  • A red banner appears at the top of the dashboard
  • A critical email is sent to the project owner with project name, last heartbeat time, environment, and URL
  • A Slack/Discord webhook alert is sent (if configured)
  • The downtime period is logged (start time, end time, duration)

Alerts are sent only once per offline event — no spam. The flag resets when the project comes back online.

Public status page

Each user gets a unique public status page URL:

https://sentinel.upgradelabs.pt/status/your-slug-abc123

The page shows all your active projects with their heartbeat status:

  • Online (green) — heartbeat received within 10 minutes
  • Offline (red, pulsing) — heartbeat older than 10 minutes
  • Waiting (gray) — no heartbeat received yet

The page auto-refreshes every 60 seconds. Share it with clients or teammates.

Test a heartbeat

php artisan tinker
>>> app(\UpgradeLabs\SentinelLaravel\SentinelClient::class)->heartbeat()
// Returns: {"message": "pong", "project": "...", "timestamp": "..."}

Notifications

Configure in Settings > Notifications.

Email alerts

Toggle the master switch to enable/disable all email notifications. Configure either:

  • SMTP — host, port, username, password, encryption (TLS/SSL)
  • Amazon SES — AWS access key, secret, region

Set the "From" address and name. Use "Send Test Email" to verify your configuration.

Webhook alerts

Add Slack and/or Discord webhook URLs. New errors send rich formatted messages with:

  • Exception class, severity, file, message
  • "View in Sentinel" button
  • Color-coded by severity

Alert rules

Create threshold-based rules per project: "Alert if X errors occur in Y minutes." When triggered, the webhook fires (with cooldown to prevent spam).

Auto-resolve

In Settings > General, configure how many days of inactivity before errors are auto-resolved. Default: 14 days. Set to 0 to disable.

Context & Breadcrumbs

Custom context

Add custom data that gets attached to any error occurring during the request:

use UpgradeLabs\SentinelLaravel\SentinelContext;

// In a controller, middleware, or service
SentinelContext::set([
    'order_id' => 123,
    'payment_method' => 'stripe',
    'subscription_plan' => 'pro',
]);

The data appears in the error occurrence's "Context" section. Automatically cleared after each error report.

Breadcrumbs

Breadcrumbs track the sequence of events leading up to an error. They're enabled by default.

Auto-captured:

  • Database queries (SQL, execution time, connection name)
  • Cache hits and misses (disabled by default — enable in config)
  • Queue job processing

Manual breadcrumbs:

SentinelContext::breadcrumb('payment', 'Charging customer', ['amount' => 99.99]);
SentinelContext::breadcrumb('api', 'Called Stripe API', ['endpoint' => '/charges']);

Up to 50 breadcrumbs per request. Oldest are dropped when the limit is reached.

Performance tracking

Add the middleware to track request duration and memory usage:

// bootstrap/app.php (Laravel 11+)
->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        \UpgradeLabs\SentinelLaravel\Middleware\TrackSentinelPerformance::class,
    ]);
})

Each error report will include duration_ms and memory_peak_mb in the context.

Log Channel

Send Laravel log entries to Sentinel alongside your regular log files:

// config/logging.php
'channels' => [
    'sentinel' => [
        'driver' => 'custom',
        'via' => \UpgradeLabs\SentinelLaravel\SentinelLogChannel::class,
        'level' => 'error',
    ],
],

Then add it to your stack or use it directly:

// .env — add sentinel to the stack
LOG_STACK=daily,sentinel

// Or log explicitly
Log::channel('sentinel')->error('Payment failed', ['order_id' => 123]);

Log levels are mapped to Sentinel severities: emergency/alert/critical = fatal, error = error, warning = warning, notice = notice, info/debug = info.

Read API

Pull data from Sentinel into external tools like Grafana or custom dashboards. Read API must be enabled per project in the project settings.

All endpoints use Bearer token authentication (same token as the reporting package).

Endpoints

MethodEndpointDescription
POST/api/v1/reportSend error report (always available)
POST/api/v1/deployRecord deployment (always available)
GET/api/v1/healthHeartbeat ping (always available)
GET/api/v1/statsProject statistics (requires read access)
GET/api/v1/errorsList errors, paginated (requires read access)
GET/api/v1/deploysDeployment history (requires read access)
GET/api/v1/downtimeDowntime periods (requires read access)

Filtering errors

# Unresolved errors only
GET /api/v1/errors?status=unresolved

# Fatal severity
GET /api/v1/errors?severity=fatal

# Custom page size
GET /api/v1/errors?per_page=50

Example: project stats

curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://sentinel.upgradelabs.pt/api/v1/stats

# Response:
{
  "project": "My App",
  "environment": "production",
  "laravel_version": "13.0",
  "total_errors": 847,
  "unresolved_errors": 23,
  "last_error_at": "2026-03-29T...",
  "last_heartbeat_at": "2026-03-30T...",
  "is_online": true
}

Settings

Profile

Update your name and email address.

Security

Change your password, configure two-factor authentication (TOTP), and manage passkeys for passwordless login.

Appearance

Theme settings (dark mode is the default).

General

Auto-Resolve — set the number of days after which errors that haven't recurred are automatically resolved. Set to 0 to disable.

Notifications

  • Email Alerts — master toggle + SMTP or SES configuration
  • Webhooks — Slack and Discord webhook URLs

Integrations

Anthropic API Key — required for AI analysis features. Get your key from console.anthropic.com. The key is stored encrypted in the database.

Multi-user

Sentinel supports multiple users. Each user has their own isolated workspace:

  • Projects — each project belongs to one user
  • Errors, deploys, downtime — all scoped to the project owner
  • Status page — each user gets their own public URL
  • Notifications — error alerts go to the project owner
  • Dashboard — shows only your projects and errors

User A cannot see User B's data. There is no public registration — administrators create accounts via:

php artisan sentinel:create-user

Languages

The entire UI is available in 6 languages:

  • English (default)
  • Portuguese (Portugal)
  • Spanish
  • German
  • French
  • Italian

Switch language from the user menu in the sidebar, or from the language selector on the login and homepage. Your preference is saved to your account.

Artisan Commands

Sentinel Dashboard

CommandDescription
sentinel:create-userCreate a new user account (interactive)
sentinel:create-project {name?}Create a project and show its API token
sentinel:projectsList all projects
sentinel:projects --regenerate=slugRegenerate API token for a project
sentinel:auto-resolveAuto-resolve stale errors (runs daily)
sentinel:check-heartbeatsCheck for offline projects (runs every 5 min)
sentinel:weekly-digestSend AI weekly digest email (runs Mondays 8am)

Client Package

CommandDescription
sentinel:deploy --autoNotify Sentinel of a deploy (auto-detects from git)
sentinel:deploy --tag=1.0 --deployer="Forge"Deploy with explicit values