Skip to content

Commit 5b964b4

Browse files
authored
feat(agent): Add supportability metrics for packages that provide major version (#868)
This PR creates a new supportability metric that will provide information on what major version of the package is being used. The packages that provide the major version and will send up this supportability metric are: - Drupal - Guzzle - Laravel - Monolog - Predis - Slim - Wordpress.
1 parent 539dd4f commit 5b964b4

File tree

115 files changed

+295
-26
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+295
-26
lines changed

agent/fw_drupal8.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "util_memory.h"
1919
#include "util_strings.h"
2020

21+
#define PHP_PACKAGE_NAME "drupal/core"
22+
2123
/*
2224
* Purpose : Convenience function to handle adding a callback to a method,
2325
* given a class entry and a method name. This will check the
@@ -684,7 +686,11 @@ void nr_drupal_version() {
684686
// Add php package to transaction
685687
if (nr_php_is_zval_valid_string(zval_version)) {
686688
char* version = Z_STRVAL_P(zval_version);
687-
nr_txn_add_php_package(NRPRG(txn), "drupal/core", version);
689+
if (NRINI(vulnerability_management_package_detection_enabled)) {
690+
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
691+
}
692+
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
693+
version);
688694
}
689695

690696
nr_php_zval_free(&zval_version);
@@ -753,7 +759,7 @@ void nr_drupal8_enable(TSRMLS_D) {
753759
}
754760

755761
if (NRINI(vulnerability_management_package_detection_enabled)) {
756-
nr_txn_add_php_package(NRPRG(txn), "drupal/core",
762+
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
757763
PHP_PACKAGE_VERSION_UNKNOWN);
758764
}
759765
}

agent/fw_laravel.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include "ext/standard/php_versioning.h"
2525
#include "Zend/zend_exceptions.h"
2626

27+
#define PHP_PACKAGE_NAME "laravel/framework"
28+
2729
/*
2830
* This instruments Laravel 4.0-5.0, inclusive.
2931
* There is no support for Laravel 3.X or earlier.
@@ -959,8 +961,10 @@ NR_PHP_WRAPPER(nr_laravel_application_construct) {
959961

960962
if (NRINI(vulnerability_management_package_detection_enabled)) {
961963
// Add php package to transaction
962-
nr_txn_add_php_package(NRPRG(txn), "laravel/framework", version);
964+
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
963965
}
966+
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
967+
version);
964968

965969
if (version) {
966970
nrl_debug(NRL_FRAMEWORK, "Laravel version is " NRP_FMT, NRP_PHP(version));

agent/fw_slim.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "fw_support.h"
1313
#include "util_logging.h"
1414

15+
#define PHP_PACKAGE_NAME "slim/slim"
16+
1517
static char* nr_slim_path_from_route(zval* route TSRMLS_DC) {
1618
zval* name = NULL;
1719
zval* pattern = NULL;
@@ -119,8 +121,13 @@ NR_PHP_WRAPPER(nr_slim_application_construct) {
119121

120122
version = nr_php_get_object_constant(this_var, "VERSION");
121123

122-
// Add php package to transaction
123-
nr_txn_add_php_package(NRPRG(txn), "slim/slim", version);
124+
if (NRINI(vulnerability_management_package_detection_enabled)) {
125+
// Add php package to transaction
126+
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
127+
}
128+
129+
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
130+
version);
124131

125132
nr_free(version);
126133
nr_php_scope_release(&this_var);
@@ -139,13 +146,11 @@ void nr_slim_enable(TSRMLS_D) {
139146
nr_php_wrap_user_function(NR_PSTR("Slim\\Routing\\Route::run"),
140147
nr_slim3_4_route_run TSRMLS_CC);
141148

142-
if (NRINI(vulnerability_management_package_detection_enabled)) {
143-
/* Slim 2 does not have the same path as Slim 3/4 which is why
144-
we need to separate these*/
145-
nr_php_wrap_user_function(NR_PSTR("Slim\\Slim::__construct"),
146-
nr_slim_application_construct);
149+
/* Slim 2 does not have the same path as Slim 3/4 which is why
150+
we need to separate these*/
151+
nr_php_wrap_user_function(NR_PSTR("Slim\\Slim::__construct"),
152+
nr_slim_application_construct);
147153

148-
nr_php_wrap_user_function(NR_PSTR("Slim\\App::__construct"),
149-
nr_slim_application_construct);
150-
}
154+
nr_php_wrap_user_function(NR_PSTR("Slim\\App::__construct"),
155+
nr_slim_application_construct);
151156
}

agent/fw_support.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include "util_memory.h"
1212
#include "util_strings.h"
1313

14+
#define MAJOR_VERSION_LENGTH 8
15+
1416
void nr_php_framework_add_supportability_metric(const char* framework_name,
1517
const char* name TSRMLS_DC) {
1618
char buf[512];
@@ -52,3 +54,36 @@ void nr_fw_support_add_logging_supportability_metric(nrtxn_t* txn,
5254
nrm_force_add(txn->unscoped_metrics, metname, 0);
5355
nr_free(metname);
5456
}
57+
58+
void nr_fw_support_add_package_supportability_metric(
59+
nrtxn_t* txn,
60+
const char* package_name,
61+
const char* package_version) {
62+
if (NULL == txn || NULL == package_name || NULL == package_version) {
63+
return;
64+
}
65+
66+
char* metname = NULL;
67+
char major_version[MAJOR_VERSION_LENGTH] = {0};
68+
69+
/* The below for loop checks if the major version of the package is more than
70+
* one digit and keeps looping until a '.' is encountered or one of the
71+
* conditions is met.
72+
*/
73+
for (int i = 0; package_version[i] && i < MAJOR_VERSION_LENGTH - 1; i++) {
74+
if ('.' == package_version[i]) {
75+
break;
76+
}
77+
major_version[i] = package_version[i];
78+
}
79+
80+
if (NR_FW_UNSET == NRINI(force_framework)) {
81+
metname = nr_formatf("Supportability/PHP/package/%s/%s/detected",
82+
package_name, major_version);
83+
} else {
84+
metname = nr_formatf("Supportability/PHP/package/%s/%s/forced",
85+
package_name, major_version);
86+
}
87+
nrm_force_add(txn->unscoped_metrics, metname, 0);
88+
nr_free(metname);
89+
}

agent/fw_support.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,17 @@ extern void nr_fw_support_add_logging_supportability_metric(
3838
const char* library_name,
3939
const bool is_enabled);
4040

41+
/*
42+
* Purpose: Add 'Supportability/PHP/package/{package}/{version}/detected' metric
43+
*
44+
* Params : 1. Transaction object
45+
* 2. Package name
46+
* 3. Package version
47+
*
48+
*/
49+
extern void nr_fw_support_add_package_supportability_metric(
50+
nrtxn_t* txn,
51+
const char* package_name,
52+
const char* package_version);
53+
4154
#endif /* FW_SUPPORT_HDR */

agent/fw_wordpress.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#define NR_WORDPRESS_HOOK_PREFIX "Framework/WordPress/Hook/"
2323
#define NR_WORDPRESS_PLUGIN_PREFIX "Framework/WordPress/Plugin/"
24+
#define PHP_PACKAGE_NAME "wordpress"
2425

2526
static nr_regex_t* wordpress_hook_regex;
2627

@@ -809,7 +810,11 @@ void nr_wordpress_version() {
809810
if (SUCCESS == result) {
810811
if (nr_php_is_zval_valid_string(&retval)) {
811812
char* version = Z_STRVAL(retval);
812-
nr_txn_add_php_package(NRPRG(txn), "wordpress", version);
813+
if (NRINI(vulnerability_management_package_detection_enabled)) {
814+
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
815+
}
816+
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
817+
version);
813818
}
814819
zval_dtor(&retval);
815820
}
@@ -865,7 +870,7 @@ void nr_wordpress_enable(TSRMLS_D) {
865870
#endif /* OAPI */
866871

867872
if (NRINI(vulnerability_management_package_detection_enabled)) {
868-
nr_txn_add_php_package(NRPRG(txn), "wordpress",
873+
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
869874
PHP_PACKAGE_VERSION_UNKNOWN);
870875
}
871876
}

agent/lib_guzzle6.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858

5959
#include "ext/standard/php_var.h"
6060

61+
#define PHP_PACKAGE_NAME "guzzlehttp/guzzle"
62+
6163
/*
6264
* Since Guzzle 6 requires PHP 5.5.0 or later, we just won't build the Guzzle 6
6365
* support on older versions and will instead provide simple stubs for the two
@@ -350,12 +352,18 @@ NR_PHP_WRAPPER_START(nr_guzzle6_client_construct) {
350352
zval* retval;
351353
zval* this_var = nr_php_scope_get(NR_EXECUTE_ORIG_ARGS);
352354

355+
char* version = nr_php_get_object_constant(this_var, "VERSION");
356+
if (NULL == version) {
357+
version = nr_php_get_object_constant(this_var, "MAJOR_VERSION");
358+
}
359+
353360
if (NRINI(vulnerability_management_package_detection_enabled)) {
354-
char* version = nr_php_get_object_constant(this_var, "VERSION");
355361
// Add php package to transaction
356-
nr_txn_add_php_package(NRPRG(txn), "guzzlehttp/guzzle", version);
357-
nr_free(version);
362+
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
358363
}
364+
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
365+
version);
366+
nr_free(version);
359367

360368
(void)wraprec;
361369
NR_UNUSED_SPECIALFN;

agent/lib_monolog.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
#define LOG_DECORATE_PROC_FUNC_NAME \
3131
"newrelic_phpagent_monolog_decorating_processor"
3232

33+
#define PHP_PACKAGE_NAME "monolog/monolog"
34+
#define MAJOR_VERSION_LENGTH 8
35+
3336
/*
3437
* Purpose : Convert Monolog\Logger::API to integer
3538
*
@@ -373,6 +376,10 @@ NR_PHP_WRAPPER(nr_monolog_logger_addrecord) {
373376
api = nr_monolog_version(this_var TSRMLS_CC);
374377
timestamp
375378
= nr_monolog_get_timestamp(api, argc, NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
379+
char version[MAJOR_VERSION_LENGTH];
380+
snprintf(version, sizeof(version), "%d", api);
381+
nr_fw_support_add_package_supportability_metric(NRPRG(txn),
382+
PHP_PACKAGE_NAME, version);
376383
}
377384

378385
/* Record the log event */
@@ -513,7 +520,7 @@ void nr_monolog_enable(TSRMLS_D) {
513520
nr_monolog_logger_addrecord TSRMLS_CC);
514521

515522
if (NRINI(vulnerability_management_package_detection_enabled)) {
516-
nr_txn_add_php_package(NRPRG(txn), "monolog/monolog",
523+
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
517524
PHP_PACKAGE_VERSION_UNKNOWN);
518525
}
519526
}

agent/lib_predis.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "util_strings.h"
2020
#include "lib_predis_private.h"
2121

22+
#define PHP_PACKAGE_NAME "predis/predis"
23+
2224
/*
2325
* Predis instrumentation
2426
* ======================
@@ -646,12 +648,15 @@ NR_PHP_WRAPPER(nr_predis_client_construct) {
646648
(void)wraprec;
647649

648650
NR_PHP_WRAPPER_CALL;
651+
652+
char* version = nr_php_get_object_constant(scope, "VERSION");
649653
if (NRINI(vulnerability_management_package_detection_enabled)) {
650-
char* version = nr_php_get_object_constant(scope, "VERSION");
651654
// Add php package to transaction
652-
nr_txn_add_php_package(NRPRG(txn), "predis/predis", version);
653-
nr_free(version);
655+
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
654656
}
657+
nr_fw_support_add_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
658+
version);
659+
nr_free(version);
655660

656661
/*
657662
* Grab the connection object from the client, since we actually instrument

agent/php_agent.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -727,10 +727,15 @@ char* nr_php_get_object_constant(zval* app, const char* name) {
727727

728728
if (nr_php_is_zval_valid_string(version)) {
729729
retval = nr_strndup(Z_STRVAL_P(version), Z_STRLEN_P(version));
730+
} else if (nr_php_is_zval_valid_integer(version)) {
731+
zend_string* zstr = zend_long_to_str(Z_LVAL_P(version));
732+
retval = nr_strndup(ZSTR_VAL(zstr), ZSTR_LEN(zstr));
733+
zend_string_release(zstr);
730734
} else {
731-
nrl_verbosedebug(NRL_FRAMEWORK,
732-
"%s: expected VERSION be a valid string, got type %d",
733-
__func__, Z_TYPE_P(version));
735+
nrl_verbosedebug(
736+
NRL_FRAMEWORK,
737+
"%s: expected VERSION to be a valid string or int, got type %d",
738+
__func__, Z_TYPE_P(version));
734739
}
735740

736741
nr_php_zval_free(&version);

0 commit comments

Comments
 (0)