Skip to content

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.

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.

The logging system follows a strict DDD architecture with clear separation of concerns:

  • WordPressErrorLoggerInterface: Defines the contract for logging WordPress errors
  • WordPressErrorHookRegistrarInterface: Defines the contract for registering WordPress hooks
  • WordPressError: Domain entity representing a WordPress error with contextual information
  • WordPressErrorType: Enum defining the three types of WordPress errors and their log levels
  • WordPressErrorHandler: Pure domain service handling error processing logic

Application Layer (src/Logging/Application/)

Section titled “Application Layer (src/Logging/Application/)”
  • 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/)”
  • LaravelWordPressErrorLogger: Adapts domain logging interface to Laravel’s logging system
  • WordPressErrorHookRegistrar: Registers WordPress hooks and filters using the container pattern
  • LoggingServiceProvider: Configures dependency injection and initializes the logging system
  • 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.

The simplest way to log WordPress errors in Laravel is using the WordPressError facade:

use Pollora\Support\Facades\WordPressError;
// Log a "doing it wrong" error
WordPressError::doingItWrong(
'wp_enqueue_script',
'Scripts should be enqueued in wp_enqueue_scripts action',
'6.0.0'
);
// Log a deprecated function usage
WordPressError::deprecatedFunction(
'mysql_query',
'wpdb::prepare()',
'3.9.0'
);
// Log a deprecated argument usage
WordPressError::deprecatedArgument(
'get_posts',
'The "numberposts" parameter is deprecated. Use "posts_per_page" instead.',
'4.4.0'
);
// Domain model showing error types and their log levels
enum 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'
}

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()']
);

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 logs
WORDPRESS_LOG_DAYS=7

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,
],
],

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',
],
],

The logging system automatically includes contextual information:

  • 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

In local environments, additional debugging information is included:

  • backtrace: Clean stack trace (limited to 10 frames, excluding internal logging calls)
{
"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"
}

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
);

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
}
}

The DDD architecture makes the logging system highly testable:

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());
}
}
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');
}
}
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');
}
}

The system uses Laravel’s container to resolve dependencies only when WordPress hooks are triggered, avoiding circular dependencies and reducing memory usage.

  • Backtraces are only generated in local environments
  • Limited to 10 stack frames to prevent memory issues
  • Arguments are excluded from backtraces for performance

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
],

Enable debug mode to see backtraces in logs:

APP_ENV=local
WORDPRESS_LOG_LEVEL=debug

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)
  1. Use appropriate log levels: Set WORDPRESS_LOG_LEVEL=info in production to avoid debug noise
  2. Monitor log size: Implement log rotation in production environments
  3. Custom context: Add relevant context when manually creating WordPress errors
  4. Error handling: The system prevents WordPress errors from breaking your application, but fix underlying issues
  5. Performance: Avoid logging in tight loops; the system is designed for occasional WordPress errors, not high-frequency logging

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