Installation:
composer require cethyworks/log-tail-bundle
Add the bundle to config/bundles.php (Symfony 4+):
return [
// ...
Cethyworks\LogTailBundle\CethyworksLogTailBundle::class => ['all' => true],
];
First Use Case:
Run the prettified tail -f command directly via Artisan:
php artisan debug:log:tail
var/log/dev.log (hardcoded).--interval flag (e.g., --interval=2 for 2-second refreshes).Where to Look First:
src/Command/DebugLogTailCommand.php (core logic).getLogFile() in the command for default paths.formatLine() for prettification logic (e.g., timestamps, colors).Tail Specific Logs: Override the hardcoded path by extending the command:
// app/Console/Commands/TailCustomLog.php
namespace App\Console\Commands;
use Cethyworks\LogTailBundle\Command\DebugLogTailCommand;
class TailCustomLog extends DebugLogTailCommand {
protected function getLogFile() {
return storage_path('logs/custom.log');
}
}
Register the new command in app/Console/Kernel.php.
Integration with Laravel Logging: Use the bundle alongside Laravel’s logging system:
# Tail the default Laravel log
php artisan debug:log:tail
# Tail a monolog channel (e.g., 'single')
php artisan debug:log:tail --log-channel=single
(Note: Requires extending the bundle to support channels—see "Extension Points" below.)
Workflow: Debugging in Real-Time:
tail -f in the terminal.pipes to forward output).bin/console aliases for easier access:
# config/packages/console.yaml
console:
commands:
debug:log:tail: 'Cethyworks\LogTailBundle\Command\DebugLogTailCommand'
formatLine() method to add:
[INFO], [ERROR]).// config/log-tail.php
return [
'log_path' => env('LOG_TAIL_PATH', 'var/log/dev.log'),
];
Then inject this into the command via dependency injection.Hardcoded Dependencies:
var/log/dev.log) are hardcoded. Override getLogFile() or patch the bundle.storage/logs/laravel-*.log).Performance Overhead:
--interval=1 for a balance between responsiveness and CPU usage.Output Formatting Issues:
formatLine() to handle custom formats:
protected function formatLine(string $line): string {
if (str_starts_with($line, '[')) {
return $line; // Skip prettification for JSON
}
return parent::formatLine($line);
}
Missing Features:
--level=error).-f) toggle (always tails).grep for filtering:
php artisan debug:log:tail 2>&1 | grep -i "error"
Archived Package Risks:
config/bundles.php and dependencies are installed.chmod or SELinux adjustments:
chmod 644 var/log/dev.log
$this->info("Tailing file: " . $this->getLogFile());
Add Log Channel Support: Extend the command to read from Monolog channels:
use Psr\Log\LoggerInterface;
class ExtendedLogTailCommand extends DebugLogTailCommand {
protected LoggerInterface $logger;
public function __construct(LoggerInterface $logger) {
$this->logger = $logger;
}
protected function getLogFile() {
// Use Monolog's handlers to resolve the log file.
// Requires deep integration with Monolog's stream handler.
}
}
(Note: This requires significant refactoring of the original bundle.)
Custom Output Handlers: Replace the default output with a custom handler (e.g., write to a database):
protected function outputLine(string $line) {
// Custom logic (e.g., save to DB, send to Slack).
parent::outputLine($line); // Fallback to default.
}
Configuration via Laravel:
Make the bundle configurable by adding a config file (config/log-tail.php) and binding it to the command:
// In the command's constructor:
public function __construct(array $config) {
$this->config = $config;
}
Register the config in AppServiceProvider@boot():
$this->app->bind(CethyworksLogTailBundleCommand::class, function ($app) {
return new CethyworksLogTailBundleCommand(config('log-tail'));
});
~/.bashrc or ~/.zshrc:
alias tail-logs='php artisan debug:log:tail'
tmux or screen to run the command in a detached session:
tmux new -s log-tail 'php artisan debug:log:tail'
mkfifo /tmp/laravel.log
php artisan debug:log:tail --log-file=/tmp/laravel.log &
# Another process writes to /tmp/laravel.log
How can I help you explore Laravel packages today?