PHPackages                             ahmedmerza/logscope - 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. ahmedmerza/logscope

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

ahmedmerza/logscope
===================

A fast, database-backed log viewer for Laravel applications

v1.5.1(2mo ago)269[2 issues](https://github.com/AhmedMerza/laravel-logscope/issues)1MITPHPPHP ^8.2

Since Jan 20Pushed 2mo agoCompare

[ Source](https://github.com/AhmedMerza/laravel-logscope)[ Packagist](https://packagist.org/packages/ahmedmerza/logscope)[ RSS](/packages/ahmedmerza-logscope/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (14)Versions (28)Used By (1)

LogScope
========

[](#logscope)

[![Latest Version](https://camo.githubusercontent.com/255a916e087a564bfaf7f9a63aafa9e6da9281e8d585d3410af405b8a05b6bdb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f61686d65646d65727a612f6c6f6773636f70652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ahmedmerza/logscope)[![License](https://camo.githubusercontent.com/a2433598416c95aacb94e1ae36ec397f3336d51ab6d43de19777a075a97d4f21/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f61686d65646d65727a612f6c6f6773636f70652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ahmedmerza/logscope)[![PHP Version](https://camo.githubusercontent.com/543d4fafc416213a7c4bbd8fd16dcb41fb40cbabfd0f292c66b3e363e1dbbd65/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f61686d65646d65727a612f6c6f6773636f70652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ahmedmerza/logscope)

A beautiful, database-backed log viewer for Laravel applications. Production-ready.

[![LogScope Screenshot](art/logscope-preview.png)](art/logscope-preview.png)

Quick Start
-----------

[](#quick-start)

```
composer require ahmedmerza/logscope
php artisan logscope:install
php artisan migrate
```

Visit `/logscope` in your browser. That's it!

---

What's New
----------

[](#whats-new)

### v1.5.0 — Performance Overhaul

[](#v150--performance-overhaul)

To understand how LogScope holds up at scale, we stress-tested against a SQLite database with **1,000,052 log entries** — significantly more than a typical production deployment (weekly pruning keeps most installs around 400k). The results exposed three fixable bottlenecks.

ScenarioBeforeAfterImprovementFirst page load20.6 ms0.6 ms**34× faster**Page 10029.4 ms1.2 ms**25× faster**Page 1,00095.3 ms6.4 ms**15× faster**Filtered query461.4 ms0.7 ms**659× faster**Response payload47.7 KB29.4 KB**38% smaller****What changed and why:**

**1. Narrow SELECT on the list query**The list was running `SELECT *`, fetching full `message` and `context` columns (up to 48 KB per row × 50 rows) that the list view never renders — it only shows short previews. Full content still loads, but only when you open a specific entry.

**2. Keyset (cursor) pagination instead of OFFSET**`LIMIT 50 OFFSET 49950` tells the database to scan and throw away 49,950 rows before returning your 50. Cursor pagination stores a `(occurred_at, id)` bookmark and jumps directly — O(1) regardless of depth. In practice most users find what they need on page 1, but it means deep pagination no longer degrades.

**3. No COUNT on filtered queries**Laravel's paginator ran a `COUNT(*)` with all active filters on every page change to compute total pages. On large filtered result sets this was the dominant cost — most of the 461 ms on filtered queries.

**The trade-off:** when filters are active, the count is capped at 1,000 and shows "1,000+" beyond that. The real unfiltered total is still shown with no extra cost (it comes from the cached stats). When you're actively filtering you're in *find mode* — "1,000+ errors in the last hour" tells you everything actionable. Knowing the exact number beyond that doesn't change what you do next.

---

### v1.4.2 — Responsive Design &amp; Stability

[](#v142--responsive-design--stability)

Full responsive layout for mobile, tablet, and desktop. The sidebar, log table, detail panel, and filters all adapt to screen size. LogScope is now usable from a phone.

Also in v1.4.x: fixed a filter race condition with debounce + AbortController, pivot filtering from the detail panel (trace ID / user ID / IP), and several stability fixes.

---

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#-features)
- [Requirements](#-requirements)
- [When to Use LogScope](#-when-to-use-logscope)
- [Installation](#-installation)
- [Configuration](#%EF%B8%8F-configuration)
- [Usage](#-usage)
- [Production Deployment](#-production-deployment)
- [Customization](#-customization)
- [Contributing](#-contributing)
- [License](#-license)

---

✨ Features
----------

[](#-features)

FeatureDescription**Zero-Config Capture**Automatically captures ALL logs from ALL channels**Request Context**Trace ID, user ID, IP, URL, and user agent for every log**Advanced Search**Search syntax (`field:value`), regex support, NOT toggle**Smart Filters**Include/exclude by level, channel, HTTP method, date range**Active Filters Bar**See all active filters at a glance, clear individually**Channel Search**Search and filter channels when you have many**JSON Viewer**Syntax-highlighted, collapsible JSON with copy support**Smart Context**Auto-expand Request/Model objects, redact sensitive data**Status Workflow**Track logs as open, investigating, resolved, or ignored**Log Notes**Add investigation notes to any log entry**Quick Filters**One-click filters for common queries**Keyboard Shortcuts**14 shortcuts for navigation, status changes, and actions**Dark Mode**Full dark mode support with persistence**Shareable URLs**Current filters reflected in URL for sharing**Deep Linking**Link directly to specific log entries**Performance**Keyset pagination, batch writes, query optimization, proper indexing---

📋 Requirements
--------------

[](#-requirements)

- PHP 8.2+
- Laravel 10, 11, or 12
- SQLite, MySQL, or PostgreSQL

---

🤔 When to Use LogScope
----------------------

[](#-when-to-use-logscope)

LogScope stores logs in your database - a deliberate choice that works great for most Laravel apps.

**Great fit if you:**

- Want log visibility without external services
- Have a typical Laravel app (up to ~100K requests/day)
- Need rich search and filtering
- Prefer simplicity over infrastructure complexity

**Consider alternatives if you:**

- Process millions of requests daily
- Need months/years of log retention
- Already use centralized logging (Datadog, CloudWatch, ELK)

**How LogScope handles common concerns:**

ConcernSolutionDatabase bloatRetention policies with scheduled pruning (default: 30 days)PerformanceBatch mode writes logs *after* response is sentQuery speedProper indexes on common filter combinations---

📦 Installation
--------------

[](#-installation)

```
composer require ahmedmerza/logscope
```

Run the install command:

```
php artisan logscope:install
php artisan migrate
```

Access the dashboard at `/logscope`.

---

⚙️ Configuration
----------------

[](#️-configuration)

After installation, configure LogScope in `config/logscope.php` or via environment variables.

### Capture Mode

[](#capture-mode)

```
# 'all' (default) - Capture all logs automatically
# 'channel' - Only capture logs sent to the logscope channel
LOGSCOPE_CAPTURE=all
```

### Write Mode (Performance)

[](#write-mode-performance)

```
# 'batch' (default) - Buffer logs, write after response
# 'sync' - Write immediately (simple, but slower)
# 'queue' - Queue each log entry (best for high-traffic)
LOGSCOPE_WRITE_MODE=batch

# Queue settings (when using 'queue' mode)
LOGSCOPE_QUEUE=default
LOGSCOPE_QUEUE_CONNECTION=
```

### Retention

[](#retention)

```
LOGSCOPE_RETENTION_ENABLED=true
LOGSCOPE_RETENTION_DAYS=30
```

> **Note:** Retention requires scheduling `logscope:prune` - see [Schedule Pruning](#schedule-pruning).

### Features

[](#features)

```
LOGSCOPE_FEATURE_STATUS=true       # Enable status workflow
LOGSCOPE_FEATURE_NOTES=true        # Add notes to logs
```

### Noise Reduction

[](#noise-reduction)

```
# Filter out noisy logs
LOGSCOPE_IGNORE_DEPRECATIONS=true  # Skip "is deprecated" messages (default: true)
LOGSCOPE_IGNORE_NULL_CHANNEL=false # Skip logs without a channel (default: false)
```

> **Note:** `null_channel` defaults to `false` because `Log::build()` (dynamic loggers) produce logs without a channel. Setting this to `true` would filter out those logs.

### Cache TTL

[](#cache-ttl)

```
# How long (in seconds) to cache stats and filter options (levels, channels, etc.)
# Set to 0 to disable caching
LOGSCOPE_CACHE_TTL=60
```

### JSON Viewer

[](#json-viewer)

Configure collapsible JSON behavior in `config/logscope.php`:

```
'json_viewer' => [
    'collapse_threshold' => 5,  // Auto-collapse arrays/objects larger than this
    'auto_collapse_keys' => ['trace', 'stack_trace', 'stacktrace', 'backtrace'],
],
```

### Routes

[](#routes)

```
LOGSCOPE_ROUTES_ENABLED=true
LOGSCOPE_ROUTE_PREFIX=logscope
LOGSCOPE_DOMAIN=
LOGSCOPE_FORBIDDEN_REDIRECT=/
LOGSCOPE_UNAUTHENTICATED_REDIRECT=/login
```

Add middleware and configure error redirects:

```
'routes' => [
    'middleware' => ['web', 'auth'],
    'forbidden_redirect' => '/',           // Where to redirect on 403 (access denied)
    'unauthenticated_redirect' => '/login', // Where to redirect on 401/419 (session expired)
],
```

### Error Handling

[](#error-handling)

LogScope handles errors gracefully with toast notifications:

ErrorBehavior401/419 (Session expired)Toast + redirect to `unauthenticated_redirect`403 (Access denied)Toast + redirect to `forbidden_redirect`429 (Rate limited)Toast only (retry later)500+ (Server error)Toast only (temporary issue)Network errorToast only (check connection)> **Note:** Redirect URLs can be relative paths (`/login`) or absolute URLs (`https://auth.example.com/login`).

---

🚀 Usage
-------

[](#-usage)

### Automatic Capture

[](#automatic-capture)

All logs are captured automatically - no code changes needed:

```
Log::info('User logged in', ['user_id' => 1]);
Log::channel('slack')->error('Payment failed');
Log::stack(['daily', 'slack'])->warning('Low inventory');
```

### Keyboard Shortcuts

[](#keyboard-shortcuts)

KeyAction`j` / `k`Navigate down / up`h` / `l`Previous / next page`r`Refresh data`Enter`Open detail panel`Esc`Close panel`/`Focus search`y`Copy context (yank)`n`Focus note field`c`Clear all filters`d`Toggle dark mode`?`Show keyboard help**Status shortcuts** (require Shift, filter by status): | `O` | Open | `I` | Investigating | `R` | Resolved | `X` | Ignored |

Action shortcuts (`r`, `h`, `l`) and status shortcuts are configurable — see [Keyboard Shortcuts](#keyboard-shortcuts).

### Search Syntax

[](#search-syntax)

Type directly in the search box using `field:value` syntax:

SyntaxExampleDescription`field:value``message:error`Search in specific field`-field:value``-level:debug`Exclude matches`field:"value"``message:"user login"`Quoted values with spaces`text``error`Search in all fields`-text``-deprecated`Exclude from all fields**Searchable fields:** `message`, `source`, `context`, `level`, `channel`, `user_id`, `ip_address`, `url`, `trace_id`, `http_method`

> **Tip:** Request context filters (trace ID, user ID, IP, URL) support partial matching. Type `192.168` to find all IPs starting with that prefix, or `42` to find user IDs containing "42".

> **Tip:** Click on trace ID, user ID, or IP address in the detail panel to pivot your investigation — severity, channel, status, and search filters are cleared so nothing is hidden. Your date range is preserved.

**Examples:**

```
# Find errors in the API channel
channel:api level:error

# Find payment logs excluding debug
channel:payment -level:debug

# Find logs mentioning a specific user ID
user_id:123

# Find logs containing "timeout" anywhere
timeout

# Find logs with "connection failed" in message
message:"connection failed"

# Find context containing a job ID
context:abc123

# Exclude deprecated warnings
-message:deprecated

# Combine multiple conditions
level:error channel:database message:timeout

# Find all POST requests
http_method:POST

# Find logs from specific URL path
url:/api/payments

# Exclude health check endpoints
-url:/health -url:/ping

# Find logs from specific IP range
ip_address:192.168

# Track a specific request by trace ID
trace_id:abc-123-def
```

**Regex mode:** Click the `.*` button to enable regex patterns:

```
# Match error OR warning levels
level:error|warning

# Match any payment-related message
message:payment.*failed

# Match IP addresses starting with 192.168
ip_address:192\.168\.\d+\.\d+
```

Both search syntax and regex can be disabled in config if not needed.

### Status Workflow

[](#status-workflow)

Logs have a status workflow: **Open** → **Investigating** → **Resolved** or **Ignored**.

Customize who changed the status:

```
// In AppServiceProvider::boot()
use LogScope\LogScope;

LogScope::statusChangedBy(function ($request) {
    return $request->user()?->name;
});
```

#### Customize Statuses

[](#customize-statuses)

Override built-in statuses or add new ones in `config/logscope.php`:

```
'statuses' => [
    // Override built-in status
    'investigating' => [
        'label' => 'In Progress',
        'color' => 'blue',
    ],
    // Add custom statuses
    'waiting' => [
        'label' => 'Waiting for Customer',
        'color' => 'orange',
        'closed' => false,  // Shows in "Needs Attention"
    ],
    'duplicate' => [
        'label' => 'Duplicate',
        'color' => 'purple',
        'closed' => true,   // Hidden from "Needs Attention"
    ],
],
```

Available colors: `gray`, `yellow`, `green`, `slate`, `blue`, `red`, `orange`, `purple`

### Quick Filters

[](#quick-filters)

Configure one-click filters in `config/logscope.php`:

```
'quick_filters' => [
    ['label' => 'Today', 'icon' => 'calendar', 'from' => 'today'],
    ['label' => 'Recent Errors', 'icon' => 'alert', 'levels' => ['error', 'critical'], 'from' => '-24 hours'],
    ['label' => 'Needs Attention', 'icon' => 'filter', 'statuses' => ['open', 'investigating']],
    ['label' => 'Resolved Today', 'icon' => 'filter', 'statuses' => ['resolved'], 'from' => 'today'],
],
```

Available options: `label`, `icon` (calendar/clock/alert/filter), `levels`, `statuses`, `from`, `to`

### Status Shortcuts

[](#status-shortcuts)

Each status has a default keyboard shortcut (uppercase, requires Shift). Customize in `config/logscope.php`:

```
'statuses' => [
    // Disable a shortcut
    'ignored' => ['shortcut' => null],
    // Custom status with shortcut
    'waiting' => ['label' => 'Waiting', 'color' => 'orange', 'shortcut' => 'w'],
],
```

### Keyboard Shortcuts

[](#keyboard-shortcuts-1)

Action shortcuts (refresh, pagination) are configurable or can be disabled:

```
'keyboard_shortcuts' => [
    'refresh'   => 'r',  // Refresh logs and stats
    'prev_page' => 'h',  // Previous page
    'next_page' => 'l',  // Next page
],
```

Set any shortcut to `null` to disable it:

```
'keyboard_shortcuts' => [
    'prev_page' => null,  // Disable previous page shortcut
    'next_page' => null,
],
```

### Authorization

[](#authorization)

LogScope uses a flexible auth system (checked in order):

**1. Custom Callback:**

```
LogScope::auth(fn ($request) => $request->user()?->isAdmin());
```

**2. Gate:**

```
Gate::define('viewLogScope', fn ($user) => $user->hasRole('admin'));
```

**3. Default:** Only accessible in `local` environment.

### Custom Context

[](#custom-context)

Add custom data to every log entry (e.g., API token ID, tenant ID):

```
// In AppServiceProvider::boot()
use LogScope\LogScope;

LogScope::captureContext(function ($request) {
    return [
        'token_id' => $request->user()?->currentAccessToken()?->id,
        'tenant_id' => $request->user()?->tenant_id,
    ];
});
```

This data is merged into the log's `context` field and appears in the JSON viewer.

### Artisan Commands

[](#artisan-commands)

```
# Import existing log files (one-time migration)
php artisan logscope:import
php artisan logscope:import storage/logs/laravel.log --days=7

# Prune old logs
php artisan logscope:prune
php artisan logscope:prune --dry-run
php artisan logscope:prune --days=14
```

> **Note:** The import command is a one-time migration for existing log files. After setup, new logs are captured automatically.

---

🏭 Production Deployment
-----------------------

[](#-production-deployment)

### Recommended Settings

[](#recommended-settings)

```
LOGSCOPE_WRITE_MODE=batch
LOGSCOPE_RETENTION_DAYS=14
LOG_LEVEL=info
```

### Schedule Pruning

[](#schedule-pruning)

```
// Laravel 11+ (routes/console.php)
Schedule::command('logscope:prune')->daily();

// Laravel 10 (app/Console/Kernel.php)
$schedule->command('logscope:prune')->daily();
```

### High-Traffic Apps

[](#high-traffic-apps)

For thousands of requests/day:

1. Use queue mode with a dedicated queue:

    ```
    LOGSCOPE_WRITE_MODE=queue
    LOGSCOPE_QUEUE=logs
    ```
2. Run a separate queue worker:

    ```
    php artisan queue:work --queue=logs
    ```
3. Consider shorter retention (7 days).

---

🎨 Customization
---------------

[](#-customization)

### Theme

[](#theme)

Customize the appearance in `config/logscope.php`:

```
'theme' => [
    // Primary accent color (buttons, links, selections)
    'primary' => '#10b981',

    // Default to dark mode for new users (users can toggle and preference is saved)
    'dark_mode_default' => true,

    // Google Fonts (set to false to use system fonts)
    'fonts' => [
        'sans' => 'Outfit',         // UI text
        'mono' => 'JetBrains Mono', // Code/logs
    ],

    // Log level badge colors
    'levels' => [
        'error' => ['bg' => '#dc2626', 'text' => '#ffffff'],
        'warning' => ['bg' => '#f59e0b', 'text' => '#1f2937'],
        // ... other levels
    ],
],
```

**Disable external fonts** (use system fonts instead):

```
'fonts' => [
    'sans' => false,
    'mono' => false,
],
```

### Context Sanitization

[](#context-sanitization)

LogScope automatically expands objects in your log context for better debugging:

```
// Request objects show useful data
Log::info('API request', ['request' => $request]);
// Context: { "request": { "_type": "request", "method": "POST", "url": "...", "input": {...} } }

// Models and Arrayable objects are converted
Log::info('User action', ['user' => $user]);
// Context: { "user": { "name": "John", "email": "..." } }
```

**Sensitive data is automatically redacted** (password, token, api\_key, credit\_card, etc.):

```
Log::info('Login', ['request' => $request]);
// Input: { "email": "john@example.com", "password": "[REDACTED]" }
```

Configure in `config/logscope.php`:

```
'context' => [
    'expand_objects' => true,      // Set false to show [Object: ClassName]
    'redact_sensitive' => true,    // Set false to disable redaction (not recommended)
    'sensitive_keys' => [],        // Empty = use defaults, or provide your own list
    'sensitive_headers' => [],     // Empty = use defaults, or provide your own list
],
```

### Publishing Assets

[](#publishing-assets)

```
php artisan vendor:publish --tag=logscope-config
php artisan vendor:publish --tag=logscope-migrations
php artisan vendor:publish --tag=logscope-views
```

### All Environment Variables

[](#all-environment-variables)

```
# Capture & Performance
LOGSCOPE_CAPTURE=all
LOGSCOPE_WRITE_MODE=batch
LOGSCOPE_QUEUE=default
LOGSCOPE_QUEUE_CONNECTION=

# Features
LOGSCOPE_FEATURE_STATUS=true
LOGSCOPE_FEATURE_NOTES=true
LOGSCOPE_FEATURE_SEARCH_SYNTAX=true
LOGSCOPE_FEATURE_REGEX=true
LOGSCOPE_IGNORE_DEPRECATIONS=true
LOGSCOPE_IGNORE_NULL_CHANNEL=false

# Database & Retention
LOGSCOPE_TABLE=log_entries
LOGSCOPE_RETENTION_ENABLED=true
LOGSCOPE_RETENTION_DAYS=30
LOGSCOPE_MIGRATIONS_ENABLED=true

# Routes
LOGSCOPE_ROUTES_ENABLED=true
LOGSCOPE_ROUTE_PREFIX=logscope
LOGSCOPE_DOMAIN=
LOGSCOPE_MIDDLEWARE_ENABLED=true
LOGSCOPE_FORBIDDEN_REDIRECT=/
LOGSCOPE_UNAUTHENTICATED_REDIRECT=/login

# Search
LOGSCOPE_SEARCH_DRIVER=database

# Cache
LOGSCOPE_CACHE_TTL=60

# Context Sanitization
LOGSCOPE_EXPAND_OBJECTS=true
LOGSCOPE_REDACT_SENSITIVE=true
```

---

🤝 Contributing
--------------

[](#-contributing)

Contributions are welcome! Please open an issue or submit a pull request.

---

📄 License
---------

[](#-license)

MIT License. See [LICENSE](LICENSE) for details.

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance65

Regular maintenance activity

Popularity14

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity57

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 ~1 days

Total

26

Last Release

78d ago

Major Versions

v0.6.1 → v1.0.02026-01-26

### Community

Maintainers

![](https://www.gravatar.com/avatar/f5d8ff95e92a6d88388e9e13d09513a5734012c14a22c5e3a8c6c43acd3bcdf1?d=identicon)[AhmedMerza](/maintainers/AhmedMerza)

---

Top Contributors

[![AhmedMerza](https://avatars.githubusercontent.com/u/67040497?v=4)](https://github.com/AhmedMerza "AhmedMerza (3 commits)")

---

Tags

laravelloggingmonitoringdebugginglogslog viewer

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/ahmedmerza-logscope/health.svg)

```
[![Health](https://phpackages.com/badges/ahmedmerza-logscope/health.svg)](https://phpackages.com/packages/ahmedmerza-logscope)
```

###  Alternatives

[spatie/laravel-health

Monitor the health of a Laravel application

85810.0M83](/packages/spatie-laravel-health)[rollbar/rollbar-laravel

Rollbar error monitoring integration for Laravel projects

14110.4M7](/packages/rollbar-rollbar-laravel)[yadahan/laravel-authentication-log

Laravel Authentication Log provides authentication logger and notification for Laravel.

416632.8k5](/packages/yadahan-laravel-authentication-log)[kssadi/log-tracker

A powerful, intuitive, and efficient log viewer for Laravel applications.

264.8k](/packages/kssadi-log-tracker)[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)
