Logging
The Pollora framework provides a WordPress error logging system. This system captures WordPress errors, warnings, and deprecated function usage, logging them through Laravel’s logging infrastructure while preventing them from breaking your application.
Overview
Section titled “Overview”The WordPress logging module intercepts and logs various WordPress error types:
- Doing it wrong: When WordPress functions are used incorrectly
- Deprecated functions: When deprecated WordPress functions are called
- Deprecated arguments: When functions are called with deprecated parameters
All errors are logged to a dedicated wordpress log channel while preventing PHP errors from being displayed to users.
Architecture
Section titled “Architecture”The logging system follows a strict DDD architecture with clear separation of concerns:
Domain Layer (src/Logging/Domain/)
Section titled “Domain Layer (src/Logging/Domain/)”Contracts
Section titled “Contracts”WordPressErrorLoggerInterface: Defines the contract for logging WordPress errorsWordPressErrorHookRegistrarInterface: Defines the contract for registering WordPress hooks
Models
Section titled “Models”WordPressError: Domain entity representing a WordPress error with contextual informationWordPressErrorType: Enum defining the three types of WordPress errors and their log levels
Services
Section titled “Services”WordPressErrorHandler: Pure domain service handling error processing logic
Application Layer (src/Logging/Application/)
Section titled “Application Layer (src/Logging/Application/)”Services
Section titled “Services”WordPressErrorLoggingService: Orchestrates error handling, builds context, and coordinates between domain and infrastructure layers
Infrastructure Layer (src/Logging/Infrastructure/)
Section titled “Infrastructure Layer (src/Logging/Infrastructure/)”Adapters
Section titled “Adapters”LaravelWordPressErrorLogger: Adapts domain logging interface to Laravel’s logging system
Services
Section titled “Services”WordPressErrorHookRegistrar: Registers WordPress hooks and filters using the container pattern
Providers
Section titled “Providers”LoggingServiceProvider: Configures dependency injection and initializes the logging system
Support Layer (src/Support/)
Section titled “Support Layer (src/Support/)”Facades
Section titled “Facades”WordPressError: Laravel facade providing convenient static methods for logging WordPress errors
The logging system is automatically registered through the main PolloraServiceProvider. No manual configuration is required for basic usage.
Laravel Facade (Recommended)
Section titled “Laravel Facade (Recommended)”The simplest way to log WordPress errors in Laravel is using the WordPressError facade:
use Pollora\Support\Facades\WordPressError;
// Log a "doing it wrong" errorWordPressError::doingItWrong( 'wp_enqueue_script', 'Scripts should be enqueued in wp_enqueue_scripts action', '6.0.0');
// Log a deprecated function usageWordPressError::deprecatedFunction( 'mysql_query', 'wpdb::prepare()', '3.9.0');
// Log a deprecated argument usageWordPressError::deprecatedArgument( 'get_posts', 'The "numberposts" parameter is deprecated. Use "posts_per_page" instead.', '4.4.0');Error Types and Log Levels
Section titled “Error Types and Log Levels”// Domain model showing error types and their log levelsenum WordPressErrorType: string{ case DOING_IT_WRONG = 'doing_it_wrong'; // Logs as 'warning' case DEPRECATED_FUNCTION = 'deprecated_function'; // Logs as 'info' case DEPRECATED_ARGUMENT = 'deprecated_argument'; // Logs as 'info'}Creating WordPress Errors
Section titled “Creating WordPress Errors”The WordPressError model provides static factory methods:
// For "doing it wrong" errors$error = WordPressError::doingItWrong( function: 'wp_enqueue_script', message: 'Scripts should be enqueued in wp_enqueue_scripts action', version: '6.0.0', context: ['url' => 'https://example.com']);
// For deprecated functions$error = WordPressError::deprecatedFunction( function: 'mysql_query', replacement: 'wpdb::prepare()', version: '3.9.0', context: ['file' => 'plugins/old-plugin/plugin.php']);
// For deprecated arguments$error = WordPressError::deprecatedArgument( function: 'get_posts', message: 'The "numberposts" parameter is deprecated. Use "posts_per_page" instead.', version: '4.4.0', context: ['caller' => 'my_theme_function()']);Configuration
Section titled “Configuration”Environment Variables
Section titled “Environment Variables”Configure the WordPress logging channel through environment variables:
# Log level for WordPress errors (debug, info, notice, warning, error, critical, alert, emergency)WORDPRESS_LOG_LEVEL=debug
# Number of days to retain WordPress logsWORDPRESS_LOG_DAYS=7Custom Configuration
Section titled “Custom Configuration”Override the default logging configuration in your config/logging.php:
'channels' => [ 'wordpress' => [ 'driver' => 'single', 'path' => storage_path('logs/wordpress.log'), 'level' => env('WORDPRESS_LOG_LEVEL', 'debug'), 'days' => env('WORDPRESS_LOG_DAYS', 7), 'replace_placeholders' => true, ],],Advanced Configuration
Section titled “Advanced Configuration”For more complex setups, you can configure multiple channels or use different drivers:
'channels' => [ 'wordpress' => [ 'driver' => 'stack', 'channels' => ['wordpress-file', 'wordpress-slack'], ],
'wordpress-file' => [ 'driver' => 'daily', 'path' => storage_path('logs/wordpress.log'), 'level' => 'info', 'days' => 14, ],
'wordpress-slack' => [ 'driver' => 'slack', 'url' => env('SLACK_WEBHOOK_URL'), 'username' => 'WordPress Logger', 'emoji' => ':warning:', 'level' => 'warning', ],],Context Information
Section titled “Context Information”The logging system automatically includes contextual information:
Standard Context
Section titled “Standard Context”- type: Error type (
doing_it_wrong,deprecated_function,deprecated_argument) - function: Name of the WordPress function
- version: WordPress version where the issue was introduced
- message: Error description (HTML tags stripped)
- url: Current request URL
- method: HTTP method
- ip: Client IP address
Development Context
Section titled “Development Context”In local environments, additional debugging information is included:
- backtrace: Clean stack trace (limited to 10 frames, excluding internal logging calls)
Example Log Entry
Section titled “Example Log Entry”{ "message": "WordPress: wp_enqueue_script called incorrectly", "context": { "type": "doing_it_wrong", "function": "wp_enqueue_script", "version": "6.0.0", "message": "Scripts should be enqueued in wp_enqueue_scripts action", "url": "https://example.com/admin", "method": "GET", "ip": "192.168.1.100", "backtrace": [ "#0 MyTheme\\Services\\AssetService::enqueueScripts() in /themes/mytheme/app/Services/AssetService.php:45", "#1 MyTheme\\Providers\\ThemeServiceProvider::boot() in /themes/mytheme/app/Providers/ThemeServiceProvider.php:23" ] }, "level": "warning", "level_name": "WARNING", "channel": "wordpress", "datetime": "2024-01-15T10:30:45.123456+00:00"}Extending the System
Section titled “Extending the System”Custom Error Logger
Section titled “Custom Error Logger”Implement your own logger by creating a class that implements WordPressErrorLoggerInterface:
use Pollora\Logging\Domain\Contracts\WordPressErrorLoggerInterface;use Pollora\Logging\Domain\Models\WordPressError;
class CustomWordPressErrorLogger implements WordPressErrorLoggerInterface{ public function logError(WordPressError $error): void { // Custom logging implementation $this->sendToExternalService($error); }}Then bind it in your service provider:
$this->app->bind( WordPressErrorLoggerInterface::class, CustomWordPressErrorLogger::class);Custom Hook Registration
Section titled “Custom Hook Registration”Implement custom hook registration by implementing WordPressErrorHookRegistrarInterface:
use Pollora\Logging\Domain\Contracts\WordPressErrorHookRegistrarInterface;
class CustomWordPressErrorHookRegistrar implements WordPressErrorHookRegistrarInterface{ public function registerErrorHandlers(): void { // Custom hook registration logic add_action('doing_it_wrong_run', [$this, 'handleError'], 10, 3); // ... register other hooks }}Testing
Section titled “Testing”The DDD architecture makes the logging system highly testable:
Testing Domain Logic
Section titled “Testing Domain Logic”use Pollora\Logging\Domain\Models\WordPressError;use Pollora\Logging\Domain\Models\WordPressErrorType;
class WordPressErrorTest extends TestCase{ public function test_doing_it_wrong_error_creation(): void { $error = WordPressError::doingItWrong( 'wp_enqueue_script', 'Invalid usage', '6.0.0' );
$this->assertEquals(WordPressErrorType::DOING_IT_WRONG, $error->type); $this->assertEquals('warning', $error->getLogLevel()); $this->assertEquals('WordPress: wp_enqueue_script called incorrectly', $error->getLogMessage()); }}Testing Application Services
Section titled “Testing Application Services”use Pollora\Logging\Application\Services\WordPressErrorLoggingService;use Pollora\Logging\Domain\Services\WordPressErrorHandler;
class WordPressErrorLoggingServiceTest extends TestCase{ public function test_handles_doing_it_wrong(): void { $mockHandler = $this->mock(WordPressErrorHandler::class); $mockHandler->shouldReceive('handleDoingItWrong') ->once() ->with('wp_enqueue_script', 'Invalid usage', '6.0.0', Mockery::type('array'));
$service = new WordPressErrorLoggingService( $mockHandler, app(), request() );
$service->handleDoingItWrong('wp_enqueue_script', 'Invalid usage', '6.0.0'); }}Testing with Facade
Section titled “Testing with Facade”use Pollora\Support\Facades\WordPressError;use Pollora\Logging\Application\Services\WordPressErrorLoggingService;
class WordPressErrorFacadeTest extends TestCase{ public function test_facade_logs_doing_it_wrong(): void { $mockService = $this->mock(WordPressErrorLoggingService::class); $mockService->shouldReceive('handleDoingItWrong') ->once() ->with('wp_enqueue_script', 'Invalid usage', '6.0.0');
$this->app->instance(WordPressErrorLoggingService::class, $mockService);
WordPressError::doingItWrong('wp_enqueue_script', 'Invalid usage', '6.0.0'); }}Performance Considerations
Section titled “Performance Considerations”Lazy Hook Registration
Section titled “Lazy Hook Registration”The system uses Laravel’s container to resolve dependencies only when WordPress hooks are triggered, avoiding circular dependencies and reducing memory usage.
Backtrace Limitations
Section titled “Backtrace Limitations”- Backtraces are only generated in local environments
- Limited to 10 stack frames to prevent memory issues
- Arguments are excluded from backtraces for performance
Log Rotation
Section titled “Log Rotation”Configure appropriate log rotation to prevent disk space issues:
'wordpress' => [ 'driver' => 'daily', 'path' => storage_path('logs/wordpress.log'), 'level' => 'info', 'days' => 7, // Keep logs for 7 days],Troubleshooting
Section titled “Troubleshooting”Debugging
Section titled “Debugging”Enable debug mode to see backtraces in logs:
APP_ENV=localWORDPRESS_LOG_LEVEL=debugLog File Locations
Section titled “Log File Locations”Default log file locations:
- Single channel:
storage/logs/wordpress.log - Daily rotation:
storage/logs/wordpress-YYYY-MM-DD.log - Laravel default:
storage/logs/laravel.log(if fallback occurs)
Best Practices
Section titled “Best Practices”- Use appropriate log levels: Set
WORDPRESS_LOG_LEVEL=infoin production to avoid debug noise - Monitor log size: Implement log rotation in production environments
- Custom context: Add relevant context when manually creating WordPress errors
- Error handling: The system prevents WordPress errors from breaking your application, but fix underlying issues
- Performance: Avoid logging in tight loops; the system is designed for occasional WordPress errors, not high-frequency logging
Integration with Monitoring
Section titled “Integration with Monitoring”The WordPress logging system integrates seamlessly with Laravel’s logging infrastructure, making it compatible with:
- Laravel Telescope: View WordPress errors in the logs section
- Flare: Automatic error reporting and grouping
- Bugsnag/Sentry: External error monitoring services
- ELK Stack: Elasticsearch, Logstash, and Kibana for log analysis
- Custom dashboards: Parse structured log data for monitoring dashboards