D8 Messenger Logger Watchdog - pierregermain/MyDrupal GitHub Wiki
tldr
Watchdog
\Drupal::logger('my_module')->notice(t('New User %username inserted.'),
[
'%username' => $form_state->getValue('username'),
]);
Messenger
\Drupal::messenger()->addStatus(t('This is a successful message.'));
\Drupal::messenger()->addWarning(t('This is a warning message.'));
\Drupal::messenger()->addError(t('This is an error message.'));
Watchdog
- En D7 se usaba watchdog(), ahora en D8 usamos el servicio 'logger.factory'.
\Drupal::logger($channel)->log($level, $message, $context)
donde:
- $channel generalmente se corresponde con nuestro módulo.
Otros métodos disponibles en LoggerInterface: https://api.drupal.org/api/drupal/vendor!psr!log!Psr!Log!LoggerInterface.php/interface/LoggerInterface/8
- emergency($message, $context)
- alert($message, $context)
- critical($message, $context)
- error($message, $context)
- warning($message, $context)
- notice($message, $context)
- info($message, $context)
- debug($message, $context)
Concretamente el método log acepta también el parámetro #level que puede ser RfcLogLevel::NOTICE, RfcLogLevel::ALERT, RfcLogLevel::EMERGENCY, etc.)
Ejemplo con log
// Ejemplo log()
\Drupal::logger('php')->log($error['severity_level'], '%type:
@message in %function (line %line of %file) @backtrace_string.',
$error);
Inyección del logger
Ejemplo: /core/modules/image/scr/ImageEffectBase.php
use Psr\Log\LoggerInterface;
//...
/**
* A logger instance.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/...
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerInterface $logger) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->setConfiguration($configuration);
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('logger.factory')->get('image')
);
}
///...
$this->logger->notice('...');
//....
$container->get('logger.factory')->get('image')
Implementar un sistema de log personalizado
para no escribir en la tabla watchdog
services
services:
logger.mymodule:
class: Drupal\mymodule\Logger\MymoduleLog
tags:
- { name: logger }
clase /src/Logger/MymoduleLoggerLog
<?php
namespace Drupal\mymodule\Logger;
use Drupal\Core\Logger\RfcLoggerTrait;
use Psr\Log\LoggerInterface;
class MymoduleLog implements LoggerInterface {
use RfcLoggerTrait;
/**
* {@inheritdoc}
*/
public function log($level, $message, array $context = []) {
// Custom log
}
}
Para usar el servicio una vez inyectado
$this->logger->notice('Test message');
Para usar el servicio sin DI:
\Drupal::service('logger.mymodule')->log(RfcLogLevel::NOTICE,"hello");
Más info sobre servicios y DI: https://github.com/pierregermain/MyDrupal/wiki/D8-Inyecci%C3%B3n-de-servicios-en-la-clase-controladora-(current-user)
Otro ejemplo completo: /core/modules/dblog/src/Logger/DbLog.php
- Uso del RfcLoggerTrait
- Sólo necesitas implementar el método Log()
Ejemplo de custom logger
Llamada desde un hook
\Drupal::logger('logger.mymodule_logger')->notice("Si se han borrado registros");
\Drupal::logger('logger.mymodule_logger')->notice("Registros borrados: ".$num);
Servicio:
services:
logger.mymodule_logger:
arguments: ['@config.factory', '@logger.log_message_parser', '@request_stack', '@current_user']
class: Drupal\mymodule_logger\Logger\MymoduleLoggerLog
tags:
- { name: logger }
Clase Logger custom:
<?php
namespace Drupal\mymodule_logger\Logger;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\File\FileSystem;
use Drupal\Core\Logger\LogMessageParserInterface;
use Drupal\Core\Logger\RfcLoggerTrait;
use Drupal\Core\Session\AccountProxyInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class MymoduleLoggerLog implements LoggerInterface {
use RfcLoggerTrait;
/**
* The message's placeholders parser.
*
* @var \Drupal\Core\Logger\LogMessageParserInterface
*/
protected $parser;
/**
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
private $config;
/**
* @var \Drupal\Core\Session\AccountProxyInterface
*/
private $currentUser;
/**
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
private $requestStack;
/**
* Constructs a MymoduleLoggerLog object.
*
* @param \Drupal\Core\Logger\LogMessageParserInterface $parser
* The parser to use when extracting message variables.
*/
public function __construct(
ConfigFactoryInterface $config_factory,
LogMessageParserInterface $parser,
RequestStack $request_stack,
AccountProxyInterface $current_user
) {
$this->config = $config_factory;
$this->parser = $parser;
$this->requestStack = $request_stack;
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public function log($level, $message, array $context = []) {
$type = mb_substr($context['channel'], 0, 64);
if ($type == 'logger.mymodule_logger') {
// Convert PSR3-style messages to \Drupal\Component\Render\FormattableMarkup
// style, so they can be translated too in runtime.
$message_placeholders = $this->parser->parseMessagePlaceholders($message, $context);
$timestamp = $context['timestamp'];
$ip = $this->requestStack->getCurrentRequest()->getClientIp();
$uri = $this->requestStack->getCurrentRequest()->getUri();
$uid = $context['uid'];
$message_str = t($message, $message_placeholders);
$mymessage = implode('|', [ $timestamp, $type, $ip, $uri, $uid, $message_str, ]);
file_put_contents(drupal_realpath("private://log/drupal_example.log"),
$mymessage . PHP_EOL, FILE_APPEND);
}
}
}