ravols/lara-logs-toolkit
最新稳定版本:1.1.0
Composer 安装命令:
composer require ravols/lara-logs-toolkit
包简介
LaraLogsToolkit is a package that allows you to analyze your logs and get the count of errors, info and warnings.
README 文档
README
A Laravel package that helps you track deployments and monitor log file growth by providing deployment markers and log record counting capabilities.
Problems This Package Solves
Problem 1: Log Files Filling Up After Deployment
The Issue: After a deployment, your logs might start filling up with errors, but if you're distracted or not actively monitoring, you might miss critical issues until they become severe.
The Solution: This package provides a command to quickly check how many log records exist in any specified log channel from your config/logging.php. Run it after deployments or set it up in monitoring to get instant visibility into log growth.
Extended Possibilities: You can create your own custom commands that check for new log records and send notifications (Slack, email, or SMS) when a threshold is met. This allows you to set up automated alerting that triggers when log growth exceeds acceptable levels after deployments.
Problem 2: When Did Errors Occur?
The Issue: When you see errors in your logs, it's often impossible to tell if they happened before or after your latest deployment. This makes debugging much harder, especially when you need to determine if a deployment introduced new issues.
The Solution: This package automatically logs a timestamp marker whenever composer dump-autoload finishes. By adding a single line to your composer.json, you'll have clear deployment markers in your logs, making it easy to see which errors occurred before or after each deployment.
Installation
You can install the package via composer:
composer require ravols/lara-logs-toolkit
Configuration
Publish the configuration file:
php artisan vendor:publish --tag=lara-logs-toolkit-config
This will create config/lara-logs-toolkit.php where you can configure the composer dump-autoload log channel and cache settings:
'composer_dump_autoload_channel' => env('LARA_LOGS_TOOLKIT_COMPOSER_DUMP_AUTOLOAD_CHANNEL', 'daily'), 'comparison_cache_ttl' => env('LARA_LOGS_TOOLKIT_COMPARISON_CACHE_TTL', 600),
Configuration Options:
composer_dump_autoload_channel- The log channel where the composer dump-autoload notification will be written. This should match one of the channels defined in your application's logging configuration (default:daily)comparison_cache_ttl- Cache time-to-live in seconds for storing log analysis comparison results (default:600seconds / 10 minutes)
Usage
Deployment Tracking
To automatically log when composer dump-autoload finishes, you need to add the command to your composer.json file.
Step 1: Open your composer.json file in the root of your Laravel project.
Step 2: Find the scripts section. If it doesn't exist, create it at the root level of your JSON.
Step 3: Add or update the post-autoload-dump array. Add "@php artisan lara-logs:composer-dump-autoload" as the last item in the array.
Example - of a post-autoload-dump script:
{
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi",
"@php artisan lara-logs:composer-dump-autoload"
]
}
}
Important: The line "@php artisan lara-logs:composer-dump-autoload" should be added as the last item in the post-autoload-dump array, after the existing Laravel commands.
Now, every time you run composer dump-autoload (which happens automatically during deployments), you'll see a log entry like:
[2025-12-25 11:01:23] local.INFO: Composer dump-autoload finished at 2025-12-25 11:01:23
This creates a clear marker in your logs, making it easy to identify which errors occurred before or after each deployment.
Checking Log Record Counts
To check how many log records exist in a specific channel:
php artisan lara-logs:check-records [channel]
If no channel is specified, it defaults to daily.
Examples:
# Check the default channel (from config) php artisan lara-logs:check-records # Check a specific channel php artisan lara-logs:check-records daily php artisan lara-logs:check-records api
The command will output:
Channel 'daily' contains 1523 log record(s).
This is especially useful after deployments to quickly see if error counts have increased, or you can integrate it into your monitoring/alerting system.
Deleting Log Records
To delete log records from configured log channels:
php artisan lara-logs:delete-logs
Options:
--channels=*- Comma-separated list of log channel names to delete (e.g.,--channels=daily,api)--action=- Delete action:latestorall(defaults to interactive selection)
Examples:
# Interactive mode - select channels and action php artisan lara-logs:delete-logs # Delete all logs from specific channels php artisan lara-logs:delete-logs --channels=daily,api --action=all # Delete latest record from a single channel php artisan lara-logs:delete-logs --channels=single --action=latest # Multiple channels with comma-separated list php artisan lara-logs:delete-logs --channels=daily,api --action=all
Interactive Features:
- If no channels are specified, you'll be prompted with an interactive multisearch to select one or more channels
- If no action is specified, you'll be prompted to choose between:
- Delete only latest record - Deletes the latest log file
- Delete all logs - Deletes all log files for the selected channel(s)
Safety Features:
- In production environment, you'll be prompted for confirmation before deletion
- The command validates that selected channels exist in your logging configuration
- Provides success/error counts for batch operations
Delete Actions:
latest- Deletes the latest log file for each selected channelall- Deletes all log files for each selected channel (handles both single and daily log file formats)
Comparing Log Analysis with Cached Results
The package provides a method to compare current log analysis with previously cached results. This is useful for detecting changes in log counts over time:
use Illuminate\Support\Facades\Log; use Ravols\LaraLogsToolkit\Facades\LaraLogsToolkit; $logger = Log::channel('daily'); $comparison = LaraLogsToolkit::getLogAnalysisComparison($logger); // Access the results using properties $currentCounts = $comparison->current; // LogCountsData $cachedCounts = $comparison->cached; // LogCountsData $differences = $comparison->differences; // LogCountsData // Example: Check if errors increased using methods if ($comparison->isNewError()) { echo "Errors increased by {$comparison->getNewErrorCount()} since last check\n"; } // Or access directly via properties if ($comparison->differences->error > 0) { echo "Errors increased by {$comparison->differences->error} since last check\n"; } // Use helper methods for convenience if ($comparison->hasAnyNewIssues()) { echo "Total new issues: {$comparison->getTotalNewIssuesCount()}\n"; echo "New errors: {$comparison->getNewErrorCount()}\n"; echo "New warnings: {$comparison->getNewWarningCount()}\n"; } // Check when the cache was created if ($comparison->cachedAt !== null) { echo "Cache was created at: {$comparison->cachedAt}\n"; } else { echo "No previous cache found (first run)\n"; }
The method automatically caches the current analysis results for comparison on the next call. The cache TTL is configurable via config/lara-logs-toolkit.php using the comparison_cache_ttl key (default: 600 seconds).
Return Type: LogAnalysisComparisonData containing:
current-LogCountsDatawith current log counts by levelcached-LogCountsDatawith previously cached log countsdifferences-LogCountsDatashowing the difference between current and cached (current - cached)logFileName- The log file name used for cachingcachedAt- DateTime string (e.g., "2025-01-15 10:30:45") indicating when the cache was created, ornullif no cache existed
LogCountsData Properties:
error,info,warning,emergency,alert,critical,debug,notice- Individual log level countsgetTotal()- Get total count across all levels
Analyzing All Log Channels
You can analyze all log channels at once using getAllChannelsLogAnalysis(). This method automatically excludes certain channels by default (like stack, null, single, daily, etc.) but allows you to customize which channels to include or exclude.
use Ravols\LaraLogsToolkit\Facades\LaraLogsToolkit; // Analyze all channels (excluding defaults) $analysis = LaraLogsToolkit::getAllChannelsLogAnalysis(); // Get aggregated totals across all channels $totalErrors = $analysis->getError(); $totalWarnings = $analysis->getWarning(); $total = $analysis->getTotal(); // Get specific channel data $carriersData = $analysis->getChannel('carriers'); if ($carriersData) { $carriersErrors = $carriersData->error; } // With caching/comparison enabled $analysis = LaraLogsToolkit::getAllChannelsLogAnalysis(useCache: true); // Access comparison data for specific channels $comparison = $analysis->getComparisonChannel('carriers'); if ($comparison && $comparison->hasAnyNewIssues()) { $newErrors = $comparison->getNewErrorCount(); echo "New errors in carriers channel: {$newErrors}\n"; } // Customize excluded channels $analysis = LaraLogsToolkit::excludeChannels(['stack', 'null', 'slack']) ->getAllChannelsLogAnalysis(); // Include a normally excluded channel $analysis = LaraLogsToolkit::includeChannels('stack') ->getAllChannelsLogAnalysis(); // Chain configuration methods $analysis = LaraLogsToolkit::excludeChannels(['carriers']) ->includeChannels('stack') ->getAllChannelsLogAnalysis(useCache: true);
Default Excluded Channels: single, daily, null, papertrail, stderr, syslog, errorlog, slack, emergency
AllChannelsLogAnalysisData Methods:
getChannel(string $channelName)- Get data for a specific channelgetChannels()- Get all channels datagetError(),getInfo(),getWarning(), etc. - Aggregated totals across all channelsgetTotal()- Total count across all channels and log levelsgetComparisonChannel(string $channelName)- Get comparison data for a channelhasComparisonData()- Check if any channels have comparison datatoArray()- Convert to array format
Creating Custom Alert Commands
You can create your own commands that monitor log growth and send notifications when thresholds are exceeded. Here's an example:
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Notification; use Ravols\LaraLogsToolkit\LaraLogsToolkit; class MonitorLogGrowth extends Command { protected $signature = 'logs:monitor {channel=daily : The log channel to monitor} {--threshold=100 : Alert threshold}'; protected $description = 'Monitor log growth and send alerts when threshold is exceeded'; public function handle(LaraLogsToolkit $laraLogsToolkit): int { $channel = $this->argument('channel'); $threshold = (int) $this->option('threshold'); $logger = Log::channel($channel); // Get total count $logCounts = $laraLogsToolkit->getLogAnalysis($logger); $count = $logCounts->getTotal(); // Or get count for a specific log level // $count = $logCounts->error; // or $logCounts->warning, etc. // Or compare with cached results to detect changes // $comparison = $laraLogsToolkit->getLogAnalysisComparison($logger); // if ($comparison->isNewError()) { // $newErrors = $comparison->getNewErrorCount(); // // Handle new errors since last check // } if ($count > $threshold) { // Send Slack notification Notification::route('slack', config('services.slack.webhook_url')) ->notify(new LogThresholdExceeded($channel, $count, $threshold)); // Or send email // Mail::to(config('app.admin_email'))->send(new LogAlert($channel, $count)); // Or send SMS // Notification::route('vonage', config('app.admin_phone')) // ->notify(new LogThresholdExceeded($channel, $count, $threshold)); $this->warn("Alert sent! Channel '{$channel}' has {$count} records (threshold: {$threshold})"); return self::FAILURE; } $this->info("Channel '{$channel}' is within limits ({$count} records)"); return self::SUCCESS; } }
You can then schedule this command in your app/Console/Kernel.php:
protected function schedule(Schedule $schedule): void { // Check every 5 minutes after deployment $schedule->command('logs:monitor daily --threshold=100')->everyFiveMinutes(); }
LogCountsData
Represents log counts for all log levels. Provides readonly properties for direct access to log level counts.
Properties:
error,info,warning,emergency,alert,critical,debug,notice- Individual log level counts
Methods:
getTotal()- Get total count across all levelstoArray()- Convert to array formatfromArray(array $counts): self- Static factory method to create from array
Example:
$logCounts = LaraLogsToolkit::getLogAnalysis(Log::channel('daily')); // Access individual log level counts via properties $errors = $logCounts->error; $warnings = $logCounts->warning; $info = $logCounts->info; // Get total count across all levels $total = $logCounts->getTotal();
LogAnalysisComparisonData
Represents a comparison between current and cached log analysis results.
Properties:
current-LogCountsDatawith current log countscached-LogCountsDatawith previously cached log countsdifferences-LogCountsDatashowing differences (current - cached)logFileName- The log file name used for cachingcachedAt- DateTime string (e.g., "2025-01-15 10:30:45") indicating when the cache was created, ornullif no cache existed
Helper Methods:
isNewError(),isNewWarning(),isNewCritical(),isNewAlert(),isNewEmergency()- Boolean checks for new entrieshasAnyNewIssues()- Check if there are any new issuesgetNewErrorCount(),getNewWarningCount(), etc. - Get count of new entries (returns 0 if negative)getTotalNewIssuesCount()- Get total count of all new issuesgetTotalNewCount()- Get total count of all new log entriesgetCurrentErrorCount(),getCurrentWarningCount()- Get current countsgetCachedErrorCount(),getCachedWarningCount()- Get cached counts
Example:
$comparison = LaraLogsToolkit::getLogAnalysisComparison(Log::channel('daily')); // Check for new errors if ($comparison->isNewError()) { $newErrors = $comparison->getNewErrorCount(); } // Access properties directly $currentErrors = $comparison->current->error; $cachedErrors = $comparison->cached->error; $errorDiff = $comparison->differences->error; // Check when cache was created if ($comparison->cachedAt) { echo "Last cached at: {$comparison->cachedAt}\n"; }
API Reference
Available Methods
The LaraLogsToolkit class provides the following methods:
getLogAnalysis(LoggerInterface $logger): LogCountsData
Analyzes logs and returns a LogCountsData with detailed log counts by level.
$logCounts = LaraLogsToolkit::getLogAnalysis(Log::channel('daily')); // Access individual log level counts $errorCount = $logCounts->error; $infoCount = $logCounts->info; $warningCount = $logCounts->warning; // Get total count across all levels $total = $logCounts->getTotal();
getLogAnalysisComparison(LoggerInterface $logger): LogAnalysisComparisonData
Compares current log analysis with cached results and returns a LogAnalysisComparisonData containing:
current-LogCountsDatawith current log counts by levelcached-LogCountsDatawith previously cached log countsdifferences-LogCountsDatashowing differences between current and cached (current - cached)logFileName- The log file name used for cachingcachedAt- DateTime string indicating when the cache was created, ornullif no cache existed
The results are automatically cached for the next comparison. Cache TTL is configurable.
$comparison = LaraLogsToolkit::getLogAnalysisComparison(Log::channel('daily')); // Use helper methods if ($comparison->isNewError()) { $newErrors = $comparison->getNewErrorCount(); } // Or access directly $newErrors = $comparison->differences->error; $currentErrors = $comparison->current->error; // Check for any new issues if ($comparison->hasAnyNewIssues()) { $totalNewIssues = $comparison->getTotalNewIssuesCount(); } // Check when the cache was created if ($comparison->cachedAt) { echo "Cache created at: {$comparison->cachedAt}\n"; }
LogAnalysisComparisonData Helper Methods:
isNewError(),isNewWarning(),isNewCritical(),isNewAlert(),isNewEmergency()- Check if specific log level has new entrieshasAnyNewIssues()- Check if there are any new issues (errors, warnings, critical, alert, or emergency)getNewErrorCount(),getNewWarningCount(), etc. - Get count of new entries for each level (returns 0 if negative)getTotalNewIssuesCount()- Get total count of all new issuesgetTotalNewCount()- Get total count of all new log entries across all levelsgetCurrentErrorCount(),getCurrentWarningCount()- Get current countsgetCachedErrorCount(),getCachedWarningCount()- Get cached counts
getAllChannelsLogAnalysis(bool $useCache = false): AllChannelsLogAnalysisData
Analyzes all log channels defined in config/logging.php (excluding default excluded channels) and returns an AllChannelsLogAnalysisData DTO with aggregated results.
Default Excluded Channels: single, daily, null, papertrail, stderr, syslog, errorlog, slack, emergency
Parameters:
$useCache(bool, default:false) - Iftrue, usesgetLogAnalysisComparison()instead ofgetLogAnalysis()for each channel, providing comparison data with cached results.
Chainable Configuration Methods:
excludeChannels(array|string $channels): self- Override the default excluded channelsincludeChannels(array|string $channels): self- Include channels by removing them from the excluded list
// Basic usage - analyze all channels (excluding defaults) $analysis = LaraLogsToolkit::getAllChannelsLogAnalysis(); // Get aggregated totals across all channels $totalErrors = $analysis->getError(); $totalWarnings = $analysis->getWarning(); $total = $analysis->getTotal(); // Get specific channel data $carriersData = $analysis->getChannel('carriers'); if ($carriersData instanceof LogCountsData) { $carriersErrors = $carriersData->error; } // With caching/comparison enabled $analysis = LaraLogsToolkit::getAllChannelsLogAnalysis(useCache: true); // Access comparison data for a specific channel $comparison = $analysis->getComparisonChannel('carriers'); if ($comparison) { $newErrors = $comparison->getNewErrorCount(); $hasNewIssues = $comparison->hasAnyNewIssues(); } // Check if any channels have comparison data if ($analysis->hasComparisonData()) { // Handle comparison-specific logic } // Customize excluded channels $analysis = LaraLogsToolkit::excludeChannels(['stack', 'null', 'slack']) ->getAllChannelsLogAnalysis(); // Include a normally excluded channel $analysis = LaraLogsToolkit::includeChannels('stack') ->getAllChannelsLogAnalysis(); // Chain both methods $analysis = LaraLogsToolkit::excludeChannels(['carriers', 'api']) ->includeChannels('stack') ->getAllChannelsLogAnalysis(useCache: true);
AllChannelsLogAnalysisData Methods:
getChannel(string $channelName): LogCountsData|LogAnalysisComparisonData|null- Get data for a specific channelgetChannels(): array- Get all channels datagetError(),getInfo(),getWarning(),getEmergency(),getAlert(),getCritical(),getDebug(),getNotice()- Get aggregated totals across all channels for each log levelgetTotal(): int- Get total count across all channels and all log levelsgetComparisonChannel(string $channelName): ?LogAnalysisComparisonData- Get comparison data for a specific channel (returnsnullif channel doesn't have comparison data)hasComparisonData(): bool- Check if any channels have comparison datatoArray(): array- Convert to array format (includes both individual channels and aggregated totals)fromArray(array $data): self- Static factory method to create from array
Example with aggregated totals:
$analysis = LaraLogsToolkit::getAllChannelsLogAnalysis(); // Aggregated totals across all channels $allErrors = $analysis->getError(); // Sum of all errors from all channels $allWarnings = $analysis->getWarning(); // Sum of all warnings from all channels $allInfo = $analysis->getInfo(); // Sum of all info logs from all channels $total = $analysis->getTotal(); // Total of all log levels from all channels // Individual channel access foreach ($analysis->getChannels() as $channelName => $channelData) { if ($channelData instanceof LogCountsData) { echo "{$channelName}: {$channelData->error} errors\n"; } }
getLastError(string $channel = 'stack', bool $withStackTrace = false): ?string
Retrieves the last error message from a specific log channel. By default, returns only the error message without the stack trace.
Parameters:
$channel(string, default:'stack') - The log channel name to check$withStackTrace(bool, default:false) - Iftrue, returns the full error entry including stack trace
Returns: string|null - The last error message (or full error with stack trace), or null if no error is found
use Ravols\LaraLogsToolkit\Facades\LaraLogsToolkit; // Get last error message only (default channel: 'stack') $error = LaraLogsToolkit::getLastError(); // Get last error from specific channel $error = LaraLogsToolkit::getLastError('api'); // Get last error with stack trace $error = LaraLogsToolkit::getLastError('stack', true); // Get last error with stack trace from specific channel $error = LaraLogsToolkit::getLastError('api', true);
Example:
$lastError = LaraLogsToolkit::getLastError('daily'); if ($lastError !== null) { echo "Last error: {$lastError}\n"; } else { echo "No errors found in daily channel\n"; } // With stack trace $fullError = LaraLogsToolkit::getLastError('daily', true); if ($fullError) { // Contains full error with stack trace echo $fullError; }
getLastRecord(string $channel = 'stack', bool $withStackTrace = false): ?string
Retrieves the last log record from a specific channel, regardless of log level (ERROR, INFO, WARNING, etc.). Useful for getting the most recent log entry of any type.
Parameters:
$channel(string, default:'stack') - The log channel name to check$withStackTrace(bool, default:false) - Iftrue, returns the full log entry including stack trace (if available)
Returns: string|null - The last log record (or full entry with stack trace), or null if no record is found
use Ravols\LaraLogsToolkit\Facades\LaraLogsToolkit; // Get last record (any log level) - message only $record = LaraLogsToolkit::getLastRecord(); // Get last record from specific channel $record = LaraLogsToolkit::getLastRecord('api'); // Get last record with stack trace $record = LaraLogsToolkit::getLastRecord('stack', true); // Get last record with stack trace from specific channel $record = LaraLogsToolkit::getLastRecord('api', true);
Example:
$lastRecord = LaraLogsToolkit::getLastRecord('daily'); if ($lastRecord !== null) { echo "Last log entry: {$lastRecord}\n"; } else { echo "No log entries found in daily channel\n"; } // With stack trace (if available) $fullRecord = LaraLogsToolkit::getLastRecord('daily', true); if ($fullRecord) { // Contains full log entry with stack trace echo $fullRecord; }
Tinker Helper Functions
The package provides convenient helper functions for use in artisan tinker. These functions allow you to quickly access the last error and last record methods without using the facade or dependency injection.
lastError(string $channel = 'stack', bool $withStackTrace = false): ?string
Helper function to get the last error from a specific log channel. This is a convenience wrapper around LaraLogsToolkit::getLastError().
Note: This function is intended for use in artisan tinker only.
Parameters:
$channel(string, default:'stack') - The log channel name to check$withStackTrace(bool, default:false) - Iftrue, returns the full error entry including stack trace
Returns: string|null - The last error message (or full error with stack trace), or null if no error is found
Example in Tinker:
php artisan tinker >>> lastError() => "SQLSTATE[HY000] [2002] Connection refused" >>> lastError('api') => "Route not found: GET /api/users" >>> lastError('stack', true) => "[2025-01-03 10:30:45] local.ERROR: SQLSTATE[HY000] [2002] Connection refused [stack trace] #0 /path/to/file.php(123): function() ..."
lastRecord(string $channel = 'stack', bool $withStackTrace = false): ?string
Helper function to get the last log record from a specific channel, regardless of log level. This is a convenience wrapper around LaraLogsToolkit::getLastRecord().
Note: This function is intended for use in artisan tinker only.
Parameters:
$channel(string, default:'stack') - The log channel name to check$withStackTrace(bool, default:false) - Iftrue, returns the full log entry including stack trace (if available)
Returns: string|null - The last log record (or full entry with stack trace), or null if no record is found
Example in Tinker:
php artisan tinker >>> lastRecord() => "User logged in successfully" >>> lastRecord('api') => "API request processed" >>> lastRecord('stack', true) => "[2025-01-03 10:30:45] local.INFO: User logged in successfully [stack trace] #0 /path/to/file.php(123): function() ..."
Available Commands
php artisan lara-logs:composer-dump-autoload- Manually log a deployment markerphp artisan lara-logs:check-records [channel]- Check log record count for a channelphp artisan lara-logs:delete-logs- Delete log records from selected channels (supports--channelsand--actionoptions)
Changelog
Please see CHANGELOG for more information on what has changed recently.
License
The MIT License (MIT). Please see License File for more information.
统计信息
- 总下载量: 2
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-07