Skip to content

Commit

Permalink
feat: instrument wordpress plugins' callbacks on demand (#799)
Browse files Browse the repository at this point in the history
Improve agent's performance by adding two new toggles around WordPress
instrumentation:
- `newrelic.framework.wordpress.plugins` - indicates if WordPress hooks
callback functions, implemented in WordPress core, plugins and themes,
are to be instrumented.
- `newrelic.framework.wordpress.hooks_threshold` - sets the WordPress
hook's execution duration threshold above which the hook execution will
be captured; used when WordPress hooks callback functions are not
instrumented.

By default, WordPress hooks callback functions are not instrumented and
`newrelic.framework.wordpress.hooks_threshold` is set at 1ms. This
allows to identify which hooks take up most time during request
processing. If more details are needed, i.e. which plugins are the
slowest, `newrelic.framework.wordpress.plugins` need to be set to
`true`.
  • Loading branch information
lavarou authored Jan 10, 2024
1 parent d2f21e9 commit 7a115f4
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 5 deletions.
32 changes: 27 additions & 5 deletions agent/fw_wordpress.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,21 @@ static void free_wordpress_metadata(void* metadata) {
nr_free(metadata);
}

static inline void nr_wordpress_hooks_create_metric(nr_segment_t* segment,
const char* hook_name) {
if (NULL == segment) {
return;
}
// need to capture 'now' because segment has not finished yet and therefore
// can't use segment->stop_time
nrtime_t now = nr_txn_now_rel(segment->txn);
nrtime_t duration = nr_time_duration(segment->start_time, now);
if (duration >= NRINI(wordpress_hooks_threshold)) {
// only create metrics for hooks above threshold
nr_wordpress_create_metric(segment, NR_WORDPRESS_HOOK_PREFIX, hook_name);
}
}

static char* nr_wordpress_plugin_from_function(zend_function* func TSRMLS_DC) {
const char* filename = NULL;
size_t filename_len;
Expand Down Expand Up @@ -452,6 +467,9 @@ NR_PHP_WRAPPER(nr_wordpress_exec_handle_tag) {

NRPRG(wordpress_tag) = nr_wordpress_clean_tag(tag);
NR_PHP_WRAPPER_CALL;
if (0 == NRINI(wordpress_plugins)) {
nr_wordpress_hooks_create_metric(auto_segment, NRPRG(wordpress_tag));
}
NRPRG(wordpress_tag) = old_tag;
if (NULL == NRPRG(wordpress_tag)) {
NRPRG(check_cufa) = false;
Expand Down Expand Up @@ -541,6 +559,9 @@ NR_PHP_WRAPPER(nr_wordpress_apply_filters) {
NRPRG(wordpress_tag) = nr_wordpress_clean_tag(tag);

NR_PHP_WRAPPER_CALL;
if (0 == NRINI(wordpress_plugins)) {
nr_wordpress_hooks_create_metric(auto_segment, NRPRG(wordpress_tag));
}
NRPRG(wordpress_tag) = old_tag;
if (NULL == NRPRG(wordpress_tag)) {
NRPRG(check_cufa) = false;
Expand Down Expand Up @@ -644,14 +665,15 @@ void nr_wordpress_enable(TSRMLS_D) {

nr_php_wrap_user_function(NR_PSTR("do_action_ref_array"),
nr_wordpress_exec_handle_tag TSRMLS_CC);

if (0 != NRINI(wordpress_plugins)) {
#if ZEND_MODULE_API_NO < ZEND_7_4_X_API_NO
nr_php_add_call_user_func_array_pre_callback(
nr_wordpress_call_user_func_array TSRMLS_CC);
nr_php_add_call_user_func_array_pre_callback(
nr_wordpress_call_user_func_array TSRMLS_CC);
#else
nr_php_wrap_user_function(NR_PSTR("add_filter"),
nr_wordpress_add_filter);
nr_php_wrap_user_function(NR_PSTR("add_filter"),
nr_wordpress_add_filter);
#endif
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions agent/php_newrelic.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ nrinistr_t browser_monitoring_loader; /* newrelic.browser_monitoring.loader */

nrinibool_t drupal_modules; /* newrelic.framework.drupal.modules */
nrinibool_t wordpress_hooks; /* newrelic.framework.wordpress.hooks */
nrinitime_t wordpress_hooks_threshold; /* newrelic.framework.wordpress.hooks_threshold */
nrinibool_t wordpress_plugins; /* newrelic.framework.wordpress.plugins */
nrinistr_t
wordpress_hooks_skip_filename; /* newrelic.framework.wordpress.hooks_skip_filename
*/
Expand Down
16 changes: 16 additions & 0 deletions agent/php_nrini.c
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,22 @@ STD_PHP_INI_ENTRY_EX("newrelic.framework.wordpress.hooks",
zend_newrelic_globals,
newrelic_globals,
nr_on_off_dh)
STD_PHP_INI_ENTRY_EX("newrelic.framework.wordpress.hooks_threshold",
"1ms",
NR_PHP_REQUEST,
nr_time_mh,
wordpress_hooks_threshold,
zend_newrelic_globals,
newrelic_globals,
0)
STD_PHP_INI_ENTRY_EX("newrelic.framework.wordpress.plugins",
"0",
NR_PHP_REQUEST,
nr_boolean_mh,
wordpress_plugins,
zend_newrelic_globals,
newrelic_globals,
nr_on_off_dh)
STD_PHP_INI_ENTRY_EX("newrelic.framework.wordpress.hooks_skip_filename",
"",
NR_PHP_REQUEST,
Expand Down
17 changes: 17 additions & 0 deletions agent/scripts/newrelic.ini.template
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,23 @@ newrelic.daemon.logfile = "/var/log/newrelic/newrelic-daemon.log"
;
;newrelic.framework.wordpress.hooks = true

; Setting: newrelic.framework.wordpress.hooks_threshold
; Type : time specification string ("500ms", "1s750ms" etc)
; Scope : per-directory
; Default: 1ms
; Info : Sets the threshold above which the New Relic agent will record a
; wordpress hooks.
;
;newrelic.framework.wordpress.hooks_threshold = 1ms

; Setting: newrelic.framework.wordpress.plugins
; Type : boolean
; Scope : per-directory
; Default: false
; Info : Indicates if WordPress plugins are to be instrumented.
;
;newrelic.framework.wordpress.plugins = false

; Setting: newrelic.application_logging.enabled
; Type : boolean
; Scope : per-directory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

/*INI
newrelic.framework = wordpress
newrelic.framework.wordpress.hooks_threshold = 0
*/

/*EXPECT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

/*INI
newrelic.framework = wordpress
newrelic.framework.wordpress.hooks_threshold = 0
*/

/*EXPECT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
/*INI
newrelic.framework = wordpress
newrelic.framework.wordpress.hooks = true
newrelic.framework.wordpress.hooks_threshold = 0
*/

/*ENVIRONMENT
Expand Down

0 comments on commit 7a115f4

Please sign in to comment.