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\Formatter;
13
14use Monolog\Utils;
15
16/**
17 * Class FluentdFormatter
18 *
19 * Serializes a log message to Fluentd unix socket protocol
20 *
21 * Fluentd config:
22 *
23 * <source>
24 *  type unix
25 *  path /var/run/td-agent/td-agent.sock
26 * </source>
27 *
28 * Monolog setup:
29 *
30 * $logger = new Monolog\Logger('fluent.tag');
31 * $fluentHandler = new Monolog\Handler\SocketHandler('unix:///var/run/td-agent/td-agent.sock');
32 * $fluentHandler->setFormatter(new Monolog\Formatter\FluentdFormatter());
33 * $logger->pushHandler($fluentHandler);
34 *
35 * @author Andrius Putna <fordnox@gmail.com>
36 */
37class FluentdFormatter implements FormatterInterface
38{
39    /**
40     * @var bool $levelTag should message level be a part of the fluentd tag
41     */
42    protected $levelTag = false;
43
44    public function __construct(bool $levelTag = false)
45    {
46        if (!function_exists('json_encode')) {
47            throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s FluentdUnixFormatter');
48        }
49
50        $this->levelTag = $levelTag;
51    }
52
53    public function isUsingLevelsInTag(): bool
54    {
55        return $this->levelTag;
56    }
57
58    public function format(array $record): string
59    {
60        $tag = $record['channel'];
61        if ($this->levelTag) {
62            $tag .= '.' . strtolower($record['level_name']);
63        }
64
65        $message = [
66            'message' => $record['message'],
67            'context' => $record['context'],
68            'extra' => $record['extra'],
69        ];
70
71        if (!$this->levelTag) {
72            $message['level'] = $record['level'];
73            $message['level_name'] = $record['level_name'];
74        }
75
76        return Utils::jsonEncode([$tag, $record['datetime']->getTimestamp(), $message]);
77    }
78
79    public function formatBatch(array $records): string
80    {
81        $message = '';
82        foreach ($records as $record) {
83            $message .= $this->format($record);
84        }
85
86        return $message;
87    }
88}
89