dschuppelius / php-error-toolkit
Reused codes for my api php sdks
Installs: 717
Dependents: 1
Suggesters: 0
Security: 0
Stars: 1
Watchers: 2
Forks: 0
Open Issues: 0
pkg:composer/dschuppelius/php-error-toolkit
Requires
- php: >=8.1 <8.5
- psr/log: ^3.0
Requires (Dev)
- phpunit/phpunit: ^11.3@dev
README
A PSR-3 compliant logging library built for PHP 8.2+ with a focus on console and file logging. Designed as a lightweight, reusable component for modern PHP applications.
Features
- π― PSR-3 Compliant - Full compatibility with PSR-3 logging standards
- π₯οΈ Console Logging - Colored output with ANSI support and terminal detection
- π File Logging - Automatic log rotation and fail-safe mechanisms
- π Factory Pattern - Clean instantiation with singleton behavior
- π Global Registry - Centralized logger management across your application
- β¨ Magic Methods - Convenient
logDebug(),logInfo(),logErrorAndThrow()methods via trait - π¨ Cross-Platform - Windows and Unix/Linux terminal support
- π§ͺ Fully Tested - Comprehensive test suite with PHPUnit
Installation
Install via Composer:
composer require dschuppelius/php-error-toolkit
Requirements
- PHP 8.1 or higher
- PSR-3 Log Interface
Quick Start
Basic Usage with Console Logger
use ERRORToolkit\Factories\ConsoleLoggerFactory; // Create a console logger $logger = ConsoleLoggerFactory::getLogger(); // Log messages with different levels $logger->info('Application started'); $logger->warning('This is a warning message'); $logger->error('An error occurred');
File Logging
use ERRORToolkit\Factories\FileLoggerFactory; // Create a file logger $logger = FileLoggerFactory::getLogger('/path/to/logfile.log'); // Log with context $logger->error('Database connection failed', [ 'host' => 'localhost', 'port' => 3306, 'error' => 'Connection timeout' ]);
Using the ErrorLog Trait
Add logging capabilities to any class:
use ERRORToolkit\Traits\ErrorLog; use ERRORToolkit\Factories\ConsoleLoggerFactory; class MyService { use ErrorLog; public function __construct() { // Set up logging self::setLogger(ConsoleLoggerFactory::getLogger()); } public function doSomething() { $this->logInfo('Starting operation'); try { // Your code here $this->logDebug('Operation completed successfully'); } catch (Exception $e) { $this->logError('Operation failed: ' . $e->getMessage()); } } }
Logger Types
Console Logger
- Colored output with level-specific colors
- Automatic terminal detection
- Debug console support (VS Code, etc.)
- Clean formatting with newline management
File Logger
- Automatic log rotation when size limit exceeded
- Fail-safe fallback to console/syslog
- Customizable file size limits
- Thread-safe file operations
Null Logger
- Silent logger for testing/production environments
- PSR-3 compliant no-op implementation
Global Logger Registry
Manage loggers globally across your application:
use ERRORToolkit\LoggerRegistry; use ERRORToolkit\Factories\FileLoggerFactory; // Set a global logger LoggerRegistry::setLogger(FileLoggerFactory::getLogger('app.log')); // Use it anywhere in your application if (LoggerRegistry::hasLogger()) { $logger = LoggerRegistry::getLogger(); $logger->info('Using global logger'); } // Reset when needed LoggerRegistry::resetLogger();
Log Levels
Supports all PSR-3 log levels with integer-based filtering:
EMERGENCY(0) - System is unusableALERT(1) - Action must be taken immediatelyCRITICAL(2) - Critical conditionsERROR(3) - Error conditionsWARNING(4) - Warning conditionsNOTICE(5) - Normal but significant conditionINFO(6) - Informational messagesDEBUG(7) - Debug-level messages
ErrorLog Trait Features
The ErrorLog trait provides comprehensive logging capabilities with multiple advanced features:
Magic Methods
All PSR-3 log levels are available as magic methods:
use ERRORToolkit\Traits\ErrorLog; class MyClass { use ErrorLog; public function example() { // Instance methods - these methods are automatically available $this->logDebug('Debug message'); $this->logInfo('Info message'); $this->logNotice('Notice message'); $this->logWarning('Warning message'); $this->logError('Error message'); $this->logCritical('Critical message'); $this->logAlert('Alert message'); $this->logEmergency('Emergency message'); // All methods support context arrays $this->logError('Database error', ['table' => 'users', 'id' => 123]); } public static function staticExample() { // Static methods - all static magic methods are available self::logDebug('Static debug message'); self::logInfo('Static info message'); self::logNotice('Static notice message'); self::logWarning('Static warning message'); self::logError('Static error message'); self::logCritical('Static critical message'); self::logAlert('Static alert message'); self::logEmergency('Static emergency message'); // Static methods also support context self::logInfo('User action', ['user' => 'admin', 'action' => 'login']); } }
Log and Throw Exceptions
Combine logging and exception throwing in a single call with log{Level}AndThrow():
use ERRORToolkit\Traits\ErrorLog; use RuntimeException; use InvalidArgumentException; class ValidationService { use ErrorLog; public function validateUser(array $data): void { if (empty($data['email'])) { // Logs error and throws exception in one call $this->logErrorAndThrow( InvalidArgumentException::class, 'Email is required' ); } if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { // With context array $this->logWarningAndThrow( InvalidArgumentException::class, 'Invalid email format', ['email' => $data['email']] ); } } public function processPayment(float $amount): void { try { // Payment processing... } catch (\Exception $e) { // With exception chaining $this->logCriticalAndThrow( RuntimeException::class, 'Payment processing failed', ['amount' => $amount], $e // Previous exception for chaining ); } } public static function validateConfig(array $config): void { if (!isset($config['api_key'])) { // Static usage self::logErrorAndThrow( RuntimeException::class, 'API key not configured' ); } } }
Available log-and-throw methods:
| Method | Log Level |
|---|---|
logDebugAndThrow() |
DEBUG |
logInfoAndThrow() |
INFO |
logNoticeAndThrow() |
NOTICE |
logWarningAndThrow() |
WARNING |
logErrorAndThrow() |
ERROR |
logCriticalAndThrow() |
CRITICAL |
logAlertAndThrow() |
ALERT |
logEmergencyAndThrow() |
EMERGENCY |
Method signature:
log{Level}AndThrow(
string $exceptionClass, // Exception class to throw (e.g., RuntimeException::class)
string $message, // Error message (used for both log and exception)
array $context = [], // Optional: Context array for logging
?Throwable $previous = null // Optional: Previous exception for chaining
): never
Logger Management
The trait provides flexible logger management:
use ERRORToolkit\Traits\ErrorLog; use ERRORToolkit\Factories\FileLoggerFactory; class MyService { use ErrorLog; public function __construct() { // Set a specific logger for this class self::setLogger(FileLoggerFactory::getLogger('service.log')); // Or use global logger from registry (automatic fallback) self::setLogger(); // Uses LoggerRegistry::getLogger() } }
Automatic Project Detection
The trait automatically detects project names from class namespaces:
namespace MyCompany\ProjectName\Services; use ERRORToolkit\Traits\ErrorLog; class UserService { use ErrorLog; public function process() { // Project name "MyCompany" is automatically detected // Log entry: [2025-12-29 10:30:00] info [MyCompany::UserService::process()]: Processing user $this->logInfo('Processing user'); } }
Fallback Logging System
When no logger is available, the trait provides intelligent fallbacks:
- Primary: Uses configured PSR-3 logger
- Fallback 1: PHP error_log() if configured
- Fallback 2: System syslog with project-specific facility
- Fallback 3: File logging to system temp directory
class EmergencyService { use ErrorLog; public function criticalOperation() { // Even without explicit logger setup, this will work // Falls back through: error_log β syslog β temp file self::logEmergency('System failure detected'); } }
Context Support
All logging methods support PSR-3 context arrays:
class ApiService { use ErrorLog; public function handleRequest($request) { $context = [ 'method' => $request->method, 'url' => $request->url, 'user_id' => $request->user?->id, 'timestamp' => time() ]; $this->logInfo('API request received', $context); try { // Process request } catch (Exception $e) { $this->logError('API request failed', [ ...$context, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); } } }
Configuration
Log Level Filtering
use ERRORToolkit\Logger\ConsoleLogger; use Psr\Log\LogLevel; // Only log warnings and above $logger = new ConsoleLogger(LogLevel::WARNING); $logger->info('This will be ignored'); $logger->warning('This will be logged');
File Logger Options
use ERRORToolkit\Logger\FileLogger; $logger = new FileLogger( logFile: '/var/log/app.log', logLevel: LogLevel::INFO, failSafe: true, // Fallback to console/syslog on file errors maxFileSize: 5000000, // 5MB before rotation rotateLogs: true // Create .old backup when rotating );
Testing
Run the test suite:
composer test
Or run PHPUnit directly:
vendor/bin/phpunit
Cross-Platform Terminal Support
The toolkit automatically detects:
- Windows VT100 support via
sapi_windows_vt100_support() - Unix/Linux TTY via
posix_isatty() - Debug consoles (VS Code, PHPStorm, etc.)
- PHPUnit color configuration
Architecture
- Factory Pattern - All loggers created via factories with singleton behavior
- Strategy Pattern - Different logging strategies (Console, File, Null)
- Registry Pattern - Global logger management
- Trait-based - Easy integration via
ErrorLogtrait - PSR-3 Compliant - Standard logging interface
License
MIT License. See LICENSE file for details.
Author
Daniel JΓΆrg Schuppelius
- Website: schuppelius.org
- Email: info@schuppelius.org
Contributing
This is a personal toolkit for Daniel Schuppelius's projects. For bugs or feature requests, please open an issue.