定制 ravols/lara-logs-toolkit 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

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: 600 seconds / 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: latest or all (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 channel
  • all - 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 - LogCountsData with current log counts by level
  • cached - LogCountsData with previously cached log counts
  • differences - LogCountsData showing the difference between current and cached (current - cached)
  • logFileName - The log file name used for caching
  • cachedAt - DateTime string (e.g., "2025-01-15 10:30:45") indicating when the cache was created, or null if no cache existed

LogCountsData Properties:

  • error, info, warning, emergency, alert, critical, debug, notice - Individual log level counts
  • getTotal() - 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 channel
  • getChannels() - Get all channels data
  • getError(), getInfo(), getWarning(), etc. - Aggregated totals across all channels
  • getTotal() - Total count across all channels and log levels
  • getComparisonChannel(string $channelName) - Get comparison data for a channel
  • hasComparisonData() - Check if any channels have comparison data
  • toArray() - 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 levels
  • toArray() - Convert to array format
  • fromArray(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 - LogCountsData with current log counts
  • cached - LogCountsData with previously cached log counts
  • differences - LogCountsData showing differences (current - cached)
  • logFileName - The log file name used for caching
  • cachedAt - DateTime string (e.g., "2025-01-15 10:30:45") indicating when the cache was created, or null if no cache existed

Helper Methods:

  • isNewError(), isNewWarning(), isNewCritical(), isNewAlert(), isNewEmergency() - Boolean checks for new entries
  • hasAnyNewIssues() - Check if there are any new issues
  • getNewErrorCount(), getNewWarningCount(), etc. - Get count of new entries (returns 0 if negative)
  • getTotalNewIssuesCount() - Get total count of all new issues
  • getTotalNewCount() - Get total count of all new log entries
  • getCurrentErrorCount(), getCurrentWarningCount() - Get current counts
  • getCachedErrorCount(), 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 - LogCountsData with current log counts by level
  • cached - LogCountsData with previously cached log counts
  • differences - LogCountsData showing differences between current and cached (current - cached)
  • logFileName - The log file name used for caching
  • cachedAt - DateTime string indicating when the cache was created, or null if 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 entries
  • hasAnyNewIssues() - 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 issues
  • getTotalNewCount() - Get total count of all new log entries across all levels
  • getCurrentErrorCount(), getCurrentWarningCount() - Get current counts
  • getCachedErrorCount(), 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) - If true, uses getLogAnalysisComparison() instead of getLogAnalysis() for each channel, providing comparison data with cached results.

Chainable Configuration Methods:

  • excludeChannels(array|string $channels): self - Override the default excluded channels
  • includeChannels(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 channel
  • getChannels(): array - Get all channels data
  • getError(), getInfo(), getWarning(), getEmergency(), getAlert(), getCritical(), getDebug(), getNotice() - Get aggregated totals across all channels for each log level
  • getTotal(): int - Get total count across all channels and all log levels
  • getComparisonChannel(string $channelName): ?LogAnalysisComparisonData - Get comparison data for a specific channel (returns null if channel doesn't have comparison data)
  • hasComparisonData(): bool - Check if any channels have comparison data
  • toArray(): 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) - If true, 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) - If true, 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) - If true, 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) - If true, 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 marker
  • php artisan lara-logs:check-records [channel] - Check log record count for a channel
  • php artisan lara-logs:delete-logs - Delete log records from selected channels (supports --channels and --action options)

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

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-01-07