monkeyscloud/monkeyslegion-logger

Advanced logger for the MonkeysLegion PHP framework.

Installs: 19

Dependents: 4

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/monkeyscloud/monkeyslegion-logger

1.0.2 2025-11-20 09:26 UTC

This package is auto-updated.

Last update: 2025-11-21 09:29:09 UTC


README

A flexible, PSR-3 compliant PHP logging library with environment-aware logging, multiple drivers, and extensive configuration options.

PHP Version License

Features

  • ๐ŸŽฏ PSR-3 Compliant - Implements PSR-3 LoggerInterface
  • ๐ŸŒ Environment-Aware Logging - Smart logging based on environment
  • ๐Ÿ”Œ Multiple Drivers - File, Console, Syslog, Error Log, Null, and Stack
  • ๐ŸŽจ Colorized Console Output - Beautiful colored terminal logs
  • ๐Ÿ“Š Log Level Filtering - Control what gets logged
  • ๐ŸŽญ Custom Formatting - Flexible message formatting
  • ๐Ÿ“š Stack Logger - Combine multiple loggers
  • ๐Ÿ“… Daily Rotation - Automatic date-based log file rotation
  • ๐Ÿ”„ Circular Dependency Detection - Prevents infinite loops
  • ๐Ÿงช Fully Tested - Comprehensive test coverage
  • ๐Ÿ’ช Type-Safe - Full PHPStan level max compliance

Installation

composer require monkeyscloud/monkeyslegion-logger

Quick Start

use MonkeysLegion\Logger\Factory\LoggerFactory;

// Load configuration
$config = require 'config/logging.php';

// Create logger factory
$factory = new LoggerFactory($config, 'production');

// Get default logger
$logger = $factory->make();

// Start logging
$logger->info('Application started', ['user_id' => 123]);
$logger->error('Database connection failed', ['error' => $e->getMessage()]);

Configuration

Create a configuration file (e.g., config/logging.php):

<?php

return [
    'default' => $_ENV['LOG_CHANNEL'] ?? 'stack',

    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['daily', 'console'],
        ],

        'single' => [
            'driver' => 'file',
            'path' => 'logs/app.log',
            'level' => 'debug',
        ],

        'daily' => [
            'driver' => 'file',
            'path' => 'logs/app.log',
            'daily' => true,  // Enable daily rotation
            'date_format' => 'Y-m-d',  // Optional, defaults to Y-m-d
            'level' => 'debug',
            'format' => '[{timestamp}] [{env}] {level}: {message} {context}',
        ],

        'console' => [
            'driver' => 'console',
            'level' => 'debug',
            'colorize' => true,
            'format' => '[{env}] {level}: {message} {context}',
        ],

        'syslog' => [
            'driver' => 'syslog',
            'level' => 'warning',
            'ident' => 'my-app',
            'facility' => LOG_USER,
        ],

        'errorlog' => [
            'driver' => 'errorlog',
            'level' => 'error',
            'message_type' => 0,
        ],

        'null' => [
            'driver' => 'null',
        ],
    ],
];

Available Drivers

File Logger

Logs to files with optional date-based rotation.

Single File (No Rotation):

'single' => [
    'driver' => 'file',
    'path' => 'logs/app.log',
    'level' => 'debug',
    'format' => '[{timestamp}] {level}: {message} {context}',
]

Daily Rotation:

'daily' => [
    'driver' => 'file',
    'path' => 'logs/app.log',
    'daily' => true,  // Enable daily rotation
    'date_format' => 'Y-m-d',  // Optional, defaults to Y-m-d
    'level' => 'debug',
    'format' => '[{timestamp}] [{env}] {level}: {message} {context}',
]

When daily rotation is enabled:

  • logs/app.log โ†’ logs/app-2024-01-15.log
  • logs/errors.log โ†’ logs/errors-2024-01-15.log
  • logs/debug.txt โ†’ logs/debug-2024-01-15.txt

The date is automatically inserted before the file extension!

Console Logger

Outputs to console with optional colorization.

'console' => [
    'driver' => 'console',
    'level' => 'debug',
    'colorize' => true,
    'format' => '[{env}] {level}: {message}',
]

Color Scheme:

  • ๐Ÿ”ด Emergency/Alert/Critical - Bold Red
  • ๐Ÿ”ด Error - Red
  • ๐ŸŸก Warning - Yellow
  • ๐Ÿ”ต Notice - Cyan
  • ๐ŸŸข Info - Green
  • โšช Debug - White

Syslog Logger

Sends logs to system logger.

'syslog' => [
    'driver' => 'syslog',
    'level' => 'warning',
    'ident' => 'my-application',
    'facility' => LOG_USER,
]

Error Log Logger

Uses PHP's native error_log() function.

'errorlog' => [
    'driver' => 'errorlog',
    'level' => 'error',
    'message_type' => 0, // 0=system, 1=email, 3=file, 4=SAPI
    'destination' => null, // Required for types 1 and 3
]

Null Logger

Discards all log messages (useful for testing).

'null' => [
    'driver' => 'null',
]

Stack Logger

Combines multiple loggers to write to multiple destinations.

'stack' => [
    'driver' => 'stack',
    'channels' => ['daily', 'console', 'syslog'],
]

Usage Examples

Basic Logging

use MonkeysLegion\Logger\Factory\LoggerFactory;

$factory = new LoggerFactory($config);
$logger = $factory->make('daily');

// PSR-3 log levels
$logger->emergency('System is down!');
$logger->alert('Database is unavailable');
$logger->critical('Application crash');
$logger->error('User registration failed');
$logger->warning('Disk space low');
$logger->notice('User logged in');
$logger->info('Email sent successfully');
$logger->debug('Processing request', ['data' => $requestData]);

Daily Rotation Example

$config = [
    'channels' => [
        'daily' => [
            'driver' => 'file',
            'path' => 'logs/app.log',
            'daily' => true,  // Enable rotation
        ],
        'errors_daily' => [
            'driver' => 'file',
            'path' => 'logs/errors.log',
            'daily' => true,
            'date_format' => 'Y-m-d',
            'level' => 'error',
        ],
    ],
];

$factory = new LoggerFactory($config);
$logger = $factory->make('daily');

$logger->info('This logs to logs/app-2024-01-15.log');

$errorLogger = $factory->make('errors_daily');
$errorLogger->error('This logs to logs/errors-2024-01-15.log');

Environment-Aware Smart Logging

The smartLog() method automatically adjusts log levels based on environment:

// Production: logs as INFO
// Staging: logs as NOTICE
// Testing: logs as WARNING
// Development: logs as DEBUG
$logger->smartLog('Processing payment', ['amount' => 99.99]);

Contextual Logging

$logger->info('User action', [
    'user_id' => 42,
    'action' => 'purchase',
    'amount' => 99.99,
    'timestamp' => time(),
]);

// Output: [2024-01-15 10:30:45] [production] INFO: User action {"user_id":42,"action":"purchase","amount":99.99,"timestamp":1705315845}

Using Different Channels

$factory = new LoggerFactory($config);

// Production logging with daily rotation
$productionLogger = $factory->make('stack');
$productionLogger->info('Application started');

// Debug logging to daily file
$debugLogger = $factory->make('daily');
$debugLogger->debug('Debugging info', ['vars' => $debug]);

// Emergency logging
$emergencyLogger = $factory->make('syslog');
$emergencyLogger->emergency('Critical system failure');

Custom Formatting

Format tokens:

  • {timestamp} - Current date/time
  • {env} - Environment name
  • {level} - Log level (uppercase)
  • {message} - Log message
  • {context} - JSON-encoded context
'custom' => [
    'driver' => 'file',
    'path' => 'logs/custom.log',
    'format' => '{timestamp}|{level}|{message}',
]

// Output: 2024-01-15 10:30:45|INFO|User logged in

Log Level Filtering

Only logs at or above the specified level are written:

'production' => [
    'driver' => 'file',
    'path' => 'logs/production.log',
    'daily' => true,
    'level' => 'warning', // Only warning, error, critical, alert, emergency
]

$logger->debug('Debug info');    // Not logged
$logger->info('Info message');   // Not logged
$logger->warning('Warning!');    // Logged โœ“ to logs/production-2024-01-15.log
$logger->error('Error occurred'); // Logged โœ“ to logs/production-2024-01-15.log

Log Level Hierarchy:

DEBUG < INFO < NOTICE < WARNING < ERROR < CRITICAL < ALERT < EMERGENCY

Advanced Usage

Factory with Environment

// Automatically uses APP_ENV from environment
$factory = new LoggerFactory($config);

// Or explicitly set environment
$factory = new LoggerFactory($config, 'production');
$factory = new LoggerFactory($config, 'development');

Multiple Loggers with Daily Rotation

$config = [
    'channels' => [
        'app' => [
            'driver' => 'file',
            'path' => 'logs/app.log',
            'daily' => true,
        ],
        'errors' => [
            'driver' => 'file',
            'path' => 'logs/errors.log',
            'daily' => true,
            'level' => 'error',
        ],
        'audit' => [
            'driver' => 'file',
            'path' => 'logs/audit.log',
            'daily' => true,
            'date_format' => 'Y-m-d',
        ],
    ],
];

$appLogger = $factory->make('app');
$errorLogger = $factory->make('errors');
$auditLogger = $factory->make('audit');

try {
    // Your code
} catch (\Exception $e) {
    $errorLogger->error('Exception caught', [
        'exception' => $e->getMessage(),
        'trace' => $e->getTraceAsString(),
    ]);
}

$auditLogger->info('User action', ['user_id' => $userId, 'action' => 'login']);
$appLogger->debug('Request details', ['request' => $_REQUEST]);

// This creates:
// - logs/app-2024-01-15.log
// - logs/errors-2024-01-15.log (only errors and above)
// - logs/audit-2024-01-15.log

Testing with Null Logger

class UserService
{
    public function __construct(
        private MonkeysLoggerInterface $logger
    ) {}
}

// Production
$service = new UserService($factory->make('stack'));

// Testing - no actual logging
$service = new UserService($factory->make('null'));

Environment Configuration

# .env file
LOG_CHANNEL=stack
LOG_LEVEL=debug
APP_ENV=production
APP_NAME=my-application

Best Practices

1. Use Appropriate Log Levels

// โŒ Bad
$logger->info('Database connection failed');

// โœ… Good
$logger->error('Database connection failed', [
    'host' => $dbHost,
    'error' => $e->getMessage(),
]);

2. Add Context

// โŒ Bad
$logger->error('Payment failed');

// โœ… Good
$logger->error('Payment failed', [
    'user_id' => $userId,
    'amount' => $amount,
    'payment_method' => $method,
    'error_code' => $errorCode,
]);

3. Use Daily Rotation for Production

// โœ… Good for production
'production' => [
    'driver' => 'file',
    'path' => 'logs/app.log',
    'daily' => true,  // New file each day
    'level' => 'warning',
]

// โŒ Avoid single file in production (grows indefinitely)
'production' => [
    'driver' => 'file',
    'path' => 'logs/app.log',
    'daily' => false,
]

4. Use smartLog() for General Flow

// Automatically adjusts based on environment
$logger->smartLog('Processing order', ['order_id' => $orderId]);

5. Configure Per Environment

// config/logging-production.php
return [
    'default' => 'stack',
    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['syslog', 'daily'],
        ],
        'daily' => [
            'driver' => 'file',
            'path' => 'logs/app.log',
            'daily' => true,
            'level' => 'warning',  // Only warnings and above
        ],
    ],
];

// config/logging-development.php
return [
    'default' => 'console',
    'channels' => [
        'console' => [
            'driver' => 'console',
            'level' => 'debug',  // Everything in development
            'colorize' => true,
        ],
    ],
];

Testing

Run the test suite:

# Install dependencies
composer install

# Run tests
./vendor/bin/phpunit

# Run with coverage
./vendor/bin/phpunit --coverage-html coverage

# Run static analysis
./vendor/bin/phpstan analyse

Requirements

  • PHP 8.1 or higher
  • PSR-3 Logger Interface

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please submit pull requests or open issues on GitHub.

Support

For issues, questions, or suggestions, please open an issue on GitHub.

Changelog

Version 1.0.0

  • Initial release
  • PSR-3 compliant logging
  • Multiple driver support (File, Console, Syslog, ErrorLog, Null, Stack)
  • Environment-aware logging with smartLog()
  • Daily rotation support for file logger
  • Custom formatting with tokens
  • Log level filtering
  • Full test coverage
  • PHPStan level max compliance

Made with โค๏ธ by MonkeysLegion