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 /** 52 * @param int|string $level 53 */ 54 public function __construct(DynamoDbClient $client, string $table, $level = Logger::DEBUG, bool $bubble = true) 55 { 56 /** @phpstan-ignore-next-line */ 57 if (defined('Aws\Sdk::VERSION') && version_compare(Sdk::VERSION, '3.0', '>=')) { 58 $this->version = 3; 59 $this->marshaler = new Marshaler; 60 } else { 61 $this->version = 2; 62 } 63 64 $this->client = $client; 65 $this->table = $table; 66 67 parent::__construct($level, $bubble); 68 } 69 70 /** 71 * {@inheritdoc} 72 */ 73 protected function write(array $record): void 74 { 75 $filtered = $this->filterEmptyFields($record['formatted']); 76 if ($this->version === 3) { 77 $formatted = $this->marshaler->marshalItem($filtered); 78 } else { 79 /** @phpstan-ignore-next-line */ 80 $formatted = $this->client->formatAttributes($filtered); 81 } 82 83 $this->client->putItem([ 84 'TableName' => $this->table, 85 'Item' => $formatted, 86 ]); 87 } 88 89 protected function filterEmptyFields(array $record): array 90 { 91 return array_filter($record, function ($value) { 92 return !empty($value) || false === $value || 0 === $value; 93 }); 94 } 95 96 /** 97 * {@inheritdoc} 98 */ 99 protected function getDefaultFormatter(): FormatterInterface 100 { 101 return new ScalarFormatter(self::DATE_FORMAT); 102 } 103} 104