LogstashFormatter::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
c 0
b 0
f 0
nc 1
nop 5
dl 0
loc 10
rs 10
1
<?php
2
3
/*
4
 * This file is part of the Monolog package.
5
 *
6
 * (c) Jordi Boggiano <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Monolog\Formatter;
13
14
/**
15
 * Serializes a log message to Logstash Event Format
16
 *
17
 * @see http://logstash.net/
18
 * @see https://github.com/logstash/logstash/blob/master/lib/logstash/event.rb
19
 *
20
 * @author Tim Mower <[email protected]>
21
 */
22
class LogstashFormatter extends NormalizerFormatter
23
{
24
    const V0 = 0;
25
    const V1 = 1;
26
27
    /**
28
     * @var string the name of the system for the Logstash log message, used to fill the @source field
29
     */
30
    protected $systemName;
31
32
    /**
33
     * @var string an application name for the Logstash log message, used to fill the @type field
34
     */
35
    protected $applicationName;
36
37
    /**
38
     * @var string a prefix for 'extra' fields from the Monolog record (optional)
39
     */
40
    protected $extraPrefix;
41
42
    /**
43
     * @var string a prefix for 'context' fields from the Monolog record (optional)
44
     */
45
    protected $contextPrefix;
46
47
    /**
48
     * @var int logstash format version to use
49
     */
50
    protected $version;
51
52
    /**
53
     * @param string $applicationName the application that sends the data, used as the "type" field of logstash
54
     * @param string $systemName      the system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine
55
     * @param string $extraPrefix     prefix for extra keys inside logstash "fields"
56
     * @param string $contextPrefix   prefix for context keys inside logstash "fields", defaults to ctxt_
57
     * @param int    $version         the logstash format version to use, defaults to 0
58
     */
59
    public function __construct($applicationName, $systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_', $version = self::V0)
60
    {
61
        // logstash requires a ISO 8601 format date with optional millisecond precision.
62
        parent::__construct('Y-m-d\TH:i:s.uP');
63
64
        $this->systemName = $systemName ?: gethostname();
65
        $this->applicationName = $applicationName;
66
        $this->extraPrefix = $extraPrefix;
67
        $this->contextPrefix = $contextPrefix;
68
        $this->version = $version;
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74
    public function format(array $record)
75
    {
76
        $record = parent::format($record);
77
78
        if ($this->version === self::V1) {
79
            $message = $this->formatV1($record);
80
        } else {
81
            $message = $this->formatV0($record);
82
        }
83
84
        return $this->toJson($message) . "\n";
85
    }
86
87
    protected function formatV0(array $record)
88
    {
89
        if (empty($record['datetime'])) {
90
            $record['datetime'] = gmdate('c');
91
        }
92
        $message = array(
93
            '@timestamp' => $record['datetime'],
94
            '@source' => $this->systemName,
95
            '@fields' => array(),
96
        );
97
        if (isset($record['message'])) {
98
            $message['@message'] = $record['message'];
99
        }
100
        if (isset($record['channel'])) {
101
            $message['@tags'] = array($record['channel']);
102
            $message['@fields']['channel'] = $record['channel'];
103
        }
104
        if (isset($record['level'])) {
105
            $message['@fields']['level'] = $record['level'];
106
        }
107
        if ($this->applicationName) {
108
            $message['@type'] = $this->applicationName;
109
        }
110
        if (isset($record['extra']['server'])) {
111
            $message['@source_host'] = $record['extra']['server'];
112
        }
113
        if (isset($record['extra']['url'])) {
114
            $message['@source_path'] = $record['extra']['url'];
115
        }
116
        if (!empty($record['extra'])) {
117
            foreach ($record['extra'] as $key => $val) {
118
                $message['@fields'][$this->extraPrefix . $key] = $val;
119
            }
120
        }
121
        if (!empty($record['context'])) {
122
            foreach ($record['context'] as $key => $val) {
123
                $message['@fields'][$this->contextPrefix . $key] = $val;
124
            }
125
        }
126
127
        return $message;
128
    }
129
130
    protected function formatV1(array $record)
131
    {
132
        if (empty($record['datetime'])) {
133
            $record['datetime'] = gmdate('c');
134
        }
135
        $message = array(
136
            '@timestamp' => $record['datetime'],
137
            '@version' => 1,
138
            'host' => $this->systemName,
139
        );
140
        if (isset($record['message'])) {
141
            $message['message'] = $record['message'];
142
        }
143
        if (isset($record['channel'])) {
144
            $message['type'] = $record['channel'];
145
            $message['channel'] = $record['channel'];
146
        }
147
        if (isset($record['level_name'])) {
148
            $message['level'] = $record['level_name'];
149
        }
150
        if ($this->applicationName) {
151
            $message['type'] = $this->applicationName;
152
        }
153
        if (!empty($record['extra'])) {
154
            foreach ($record['extra'] as $key => $val) {
155
                $message[$this->extraPrefix . $key] = $val;
156
            }
157
        }
158
        if (!empty($record['context'])) {
159
            foreach ($record['context'] as $key => $val) {
160
                $message[$this->contextPrefix . $key] = $val;
161
            }
162
        }
163
164
        return $message;
165
    }
166
}
167