L’attività di logging se ben concepita può essere una miniera di informazioni per il debug di errori e per tenere traccia di quello che succede nell’applicazione, per capire cosa è andato storto o anche solo per monitorare l’attività degli utenti che ha indotto all’errore.
Se avete dimestichezza con Symfony avrete sicuramente imparato ad amare la versatilità di Monolog, scritto dallo stesso sviluppatore che ha inventato Composer.
Monolog supporta canali (Channels) di log differenti, ciascuno dei quali associati a degli Handler che sono in grado di scrivere un messaggio di log sulle destinazioni più disparate, da un semplice database passando per Syslog fino a soluzioni più evolute come postare un messaggio su Slack o Logstash.
Utilizzando un handler di Monolog possiamo interfacciarci con Amazon CloudWatch che è un servizio di monitoraggio per le risorse cloud AWS e le applicazioni in esecuzione su AWS. Si può utilizzare Amazon CloudWatch per raccogliere e monitorare parametri e file di log, impostare allarmi e reagire automaticamente ai cambiamenti nelle risorse AWS.
Quindi andiamo per ordine:
composer require drupal/monolog:^1.0
composer require maxbanton/cwh:^1.0
$settings['container_yamls'][] = 'sites/default/monolog.services.yml';
Ora abbiamo due possibili strade, la cui scelta dipende solo dalle specifiche esigenze del progetto.
Nel file sites/default/monolog.services.yml
mettiamo queste impostazioni sostituendo i parametri che iniziano con my_
che sono solamente dei segnaposto.
--- parameters: monolog.channel_handlers: default: - cloudwatch_handler monolog.processors: - message_placeholder - current_user - request_uri - ip - referer services: cloudwatch_client: class: Aws\CloudWatchLogs\CloudWatchLogsClient arguments: - credentials: key: my_amazon_accesskey secret: my_amazon_secretkey region: my_amazon_region version: latest cloudwatch_handler: class: Maxbanton\Cwh\Handler\CloudWatch arguments: - "@cloudwatch_client" - my_group_name - my_stream_name - 30 - 10000 - mytag: tag - DEBUG
Se vogliamo fare in modo che ogni channel, magari per una migliore leggibilità dei log, venga scritto in un proprio stream dobbiamo prima creare un handler custom che possiamo mettere in un modulo creato appositamente oppure in un altro modulo custom. Occhio solo a mettere il namespace
corretto.
<?php namespace Drupal\my_custom_module\Logger\Handler; use Aws\CloudWatchLogs\CloudWatchLogsClient; use Maxbanton\Cwh\Handler\CloudWatch; use Monolog\Handler\AbstractProcessingHandler; use Monolog\Logger; /** * Class CloudWatchHandler * * @package Drupal\my_custom_module\Logger\Handler */ class CloudWatchHandler extends AbstractProcessingHandler { /** * CloudWatch constructor. */ public function __construct() { parent::__construct(Logger::DEBUG, TRUE); } /** * Writes the record down to the log of the implementing handler * * @param array $record * * @return void */ protected function write(array $record) { $sdkParams = [ 'region' => "my_amazon_region", 'version' => "latest", 'credentials' => [ 'key' => "my_amazon_key", 'secret' => "my_amazon_secret", ], ]; $client = new CloudWatchLogsClient($sdkParams); $group = "my_group_name"; if (empty($record['channel'])) { $stream = "default"; } else { $stream = $record['channel']; } /** @var \Maxbanton\Cwh\Handler\CloudWatch $handler */ $handler = new CloudWatch($client, $group, $stream, 30, 10000, [], Logger::DEBUG); $handler->write($record); } }
A questo punto nel nostro file sites/default/monolog.services.yml
mettiamo le configurazioni:
--- parameters: monolog.channel_handlers: default: - cloudwatch_handler monolog.processors: - message_placeholder - current_user - request_uri - ip - referer services: cloudwatch_handler: class: Drupal\my_custom_module\Logger\Handler\CloudWatchHandler #Modificare con il namespace corretto
Come si può notare il servizio è molto spartano, ma può essere ampliato iniettando come argomento magari \Drupal\Core\Config\ConfigFactoryInterface $config_factory per caricare una configurazione oppure \Drupal\Core\Entity\EntityTypeManager $entity_type_manager per interfacciarsi con il repository di un’entità.