4 * This file is part of the Monolog package.
6 * (c) Jordi Boggiano <j.boggiano@seld.be>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Monolog\Handler;
15 use Monolog\Formatter\NormalizerFormatter;
18 * Class to record a log on a NewRelic application.
19 * Enabling New Relic High Security mode may prevent capture of useful information.
21 * @see https://docs.newrelic.com/docs/agents/php-agent
22 * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security
24 class NewRelicHandler extends AbstractProcessingHandler
27 * Name of the New Relic application that will receive logs from this handler.
34 * Name of the current transaction
38 protected $transactionName;
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?
46 protected $explodeArrays;
51 * @param string $appName
52 * @param bool $explodeArrays
53 * @param string $transactionName
55 public function __construct(
56 $level = Logger::ERROR,
59 $explodeArrays = false,
60 $transactionName = null
62 parent::__construct($level, $bubble);
64 $this->appName = $appName;
65 $this->explodeArrays = $explodeArrays;
66 $this->transactionName = $transactionName;
72 protected function write(array $record)
74 if (!$this->isNewRelicEnabled()) {
75 throw new MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler');
78 if ($appName = $this->getAppName($record['context'])) {
79 $this->setNewRelicAppName($appName);
82 if ($transactionName = $this->getTransactionName($record['context'])) {
83 $this->setNewRelicTransactionName($transactionName);
84 unset($record['formatted']['context']['transaction_name']);
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']);
91 newrelic_notice_error($record['message']);
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);
101 $this->setNewRelicParameter('context_' . $key, $parameter);
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);
113 $this->setNewRelicParameter('extra_' . $key, $parameter);
120 * Checks whether the NewRelic extension is enabled in the system.
124 protected function isNewRelicEnabled()
126 return extension_loaded('newrelic');
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.
133 * @param array $context
134 * @return null|string
136 protected function getAppName(array $context)
138 if (isset($context['appname'])) {
139 return $context['appname'];
142 return $this->appName;
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
149 * @param array $context
151 * @return null|string
153 protected function getTransactionName(array $context)
155 if (isset($context['transaction_name'])) {
156 return $context['transaction_name'];
159 return $this->transactionName;
163 * Sets the NewRelic application that should receive this log.
165 * @param string $appName
167 protected function setNewRelicAppName($appName)
169 newrelic_set_appname($appName);
173 * Overwrites the name of the current transaction
175 * @param string $transactionName
177 protected function setNewRelicTransactionName($transactionName)
179 newrelic_name_transaction($transactionName);
184 * @param mixed $value
186 protected function setNewRelicParameter($key, $value)
188 if (null === $value || is_scalar($value)) {
189 newrelic_add_custom_parameter($key, $value);
191 newrelic_add_custom_parameter($key, @json_encode($value));
198 protected function getDefaultFormatter()
200 return new NormalizerFormatter();