Completed
Push — master ( cdeef2...f03c61 )
by Justin
03:14
created

NewRelicHandler::setNewRelicParameter()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 2
nop 2
dl 0
loc 6
rs 10
c 0
b 0
f 0
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\Handler;
13
14
use Monolog\Logger;
15
use Monolog\Formatter\NormalizerFormatter;
16
17
/**
18
 * Class to record a log on a NewRelic application.
19
 * Enabling New Relic High Security mode may prevent capture of useful information.
20
 *
21
 * @see https://docs.newrelic.com/docs/agents/php-agent
22
 * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security
23
 */
24
class NewRelicHandler extends AbstractProcessingHandler
25
{
26
    /**
27
     * Name of the New Relic application that will receive logs from this handler.
28
     *
29
     * @var string
30
     */
31
    protected $appName;
32
33
    /**
34
     * Name of the current transaction
35
     *
36
     * @var string
37
     */
38
    protected $transactionName;
39
40
    /**
41
     * Some context and extra data is passed into the handler as arrays of values. Do we send them as is
42
     * (useful if we are using the API), or explode them for display on the NewRelic RPM website?
43
     *
44
     * @var bool
45
     */
46
    protected $explodeArrays;
47
48
    /**
49
     * {@inheritDoc}
50
     *
51
     * @param string $appName
52
     * @param bool   $explodeArrays
53
     * @param string $transactionName
54
     */
55
    public function __construct(
56
        $level = Logger::ERROR,
57
        $bubble = true,
58
        $appName = null,
59
        $explodeArrays = false,
60
        $transactionName = null
61
    ) {
62
        parent::__construct($level, $bubble);
63
64
        $this->appName       = $appName;
65
        $this->explodeArrays = $explodeArrays;
66
        $this->transactionName = $transactionName;
67
    }
68
69
    /**
70
     * {@inheritDoc}
71
     */
72
    protected function write(array $record)
73
    {
74
        if (!$this->isNewRelicEnabled()) {
75
            throw new MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler');
76
        }
77
78
        if ($appName = $this->getAppName($record['context'])) {
79
            $this->setNewRelicAppName($appName);
80
        }
81
82
        if ($transactionName = $this->getTransactionName($record['context'])) {
83
            $this->setNewRelicTransactionName($transactionName);
84
            unset($record['formatted']['context']['transaction_name']);
85
        }
86
87
        if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Exception) {
88
            newrelic_notice_error($record['message'], $record['context']['exception']);
89
            unset($record['formatted']['context']['exception']);
90
        } else {
91
            newrelic_notice_error($record['message']);
92
        }
93
94
        if (isset($record['formatted']['context']) && is_array($record['formatted']['context'])) {
95
            foreach ($record['formatted']['context'] as $key => $parameter) {
96
                if (is_array($parameter) && $this->explodeArrays) {
97
                    foreach ($parameter as $paramKey => $paramValue) {
98
                        $this->setNewRelicParameter('context_' . $key . '_' . $paramKey, $paramValue);
99
                    }
100
                } else {
101
                    $this->setNewRelicParameter('context_' . $key, $parameter);
102
                }
103
            }
104
        }
105
106
        if (isset($record['formatted']['extra']) && is_array($record['formatted']['extra'])) {
107
            foreach ($record['formatted']['extra'] as $key => $parameter) {
108
                if (is_array($parameter) && $this->explodeArrays) {
109
                    foreach ($parameter as $paramKey => $paramValue) {
110
                        $this->setNewRelicParameter('extra_' . $key . '_' . $paramKey, $paramValue);
111
                    }
112
                } else {
113
                    $this->setNewRelicParameter('extra_' . $key, $parameter);
114
                }
115
            }
116
        }
117
    }
118
119
    /**
120
     * Checks whether the NewRelic extension is enabled in the system.
121
     *
122
     * @return bool
123
     */
124
    protected function isNewRelicEnabled()
125
    {
126
        return extension_loaded('newrelic');
127
    }
128
129
    /**
130
     * Returns the appname where this log should be sent. Each log can override the default appname, set in this
131
     * handler's constructor, by providing the appname in it's context.
132
     *
133
     * @param  array       $context
134
     * @return null|string
135
     */
136
    protected function getAppName(array $context)
137
    {
138
        if (isset($context['appname'])) {
139
            return $context['appname'];
140
        }
141
142
        return $this->appName;
143
    }
144
145
    /**
146
     * Returns the name of the current transaction. Each log can override the default transaction name, set in this
147
     * handler's constructor, by providing the transaction_name in it's context
148
     *
149
     * @param array $context
150
     *
151
     * @return null|string
152
     */
153
    protected function getTransactionName(array $context)
154
    {
155
        if (isset($context['transaction_name'])) {
156
            return $context['transaction_name'];
157
        }
158
159
        return $this->transactionName;
160
    }
161
162
    /**
163
     * Sets the NewRelic application that should receive this log.
164
     *
165
     * @param string $appName
166
     */
167
    protected function setNewRelicAppName($appName)
168
    {
169
        newrelic_set_appname($appName);
170
    }
171
172
    /**
173
     * Overwrites the name of the current transaction
174
     *
175
     * @param string $transactionName
176
     */
177
    protected function setNewRelicTransactionName($transactionName)
178
    {
179
        newrelic_name_transaction($transactionName);
180
    }
181
182
    /**
183
     * @param string $key
184
     * @param mixed  $value
185
     */
186
    protected function setNewRelicParameter($key, $value)
187
    {
188
        if (null === $value || is_scalar($value)) {
189
            newrelic_add_custom_parameter($key, $value);
190
        } else {
191
            newrelic_add_custom_parameter($key, @json_encode($value));
192
        }
193
    }
194
195
    /**
196
     * {@inheritDoc}
197
     */
198
    protected function getDefaultFormatter()
199
    {
200
        return new NormalizerFormatter();
201
    }
202
}
203