Logging Service

The logging service is the only example of a service provided in the foundations module. That's because we believe that every plugin should use logging (hence also why every service is forced to implement the LoggingServiceAwareInterface interface).

In short, the logging service is a multi-handler service that accepts any handler implementing the LoggingHandlerInterface interface. It's expected to provide the service with two handlers, one with the ID framework and one with the ID plugin.

By default, the logging service attempts to log using the plugin handler, whereas messages logged by framework modules will always use the framework handler. In order to include sensitive data in the log messages, you need to instantiate the service with the second parameter set to true.

The logging service doesn't understand what data is of sensitive nature and which is not. It's your responsibility to mark it accordingly when composing the logged message.

If you want to disable logging for your plugin, it's enough to not register the two aforementioned handlers. The service will simply default to using the NullLogger.

The default logging handler requires an ID and a PSR-3 logger. We recommend using Monolog for your PSR-3 logger needs, but if you're building a WooCommerce plugin, please be aware that the WooCommerce module provides a handler compatible with the WooCommerce logger.

Here is a simple example for instantiating the logging service using Monolog loggers:

<?php

namespace DeepWebSolutions\Plugins\MyTestPlugin;

use DeepWebSolutions\Framework\Foundations\Logging\LoggingHandler;
use DeepWebSolutions\Framework\Foundations\Logging\LoggingService;
use DeepWebSolutions\Framework\Helpers\WordPress\Request;

use Monolog\Handler\RotatingFileHandler as MonologRotatingFileHandler;
use Monolog\Logger as MonologLogger;

use function DeepWebSolutions\Framework\dws_wp_framework_get_temp_dir_path;


$min_log_level = Request::has_debug() ? MonologLogger::DEBUG : MonologLogger::ERROR;
$logs_path     = dws_wp_framework_get_temp_dir_path() . 'my-test-plugin' . DIRECTORY_SEPARATOR;

$monolog_handler = new MonologRotatingFileHandler( $logs_path . 'errors.log', 30, $min_log_level );
$dws_handlers    = array(
    new LoggingHandler( 'framework', new MonologLogger( 'framework', array( $monolog_handler ) ) ),
    new LoggingHandler( 'plugin', new MonologLogger( 'plugin', array( $monolog_handler ) ) ),
);

$plugin_instance     = dws_test_plugin_instance();
$dws_logging_service = new LoggingService( $plugin_instance, $dws_handlers, Request::has_debug() );

The logging service provides two public methods:

  • log_event -- returns an instance of the LogMessageBuilder class which can be further configured to perform other actions before logging the message.

  • log_event_and_finalize -- shortcut for calling the log_event method and finalizing the message.

Instances of the LogMessageBuilder class need to have the finalize method called on them for the message to be logged and the other actions performed as well.

If you don't call finalize on LogMessageBuilder objects, the message will never be logged!

A few things that the message builder can do:

  • If the service is configured to ignore sensitive content, it removes all the text wrapped in <sensitive></sensitive> tags.

  • It can log the message using WordPress' _doing_it_wrong as well.

  • By default, it returns null when calling finalize, but it can be configured to return the logged message wrapped in an exception or a given throwable object.

And here are examples on how to use the message builder (we'll assume the logging service instantiated above is present in this context as well):

<?php

use DeepWebSolutions\Framework\Foundations\Exceptions\NotFoundException;
use Psr\Log\LogLevel;

// The following two lines are EQUIVALENT.
$dws_logging_service->log_event( 'Error happened' )
                ->set_log_level( LogLevel::DEBUG )
                ->finalize();

$dws_logging_service->log_event_and_finalize( 'Error happened' );

// This message will be logged with WP too.
$dws_logging_service->log_event( 'Error happened in function' )
                ->doing_it_wrong( 'my_awesome_func', '1.3.5' )
                ->finalize();

// This message will return an exception.
$exception = $dws_logging_service->log_event_and_finalize( 'Property A not found' )
                ->return_exception( NotFoundException::class )
                ->finalize();
echo get_class( $exception ); // echoes 'NotFoundException'
echo $exception->getMessage(); // echoes 'Property A not found'

Last updated