1<?php declare(strict_types=1); 2 3/* 4 * This file is part of the Monolog package. 5 * 6 * (c) Jordi Boggiano <j.boggiano@seld.be> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Monolog\Handler; 13 14use Aws\Sdk; 15use Aws\DynamoDb\DynamoDbClient; 16use Monolog\Formatter\FormatterInterface; 17use Aws\DynamoDb\Marshaler; 18use Monolog\Formatter\ScalarFormatter; 19use Monolog\Logger; 20 21/** 22 * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/) 23 * 24 * @link https://github.com/aws/aws-sdk-php/ 25 * @author Andrew Lawson <adlawson@gmail.com> 26 */ 27class DynamoDbHandler extends AbstractProcessingHandler 28{ 29 public const DATE_FORMAT = 'Y-m-d\TH:i:s.uO'; 30 31 /** 32 * @var DynamoDbClient 33 */ 34 protected $client; 35 36 /** 37 * @var string 38 */ 39 protected $table; 40 41 /** 42 * @var int 43 */ 44 protected $version; 45 46 /** 47 * @var Marshaler 48 */ 49 protected $marshaler; 50 51 public function __construct(DynamoDbClient $client, string $table, $level = Logger::DEBUG, bool $bubble = true) 52 { 53 /** @phpstan-ignore-next-line */ 54 if (defined('Aws\Sdk::VERSION') && version_compare(Sdk::VERSION, '3.0', '>=')) { 55 $this->version = 3; 56 $this->marshaler = new Marshaler; 57 } else { 58 $this->version = 2; 59 } 60 61 $this->client = $client; 62 $this->table = $table; 63 64 parent::__construct($level, $bubble); 65 } 66 67 /** 68 * {@inheritDoc} 69 */ 70 protected function write(array $record): void 71 { 72 $filtered = $this->filterEmptyFields($record['formatted']); 73 if ($this->version === 3) { 74 $formatted = $this->marshaler->marshalItem($filtered); 75 } else { 76 /** @phpstan-ignore-next-line */ 77 $formatted = $this->client->formatAttributes($filtered); 78 } 79 80 $this->client->putItem([ 81 'TableName' => $this->table, 82 'Item' => $formatted, 83 ]); 84 } 85 86 /** 87 * @param mixed[] $record 88 * @return mixed[] 89 */ 90 protected function filterEmptyFields(array $record): array 91 { 92 return array_filter($record, function ($value) { 93 return !empty($value) || false === $value || 0 === $value; 94 }); 95 } 96 97 /** 98 * {@inheritDoc} 99 */ 100 protected function getDefaultFormatter(): FormatterInterface 101 { 102 return new ScalarFormatter(self::DATE_FORMAT); 103 } 104} 105