diff --git a/agent/fw_cakephp.c b/agent/fw_cakephp.c index 572f6f23f..590f7c8f1 100644 --- a/agent/fw_cakephp.c +++ b/agent/fw_cakephp.c @@ -173,10 +173,12 @@ void nr_cakephp_enable(TSRMLS_D) { nr_php_wrap_user_function( NR_PSTR("Cake\\Controller\\Controller::invokeAction"), nr_cakephp_name_the_wt_4); - nr_php_wrap_user_function( - NR_PSTR( - "Cake\\Error\\Middleware\\ErrorHandlerMiddleware::handleException"), - nr_cakephp_error_handler_wrapper); + if (!NRINI(ignore_framework_error_exception_handler)) { + nr_php_wrap_user_function( + NR_PSTR( + "Cake\\Error\\Middleware\\ErrorHandlerMiddleware::handleException"), + nr_cakephp_error_handler_wrapper); + } nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME, PHP_PACKAGE_VERSION_UNKNOWN); } diff --git a/agent/fw_drupal8.c b/agent/fw_drupal8.c index 59c1c5bc8..a6af1c196 100644 --- a/agent/fw_drupal8.c +++ b/agent/fw_drupal8.c @@ -898,14 +898,16 @@ void nr_drupal8_enable(TSRMLS_D) { /* * Log exceptions without further handling. */ - nr_php_wrap_user_function(NR_PSTR("Drupal\\Core\\EventSubscriber\\ExceptionLoggingSubscriber::onException"), - nr_drupal_exception); + if (!NRINI(ignore_framework_error_exception_handler)) { + nr_php_wrap_user_function(NR_PSTR("Drupal\\Core\\EventSubscriber\\ExceptionLoggingSubscriber::onException"), + nr_drupal_exception); - /* - * Last-chance handler for exceptions: the final exception subscriber. - */ - nr_php_wrap_user_function(NR_PSTR("Drupal\\Core\\EventSubscriber\\FinalExceptionSubscriber::onException"), - nr_drupal_exception); + /* + * Last-chance handler for exceptions: the final exception subscriber. + */ + nr_php_wrap_user_function(NR_PSTR("Drupal\\Core\\EventSubscriber\\FinalExceptionSubscriber::onException"), + nr_drupal_exception); + } // clang-format on /* diff --git a/agent/fw_laravel.c b/agent/fw_laravel.c index dc409ec10..1a5fe1678 100644 --- a/agent/fw_laravel.c +++ b/agent/fw_laravel.c @@ -865,19 +865,21 @@ NR_PHP_WRAPPER(nr_laravel5_application_boot) { * to sensibly name transactions when an exception is thrown during routing * and also to record the error. */ - exception_handler = nr_php_call_offsetGet( - this_var, "Illuminate\\Contracts\\Debug\\ExceptionHandler" TSRMLS_CC); - if (nr_php_is_zval_valid_object(exception_handler)) { - nr_laravel_add_callback_method(Z_OBJCE_P(exception_handler), - NR_PSTR("render"), - nr_laravel5_exception_render TSRMLS_CC); - - nr_laravel_add_callback_method(Z_OBJCE_P(exception_handler), - NR_PSTR("report"), - nr_laravel5_exception_report TSRMLS_CC); - } else { - nrl_verbosedebug(NRL_FRAMEWORK, "%s: cannot get exception handler", - __func__); + if (!NRINI(ignore_framework_error_exception_handler)) { + exception_handler = nr_php_call_offsetGet( + this_var, "Illuminate\\Contracts\\Debug\\ExceptionHandler" TSRMLS_CC); + if (nr_php_is_zval_valid_object(exception_handler)) { + nr_laravel_add_callback_method(Z_OBJCE_P(exception_handler), + NR_PSTR("render"), + nr_laravel5_exception_render TSRMLS_CC); + + nr_laravel_add_callback_method(Z_OBJCE_P(exception_handler), + NR_PSTR("report"), + nr_laravel5_exception_report TSRMLS_CC); + } else { + nrl_verbosedebug(NRL_FRAMEWORK, "%s: cannot get exception handler", + __func__); + } } end: diff --git a/agent/fw_lumen.c b/agent/fw_lumen.c index 79f89ebc3..2cae28dbf 100644 --- a/agent/fw_lumen.c +++ b/agent/fw_lumen.c @@ -218,16 +218,18 @@ void nr_lumen_enable(TSRMLS_D) { nr_php_wrap_user_function( NR_PSTR("Laravel\\Lumen\\Application::handleFoundRoute"), nr_lumen_handle_found_route TSRMLS_CC); + if (!NRINI(ignore_framework_error_exception_handler)) { #if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \ && !defined OVERWRITE_ZEND_EXECUTE_DATA - nr_php_wrap_user_function_before_after_clean( - NR_PSTR("Laravel\\Lumen\\Application::sendExceptionToHandler"), - nr_lumen_exception, NULL, NULL); + nr_php_wrap_user_function_before_after_clean( + NR_PSTR("Laravel\\Lumen\\Application::sendExceptionToHandler"), + nr_lumen_exception, NULL, NULL); #else - nr_php_wrap_user_function( - NR_PSTR("Laravel\\Lumen\\Application::sendExceptionToHandler"), - nr_lumen_exception TSRMLS_CC); + nr_php_wrap_user_function( + NR_PSTR("Laravel\\Lumen\\Application::sendExceptionToHandler"), + nr_lumen_exception TSRMLS_CC); #endif + } if (NRINI(vulnerability_management_package_detection_enabled)) { nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, diff --git a/agent/fw_symfony4.c b/agent/fw_symfony4.c index 8592186ac..a9f3c06d8 100644 --- a/agent/fw_symfony4.c +++ b/agent/fw_symfony4.c @@ -250,19 +250,21 @@ void nr_symfony4_enable(TSRMLS_D) { * nr_txn_record_error and pass the exception message. Now we get errors in * the error analytics page. */ - nr_php_wrap_user_function( - NR_PSTR("Symfony\\Component\\HttpKernel\\" - "EventListener\\ExceptionListener::onKernelException"), - nr_symfony4_exception TSRMLS_CC); + if (!NRINI(ignore_framework_error_exception_handler)) { + nr_php_wrap_user_function( + NR_PSTR("Symfony\\Component\\HttpKernel\\" + "EventListener\\ExceptionListener::onKernelException"), + nr_symfony4_exception TSRMLS_CC); - /* - * In Symfony 5 listener that catch errors was changed to ErrorListener, - * we try to hook into it - */ - nr_php_wrap_user_function( - NR_PSTR("Symfony\\Component\\HttpKernel\\" - "EventListener\\ErrorListener::onKernelException"), - nr_symfony4_exception TSRMLS_CC); + /* + * In Symfony 5 listener that catch errors was changed to ErrorListener, + * we try to hook into it + */ + nr_php_wrap_user_function( + NR_PSTR("Symfony\\Component\\HttpKernel\\" + "EventListener\\ErrorListener::onKernelException"), + nr_symfony4_exception TSRMLS_CC); + } /* * Listen for Symfony commands so we can name those appropriately. diff --git a/agent/fw_yii.c b/agent/fw_yii.c index 0b1af7c96..a6eede3e8 100644 --- a/agent/fw_yii.c +++ b/agent/fw_yii.c @@ -219,8 +219,10 @@ void nr_yii2_enable(TSRMLS_D) { * allowing default PHP error handler to be intercepted by the NewRelic agent * implementation. */ - nr_php_wrap_user_function(NR_PSTR("yii\\base\\ErrorHandler::logException"), - nr_yii2_error_handler_wrapper TSRMLS_CC); + if (!NRINI(ignore_framework_error_exception_handler)) { + nr_php_wrap_user_function(NR_PSTR("yii\\base\\ErrorHandler::logException"), + nr_yii2_error_handler_wrapper TSRMLS_CC); + } #endif if (NRINI(vulnerability_management_package_detection_enabled)) { diff --git a/agent/php_newrelic.h b/agent/php_newrelic.h index 9683bad28..9a61ba723 100644 --- a/agent/php_newrelic.h +++ b/agent/php_newrelic.h @@ -238,6 +238,9 @@ nrinibool_t nrinibool_t ignore_user_exception_handler; /* newrelic.error_collector.ignore_user_exception_handler */ +nrinibool_t + ignore_framework_error_exception_handler; /* newrelic.error_collector.ignore_framework_error_excpetion_handler + */ nriniint_t ignore_errors; /* newrelic.error_collector.ignore_errors */ nrinistr_t ignore_exceptions; /* newrelic.error_collector.ignore_exceptions */ nrinibool_t diff --git a/agent/php_nrini.c b/agent/php_nrini.c index 37da5a820..70e4dc4bc 100644 --- a/agent/php_nrini.c +++ b/agent/php_nrini.c @@ -2587,6 +2587,14 @@ STD_PHP_INI_ENTRY_EX("newrelic.error_collector.ignore_user_exception_handler", zend_newrelic_globals, newrelic_globals, nr_yes_no_dh) +STD_PHP_INI_ENTRY_EX("newrelic.error_collector.ignore_framework_error_exception_handler", + "0", + NR_PHP_REQUEST, + nr_boolean_mh, + ignore_framework_error_exception_handler, + zend_newrelic_globals, + newrelic_globals, + nr_yes_no_dh) STD_PHP_INI_ENTRY_EX("newrelic.error_collector.ignore_errors", "", NR_PHP_REQUEST, diff --git a/agent/scripts/newrelic.ini.template b/agent/scripts/newrelic.ini.template index 4c199f00b..1b10c621e 100644 --- a/agent/scripts/newrelic.ini.template +++ b/agent/scripts/newrelic.ini.template @@ -432,6 +432,22 @@ newrelic.daemon.logfile = "/var/log/newrelic/newrelic-daemon.log" ; ;newrelic.error_collector.ignore_user_exception_handler = false +; Setting: newrelic.error_collector.ignore_framework_error_exception_handler +; Type : boolean +; Scope : per-directory +; Default: false +; Info : If enabled, the New Relic error collector will ignore any errors or +; exceptions that are handled by a framework error or exception +; handler. +; +; This is useful if you only want to see exceptions that are re- +; thrown by the framework or if you are inserting your own +; handling logic into the exception handling stack that will +; filter errors/exceptions and manually call the New Relic API +; when instrumentation is desired. +; +;newrelic.error_collector.ignore_framework_error_exception_handler = false + ; Setting: newrelic.error_collector.ignore_exceptions ; Type: string ; Scope: per-directory