Skip to content

Commit abdf991

Browse files
authored
feat(agent): add config option to not instrument framework exception handlers (#1113)
Our instrumentation of framework exception handlers can result in excess, unwanted error events being generated. Sometimes, these events are plentiful and diverse enough that manual filtering through them with our other error related INI options is too much effort. In cases like that, this setting exists as an easy solution. Errors may still appear on spans, but error events will, in general, not be created. This works especially well when the customer inserts their own error handling logic into the stack, so that they are able to call our API for certain, specific errors that they wish to be error events.
1 parent 22d0138 commit abdf991

File tree

9 files changed

+83
-44
lines changed

9 files changed

+83
-44
lines changed

agent/fw_cakephp.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,12 @@ void nr_cakephp_enable(TSRMLS_D) {
173173
nr_php_wrap_user_function(
174174
NR_PSTR("Cake\\Controller\\Controller::invokeAction"),
175175
nr_cakephp_name_the_wt_4);
176-
nr_php_wrap_user_function(
177-
NR_PSTR(
178-
"Cake\\Error\\Middleware\\ErrorHandlerMiddleware::handleException"),
179-
nr_cakephp_error_handler_wrapper);
176+
if (!NRINI(ignore_framework_error_exception_handler)) {
177+
nr_php_wrap_user_function(
178+
NR_PSTR(
179+
"Cake\\Error\\Middleware\\ErrorHandlerMiddleware::handleException"),
180+
nr_cakephp_error_handler_wrapper);
181+
}
180182
nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
181183
PHP_PACKAGE_VERSION_UNKNOWN);
182184
}

agent/fw_drupal8.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -898,14 +898,16 @@ void nr_drupal8_enable(TSRMLS_D) {
898898
/*
899899
* Log exceptions without further handling.
900900
*/
901-
nr_php_wrap_user_function(NR_PSTR("Drupal\\Core\\EventSubscriber\\ExceptionLoggingSubscriber::onException"),
902-
nr_drupal_exception);
901+
if (!NRINI(ignore_framework_error_exception_handler)) {
902+
nr_php_wrap_user_function(NR_PSTR("Drupal\\Core\\EventSubscriber\\ExceptionLoggingSubscriber::onException"),
903+
nr_drupal_exception);
903904

904-
/*
905-
* Last-chance handler for exceptions: the final exception subscriber.
906-
*/
907-
nr_php_wrap_user_function(NR_PSTR("Drupal\\Core\\EventSubscriber\\FinalExceptionSubscriber::onException"),
908-
nr_drupal_exception);
905+
/*
906+
* Last-chance handler for exceptions: the final exception subscriber.
907+
*/
908+
nr_php_wrap_user_function(NR_PSTR("Drupal\\Core\\EventSubscriber\\FinalExceptionSubscriber::onException"),
909+
nr_drupal_exception);
910+
}
909911
// clang-format on
910912

911913
/*

agent/fw_laravel.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -865,19 +865,21 @@ NR_PHP_WRAPPER(nr_laravel5_application_boot) {
865865
* to sensibly name transactions when an exception is thrown during routing
866866
* and also to record the error.
867867
*/
868-
exception_handler = nr_php_call_offsetGet(
869-
this_var, "Illuminate\\Contracts\\Debug\\ExceptionHandler" TSRMLS_CC);
870-
if (nr_php_is_zval_valid_object(exception_handler)) {
871-
nr_laravel_add_callback_method(Z_OBJCE_P(exception_handler),
872-
NR_PSTR("render"),
873-
nr_laravel5_exception_render TSRMLS_CC);
874-
875-
nr_laravel_add_callback_method(Z_OBJCE_P(exception_handler),
876-
NR_PSTR("report"),
877-
nr_laravel5_exception_report TSRMLS_CC);
878-
} else {
879-
nrl_verbosedebug(NRL_FRAMEWORK, "%s: cannot get exception handler",
880-
__func__);
868+
if (!NRINI(ignore_framework_error_exception_handler)) {
869+
exception_handler = nr_php_call_offsetGet(
870+
this_var, "Illuminate\\Contracts\\Debug\\ExceptionHandler" TSRMLS_CC);
871+
if (nr_php_is_zval_valid_object(exception_handler)) {
872+
nr_laravel_add_callback_method(Z_OBJCE_P(exception_handler),
873+
NR_PSTR("render"),
874+
nr_laravel5_exception_render TSRMLS_CC);
875+
876+
nr_laravel_add_callback_method(Z_OBJCE_P(exception_handler),
877+
NR_PSTR("report"),
878+
nr_laravel5_exception_report TSRMLS_CC);
879+
} else {
880+
nrl_verbosedebug(NRL_FRAMEWORK, "%s: cannot get exception handler",
881+
__func__);
882+
}
881883
}
882884

883885
end:

agent/fw_lumen.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,16 +218,18 @@ void nr_lumen_enable(TSRMLS_D) {
218218
nr_php_wrap_user_function(
219219
NR_PSTR("Laravel\\Lumen\\Application::handleFoundRoute"),
220220
nr_lumen_handle_found_route TSRMLS_CC);
221+
if (!NRINI(ignore_framework_error_exception_handler)) {
221222
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
222223
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
223-
nr_php_wrap_user_function_before_after_clean(
224-
NR_PSTR("Laravel\\Lumen\\Application::sendExceptionToHandler"),
225-
nr_lumen_exception, NULL, NULL);
224+
nr_php_wrap_user_function_before_after_clean(
225+
NR_PSTR("Laravel\\Lumen\\Application::sendExceptionToHandler"),
226+
nr_lumen_exception, NULL, NULL);
226227
#else
227-
nr_php_wrap_user_function(
228-
NR_PSTR("Laravel\\Lumen\\Application::sendExceptionToHandler"),
229-
nr_lumen_exception TSRMLS_CC);
228+
nr_php_wrap_user_function(
229+
NR_PSTR("Laravel\\Lumen\\Application::sendExceptionToHandler"),
230+
nr_lumen_exception TSRMLS_CC);
230231
#endif
232+
}
231233

232234
if (NRINI(vulnerability_management_package_detection_enabled)) {
233235
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,

agent/fw_symfony4.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -250,19 +250,21 @@ void nr_symfony4_enable(TSRMLS_D) {
250250
* nr_txn_record_error and pass the exception message. Now we get errors in
251251
* the error analytics page.
252252
*/
253-
nr_php_wrap_user_function(
254-
NR_PSTR("Symfony\\Component\\HttpKernel\\"
255-
"EventListener\\ExceptionListener::onKernelException"),
256-
nr_symfony4_exception TSRMLS_CC);
253+
if (!NRINI(ignore_framework_error_exception_handler)) {
254+
nr_php_wrap_user_function(
255+
NR_PSTR("Symfony\\Component\\HttpKernel\\"
256+
"EventListener\\ExceptionListener::onKernelException"),
257+
nr_symfony4_exception TSRMLS_CC);
257258

258-
/*
259-
* In Symfony 5 listener that catch errors was changed to ErrorListener,
260-
* we try to hook into it
261-
*/
262-
nr_php_wrap_user_function(
263-
NR_PSTR("Symfony\\Component\\HttpKernel\\"
264-
"EventListener\\ErrorListener::onKernelException"),
265-
nr_symfony4_exception TSRMLS_CC);
259+
/*
260+
* In Symfony 5 listener that catch errors was changed to ErrorListener,
261+
* we try to hook into it
262+
*/
263+
nr_php_wrap_user_function(
264+
NR_PSTR("Symfony\\Component\\HttpKernel\\"
265+
"EventListener\\ErrorListener::onKernelException"),
266+
nr_symfony4_exception TSRMLS_CC);
267+
}
266268

267269
/*
268270
* Listen for Symfony commands so we can name those appropriately.

agent/fw_yii.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,10 @@ void nr_yii2_enable(TSRMLS_D) {
219219
* allowing default PHP error handler to be intercepted by the NewRelic agent
220220
* implementation.
221221
*/
222-
nr_php_wrap_user_function(NR_PSTR("yii\\base\\ErrorHandler::logException"),
223-
nr_yii2_error_handler_wrapper TSRMLS_CC);
222+
if (!NRINI(ignore_framework_error_exception_handler)) {
223+
nr_php_wrap_user_function(NR_PSTR("yii\\base\\ErrorHandler::logException"),
224+
nr_yii2_error_handler_wrapper TSRMLS_CC);
225+
}
224226
#endif
225227

226228
if (NRINI(vulnerability_management_package_detection_enabled)) {

agent/php_newrelic.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ nrinibool_t
238238
nrinibool_t
239239
ignore_user_exception_handler; /* newrelic.error_collector.ignore_user_exception_handler
240240
*/
241+
nrinibool_t
242+
ignore_framework_error_exception_handler; /* newrelic.error_collector.ignore_framework_error_excpetion_handler
243+
*/
241244
nriniint_t ignore_errors; /* newrelic.error_collector.ignore_errors */
242245
nrinistr_t ignore_exceptions; /* newrelic.error_collector.ignore_exceptions */
243246
nrinibool_t

agent/php_nrini.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,6 +2587,14 @@ STD_PHP_INI_ENTRY_EX("newrelic.error_collector.ignore_user_exception_handler",
25872587
zend_newrelic_globals,
25882588
newrelic_globals,
25892589
nr_yes_no_dh)
2590+
STD_PHP_INI_ENTRY_EX("newrelic.error_collector.ignore_framework_error_exception_handler",
2591+
"0",
2592+
NR_PHP_REQUEST,
2593+
nr_boolean_mh,
2594+
ignore_framework_error_exception_handler,
2595+
zend_newrelic_globals,
2596+
newrelic_globals,
2597+
nr_yes_no_dh)
25902598
STD_PHP_INI_ENTRY_EX("newrelic.error_collector.ignore_errors",
25912599
"",
25922600
NR_PHP_REQUEST,

agent/scripts/newrelic.ini.template

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,22 @@ newrelic.daemon.logfile = "/var/log/newrelic/newrelic-daemon.log"
432432
;
433433
;newrelic.error_collector.ignore_user_exception_handler = false
434434

435+
; Setting: newrelic.error_collector.ignore_framework_error_exception_handler
436+
; Type : boolean
437+
; Scope : per-directory
438+
; Default: false
439+
; Info : If enabled, the New Relic error collector will ignore any errors or
440+
; exceptions that are handled by a framework error or exception
441+
; handler.
442+
;
443+
; This is useful if you only want to see exceptions that are re-
444+
; thrown by the framework or if you are inserting your own
445+
; handling logic into the exception handling stack that will
446+
; filter errors/exceptions and manually call the New Relic API
447+
; when instrumentation is desired.
448+
;
449+
;newrelic.error_collector.ignore_framework_error_exception_handler = false
450+
435451
; Setting: newrelic.error_collector.ignore_exceptions
436452
; Type: string
437453
; Scope: per-directory

0 commit comments

Comments
 (0)