Download the PHP package tibbs/scoped-logger-laravel without Composer
On this page you can find all versions of the php package tibbs/scoped-logger-laravel. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download tibbs/scoped-logger-laravel
More information about tibbs/scoped-logger-laravel
Files in tibbs/scoped-logger-laravel
Package scoped-logger-laravel
Short Description Fine-grained logging level management for Laravel
License MIT
Homepage https://github.com/tibbsa/scoped-logger-laravel
Informations about the package scoped-logger-laravel
Fine-grained logging level management for Laravel
When troubleshooting specific issues in a Laravel application, it is often helpful to have increased logging visibility regarding a specific portion of your application. However, if you increase your log level, then you will also increase the log traffic from all other parts of the application at the same time. While logging channels offer some flexibility in separating different types of log entries, they are cumbersome and must all be pre-configured before they can be used.
This package adds the ability to define different logging levels based on the "scope" of a particular log entry.
Scopes can be explicitly defined when logging, or automatically determined based on the calling class (via its name,
a defined property, or a defined method). Logging levels for a given scope can be configured in the config/scoped-logger.php
configuration file or overridden at runtime for debugging purposes.
Features
- 🎯 Scope-based log levels - Set different log levels for different parts of your application
- 🔍 Wildcard pattern matching - Use
App\Services\*orpayment.*to match multiple scopes - 📊 Smart pattern priority - Most specific pattern wins (exact > longer > fewer wildcards)
- 🔄 Automatic scope detection - Auto-detect scope from calling class (FQCN, property, or method)
- 🚫 Scope suppression - Completely silence logs from specific scopes
- ⚠️ Unknown scope detection - Configurable handling for unconfigured scopes (exception, log warning, or ignore)
- 📺 Per-channel configurations - Different scope levels for different log channels
- 🔀 Multiple scopes - Log with multiple scopes using "most verbose wins" strategy
- 🎛️ Conditional logging - Use closures for dynamic levels based on environment, time, etc.
- 🐛 Debug mode - Detailed scope resolution info for troubleshooting
- 🪝 Laravel integration - Works seamlessly with
Logfacade andlogger()helper - ⚡ Minimal config required - Works out of the box with sensible defaults (just define your scopes!)
- ⚡ Runtime modification - Temporarily override scope levels without config changes
Requirements
- Laravel 12.11.0+ or Laravel 13.x
- PHP 8.3+
Installation
Install the package via composer:
Publish the config file (optional):
Quick Start
Configure scopes in config/scoped-logger.php:
Use in your application:
Usage
Explicit Scopes
The most straightforward way to use scoped logging:
Automatic Scope Detection
Scoped Logger can automatically detect the scope from the calling class:
Scope Priority
Scopes are resolved in this order:
- Explicit scope -
Log::scope('payment') - Class FQCN - If the calling class FQCN is configured as a scope
- Class property/method - Static property
$log_scopeor methodgetLogScope() - Default level - Falls back to
default_levelconfig
Pattern Matching
Use wildcard patterns to match multiple scopes with a single configuration:
Supported Wildcards:
*- Matches any characters (including none)?- Matches exactly one character
Pattern Specificity:
When multiple patterns match a scope, the most specific pattern wins:
- Exact matches (no wildcards) are most specific
- Longer patterns are more specific than shorter ones
- Fewer wildcards make patterns more specific
Suppressing Scopes
Set a scope to false to completely suppress all logs from that scope:
Unknown Scope Handling
By default, using an unconfigured scope throws an exception. This helps catch typos and configuration mistakes:
You can configure how unknown scopes are handled:
Handling Options:
exception(default): ThrowsUnknownScopeException- best for catching configuration errorslog: Logs a warning and processes the log with the default levelignore: Silently uses the default level
What counts as "known":
- Exact match in scopes configuration
- Matches a wildcard pattern
- Has a runtime override set
- Auto-detected scopes that return
null(use default level)
Environment Variable:
Configuration
Disabling Scoped Logging
You can completely disable scoped logging by setting SCOPED_LOG_ENABLED=false in your .env file. When disabled:
- ✅ All logs pass through to the underlying Laravel logger without any filtering
- ❌ No scope-based filtering - all configured scope levels are ignored
- ❌ No scope added to context - the
scopekey won't appear in log context - ❌ No metadata added - caller metadata (file, line, class) won't be added
- ❌ No debug info added - scope resolution debug info won't be added
- ❌ No unknown scope checking - unknown scopes won't throw exceptions or log warnings
- ✅ Shared context preserved - context from
withContext()is still merged - ✅ Underlying channel level applies - Laravel's channel log level still filters
- ✅ Scoped API stays safe -
Log::scope('x')->info(...)and runtime-level calls are accepted and ignored, so code needs no changes
The same applies to individual channels listed in disabled_channels: they return a PassThroughScopedLogger, which implements the same ScopedLoggerContract as the active ScopedLogger.
Use this when:
- You want to completely bypass scoped logging
- You're troubleshooting and want to see all logs regardless of scope configuration
- You want Laravel's default logging behavior
Full Configuration Options
All available configuration options:
⚠️ Important: Channel Log Levels
The underlying Laravel channel log level acts as a floor for all logged events.
If you're using scoped logging on a channel, that channel should be configured with the lowest log level you need (typically debug), otherwise the channel will filter out logs that scoped logging passes along to record.
Example Problem
Solution
Set your channel to debug level and let scoped logging handle the filtering:
Now scoped logging has full control over what gets logged.
Why This Happens
Logging flows through two filters:
- Scoped Logger - Filters based on scope configuration
- Channel Driver - Filters based on channel
levelconfig
Both must allow the log through. The channel level is a hard floor that cannot be overridden by scoped logging.
Runtime Modification
Temporarily override scope levels at runtime without changing configuration:
Runtime overrides:
- Take precedence over configured levels and pattern matches
- Persist only for the current request (in-memory)
- Perfect for temporary debugging without config changes
Conditional Logging
Use closures for dynamic log levels based on environment, time, feature flags, or any custom logic:
Closures are evaluated on each log call, allowing real-time adjustments based on current conditions.
Per-Channel Scope Configurations
Configure different log levels for the same scope across different channels:
Channel-specific scopes override global scopes. If a scope isn't defined for a channel, it falls back to the global configuration.
On-Demand Channels
Channels created with Log::stack() and Log::build() are filtered like configured channels and support scope(). They are matched against channel_scopes and disabled_channels by name:
| Method | Channel name |
|---|---|
Log::stack($channels, 'audit') |
audit |
Log::stack($channels) |
stack |
Log::build($config) |
ondemand |
Each call returns a new logger, so runtime overrides set with setRuntimeLevel() on another channel do not apply to it.
Multiple Scopes
Log with multiple scopes simultaneously by passing an array to scope(). The package uses a "most verbose wins" strategy:
Rules:
- Uses the lowest (most verbose) log level among all scopes
- If any scope is suppressed (
false), the entire log is suppressed - All scopes are included in context as a comma-separated string
Debug Mode
Enable debug mode to see detailed scope resolution information in log context:
When enabled, each log entry includes:
⚠️ Warning: Debug mode adds overhead. Use only for troubleshooting scope resolution issues.
Artisan Commands
List all configured scopes
Options:
--sort=name|level- Sort scopes by name (default) or level--channel=<name>- Show effective scopes for a specific channel
Default output displays:
- Global scopes table with levels and pattern indicators
- Channel-specific scope overrides (if configured)
- Total scope counts and pattern cache statistics
Channel-specific output (--channel) displays:
- Merged effective scopes (global + channel overrides)
- Source column indicating whether each scope comes from
globalorchannelconfiguration - Count of channel-specific overrides
Test scope resolution
Options:
--level=<level>- Test log level to check (default: debug)--channel=<name>- Test against a specific channel's scope configuration--all-channels- Test against all channels that have overrides
Default output shows:
- What pattern (if any) matches the scope
- What log level applies
- Whether the specified test level would log or be dropped
- Whether each PSR-3 level would log or be dropped
Channel-specific output (--channel) additionally shows:
- Whether the level comes from a channel override (indicated by
(channel override))
All-channels output (--all-channels) shows:
- Detailed results for global and each channel with overrides
- Summary comparison table showing how the scope behaves across all channels
Example output for --all-channels:
Performance
If your application logs a large number of entries (thousands), some caution may be warranted because of the unavoidable overhead that this filtering process adds to each log call. In real world applications, it is likely that the overhead associated with actually logging the entry will far exceed any overhead from filtering, but for those interested in eeking out every last inch of performance, strategies you can employ to minimize the performance impact include:
- Defining explicit scopes on log calls, e.g.
logger()->scope('auth')->info('my log'), thereby eliminating the need for inspection of the calling class to determine the scope - Avoiding using closures for scope definitions, e.g.
scope => 'debug', as this incurs a performance penalty due to the need to evaluate the closure on each log call - Disable metadata extraction in production (
include_metadata=>false): This is one of the most expensive features due to stack trace walking. Only enable it for debugging purposes. - Keep
debug_modedisabled in production: This adds extra context processing overhead - Use runtime level overrides for temporary debugging instead of closures: Runtime overrides (
setRuntimeLevel()) are actually faster than the baseline explicit scope because they short-circuit other lookups. - Limit the number of wildcard patterns: While pattern matching is cached, having many patterns increases the initial match time. The difference between 3 and 50+ patterns is minimal after caching, but organizing scopes hierarchically can help.
- Set
auto_detection.enabled=>falseif you always use explicit scopes: Auto-detection adds overhead per call due to stack trace inspection and reflection. - Reduce
auto_detection.stack_depthif auto-detection is needed: The default of 10 frames is usually sufficient; deeper stacks add overhead. - Leverage early filtering: Logs that get filtered out (below threshold) or from suppressed scopes exit early and are faster than logs that pass through. This means the package has minimal impact on "noisy" debug logging in production when those scopes are set to higher levels.
- Avoid passing very large context arrays if performance is critical: While the overhead is modest, it does add up at high volumes.
Testing
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Credits
- Anthony Tibbs
- All Contributors
License
The MIT License (MIT). Please see License File for more information.
All versions of scoped-logger-laravel with dependencies
illuminate/contracts Version ^12.11.0 || ^13.0
spatie/laravel-package-tools Version ^1.16