1<?php
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 Aws\DynamoDb\Marshaler;
17use Monolog\Formatter\ScalarFormatter;
18use Monolog\Logger;
19
20/**
21 * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/)
22 *
23 * @link https://github.com/aws/aws-sdk-php/
24 * @author Andrew Lawson <adlawson@gmail.com>
25 */
26class DynamoDbHandler extends AbstractProcessingHandler
27{
28    const DATE_FORMAT = 'Y-m-d\TH:i:s.uO';
29
30    /**
31     * @var DynamoDbClient
32     */
33    protected $client;
34
35    /**
36     * @var string
37     */
38    protected $table;
39
40    /**
41     * @var int
42     */
43    protected $version;
44
45    /**
46     * @var Marshaler
47     */
48    protected $marshaler;
49
50    /**
51     * @param DynamoDbClient $client
52     * @param string         $table
53     * @param int            $level
54     * @param bool           $bubble
55     */
56    public function __construct(DynamoDbClient $client, $table, $level = Logger::DEBUG, $bubble = true)
57    {
58        if (defined('Aws\Sdk::VERSION') && version_compare(Sdk::VERSION, '3.0', '>=')) {
59            $this->version = 3;
60            $this->marshaler = new Marshaler;
61        } else {
62            $this->version = 2;
63        }
64
65        $this->client = $client;
66        $this->table = $table;
67
68        parent::__construct($level, $bubble);
69    }
70
71    /**
72     * {@inheritdoc}
73     */
74    protected function write(array $record)
75    {
76        $filtered = $this->filterEmptyFields($record['formatted']);
77        if ($this->version === 3) {
78            $formatted = $this->marshaler->marshalItem($filtered);
79        } else {
80            /** @phpstan-ignore-next-line */
81            $formatted = $this->client->formatAttributes($filtered);
82        }
83
84        $this->client->putItem(array(
85            'TableName' => $this->table,
86            'Item' => $formatted,
87        ));
88    }
89
90    /**
91     * @param  array $record
92     * @return array
93     */
94    protected function filterEmptyFields(array $record)
95    {
96        return array_filter($record, function ($value) {
97            return !empty($value) || false === $value || 0 === $value;
98        });
99    }
100
101    /**
102     * {@inheritdoc}
103     */
104    protected function getDefaultFormatter()
105    {
106        return new ScalarFormatter(self::DATE_FORMAT);
107    }
108}
109