alex-kudrya/laravel-log-viewer

A Laravel package for browsing application log files from a protected web UI.

Maintainers

Package info

gitlab.com/alexkudrya91/laravel-log-viewer

Issues

pkg:composer/alex-kudrya/laravel-log-viewer

Statistics

Installs: 106

Dependents: 0

Suggesters: 0

Stars: 1

v1.11.3 2026-06-17 10:31 UTC

README

Total Downloads Version License PHP Version Require

Laravel Log Viewer

Laravel Log Viewer is a package for browsing Laravel log files from a protected web interface. It lists regular .log files from storage/logs, displays parsed records, supports search and filters, and can let authorized users download the selected log file.

Features

  • Lists only regular readable .log files from storage/logs.
  • Ignores archives and rotated non-log files such as .log.gz, .log.1, .zip, .tar, and .php.
  • Parses standard Laravel records with date, time, environment, level, message, JSON context, and stack trace.
  • Supports search, date/time filters, environment filters, and log level filters.
  • Supports light, dark, and system themes.
  • Includes English, Russian, and Ukrainian translations.
  • Reads large files with bounded memory usage and shows the latest records by default.
  • Limits scanned bytes, displayed records, displayed payload, listed files, search input, parsed context, stack traces, and single-record size to avoid exhausting server resources.
  • Marks partial results and truncated records instead of failing on very large logs or stack traces.
  • Can disable raw log downloads while keeping the bounded web viewer available.
  • Uses published local UI assets instead of loading Bootstrap, Bootstrap Icons, or jQuery from external CDNs.

Requirements

  • PHP >= 8.2
  • Laravel 10.x, 11.x, 12.x, or 13.x

Installation

Install the package with Composer:

composer require alex-kudrya/laravel-log-viewer

The service provider is registered through Laravel package auto-discovery. If package discovery is disabled in your application, register the provider manually:

// config/app.php

'providers' => [
    AlexKudrya\LaravelLogViewer\Providers\LogViewerServiceProvider::class,
],

If you are upgrading from an older version where the provider was registered manually, remove the manual registration after enabling auto-discovery to avoid loading the package twice.

Publishing

Publish the configuration file:

php artisan vendor:publish \
    --provider="AlexKudrya\LaravelLogViewer\Providers\LogViewerServiceProvider" \
    --tag=config

Publish public assets and translations:

php artisan vendor:publish \
    --provider="AlexKudrya\LaravelLogViewer\Providers\LogViewerServiceProvider" \
    --tag=laravel-assets

To publish everything at once:

php artisan vendor:publish \
    --provider="AlexKudrya\LaravelLogViewer\Providers\LogViewerServiceProvider"

The viewer is available at:

https://your-host.example/log-viewer

Security

Log files can contain secrets, tokens, personal data, stack traces, database queries, server paths, and other sensitive application details. Do not expose this route publicly.

The route is protected by the web middleware and the configured log_viewer.middleware. By default, log_viewer.middleware is set to auth. For production, prefer a stricter admin-only middleware or policy:

// config/log_viewer.php

'middleware' => ['auth', 'can:view-log-viewer'],

Adding Disallow: /log-viewer to robots.txt is still recommended, but it is not a security control:

User-agent: *

Allow: /
Disallow: /log-viewer

Downloads return the original log file, not the redacted display output. If operators should only inspect bounded, redacted UI output, disable downloads:

// config/log_viewer.php

'download_enabled' => false,

Configuration

The package configuration is published to config/log_viewer.php.

OptionDefaultDescription
route_prefixlog-viewerURI prefix for the viewer route.
app_titleLog ViewerPage title displayed in the browser and sidebar.
middlewareauthAdditional middleware applied after Laravel's web middleware.
download_enabledtrueWhether the sidebar and download route allow original log file downloads.
max_display_records10000Maximum number of parsed records rendered for one request.
max_listed_files1000Maximum number of newest log files shown in the sidebar.
max_display_bytes16777216Approximate maximum parsed payload accumulated before rendering stops.
scan_modelatestDefault scan mode. latest reads from the end of the file, full scans from the beginning.
initial_scan_bytes8388608Initial bytes scanned for the default latest-records view.
max_scan_bytes134217728Hard cap for bytes scanned by one UI request.
read_chunk_size65536File read chunk size in bytes.
max_record_bytes1048576Maximum bytes kept in memory for one parsed log record before truncation.
max_search_terms8Maximum number of search terms applied to one request and highlighted in the browser.
max_search_length256Maximum search query length accepted from the request.
max_filter_values100Maximum number of level/environment filter values accepted from the request.
max_filter_value_length128Maximum length for each level/environment filter value.
max_json_context_bytes1048576Maximum JSON context candidate size parsed from one record.
max_context_depth8Maximum nested depth rendered for parsed JSON context tables.
max_context_items200Maximum parsed context entries rendered for one record.
max_stacktrace_rows200Maximum stack trace rows rendered for one record.
redact_patterns[]Optional PCRE patterns applied to parsed display text before rendering.
redaction_replacement[REDACTED]Replacement used for list-style redact_patterns.
localesen, ru, ukAvailable interface locales.

You can tune large-file handling and operational defaults with environment variables:

LOG_VIEWER_MAX_LINES_DISPLAY=10000
LOG_VIEWER_DOWNLOAD_ENABLED=true
LOG_VIEWER_MAX_LISTED_FILES=1000
LOG_VIEWER_MAX_DISPLAY_BYTES=16777216
LOG_VIEWER_SCAN_MODE=latest
LOG_VIEWER_INITIAL_SCAN_BYTES=8388608
LOG_VIEWER_MAX_SCAN_BYTES=134217728
LOG_VIEWER_READ_CHUNK_SIZE=65536
LOG_VIEWER_MAX_RECORD_BYTES=1048576
LOG_VIEWER_MAX_SEARCH_TERMS=8
LOG_VIEWER_MAX_SEARCH_LENGTH=256
LOG_VIEWER_MAX_FILTER_VALUES=100
LOG_VIEWER_MAX_FILTER_VALUE_LENGTH=128
LOG_VIEWER_MAX_JSON_CONTEXT_BYTES=1048576
LOG_VIEWER_MAX_CONTEXT_DEPTH=8
LOG_VIEWER_MAX_CONTEXT_ITEMS=200
LOG_VIEWER_MAX_STACKTRACE_ROWS=200

For large production logs, keep LOG_VIEWER_SCAN_MODE=latest. Users can explicitly scan from the beginning or request a deeper latest scan from the interface, but each request remains bounded by LOG_VIEWER_MAX_SCAN_BYTES.

Optional redaction can hide secrets in the web UI without changing the original log file or download response:

'redact_patterns' => [
    '/(api[_-]?key=)[^\s&]+/i' => '$1[REDACTED]',
    '/(token=)[^\s&]+/i',
],
'redaction_replacement' => '[REDACTED]',

File Handling

The package reads files from Laravel's storage/logs directory only.

Accepted files:

  • laravel.log
  • laravel-2026-06-07.log
  • worker.log

Rejected files:

  • laravel.log.gz
  • laravel.log.1
  • laravel.log.php
  • ../laravel.log
  • symlinks
  • directories
  • unreadable files

Compressed or archived logs are intentionally excluded from the list and cannot be downloaded through the viewer.

If max_listed_files is reached, the sidebar keeps the newest readable .log files by modification time and marks the list as limited.

License

Laravel Log Viewer is open-sourced software licensed under the MIT license.

Author

Alexander Kudria alexkudrya91@gmail.com