Skip to content

Commit

Permalink
Merge branch 'main' into move-release-from-lambda-to-gha
Browse files Browse the repository at this point in the history
  • Loading branch information
hmstepanek authored Jan 15, 2025
2 parents f49f3dd + 5b320e8 commit 6b87860
Show file tree
Hide file tree
Showing 183 changed files with 8,839 additions and 366 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/code-coverage-baseline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
matrix:
platform: [gnu, musl]
arch: [amd64]
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
include:
- codecov: 0
- platform: gnu
Expand Down Expand Up @@ -147,7 +147,7 @@ jobs:
matrix:
platform: [gnu, musl]
arch: [amd64]
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
include:
- codecov: 0
- platform: gnu
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners
# Consider using larger runners for possible analysis time improvements.
runs-on: 'ubuntu-latest'
runs-on: 'ubuntu-22.04'
timeout-minutes: 360
permissions:
# required for all workflows
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/make-agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
strategy:
matrix:
platform: [gnu, musl]
php: ['8.0', '8.1', '8.2', '8.3']
php: ['8.0', '8.1', '8.2', '8.3', '8.4']
steps:
- name: Checkout Repo
uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/make-integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
fail-fast: true
matrix:
platform: [gnu, musl]
php: ['8.0', '8.1', '8.2', '8.3']
php: ['8.0', '8.1', '8.2', '8.3', '8.4']
steps:
- name: Checkout integration tests
uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ jobs:
if: ${{ github.event_name == 'schedule' }}
uses: github/codeql-action/upload-sarif@v3
with:
checkout_path: ./php-agent
sarif_file: trivy-results.sarif
4 changes: 2 additions & 2 deletions .github/workflows/test-agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
matrix:
platform: [gnu, musl]
arch: [amd64, arm64]
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
exclude:
- arch: arm64
php: '7.2'
Expand Down Expand Up @@ -203,7 +203,7 @@ jobs:
matrix:
platform: [gnu, musl]
arch: [amd64, arm64]
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
exclude:
- arch: arm64
php: '7.2'
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
11.4.0
11.5.0
5 changes: 4 additions & 1 deletion agent/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,16 @@ if test "$PHP_NEWRELIC" = "yes"; then
lib_guzzle4.c lib_guzzle6.c lib_guzzle_common.c \
lib_mongodb.c lib_phpunit.c lib_predis.c lib_zend_http.c \
lib_composer.c"
PHP_NEW_EXTENSION(newrelic, $FRAMEWORKS $LIBRARIES $NEWRELIC_AGENT, $ext_shared,, \\$(NEWRELIC_CFLAGS))
PHP_NEW_EXTENSION(newrelic, $FRAMEWORKS $LIBRARIES $NEWRELIC_AGENT, $ext_shared,, $(NEWRELIC_CFLAGS))

PHP_SUBST(NEWRELIC_CFLAGS)

dnl Define $(PHP_CONFIG) so we can call it when building tests.
PHP_SUBST(PHP_CONFIG)

dnl Make sure we include the source directory in the include search path.
PHP_ADD_INCLUDE([$abs_srcdir], [1])

dnl Include the Makefile.frag, which we use to handle build time
dnl dependencies.
PHP_ADD_MAKEFILE_FRAGMENT
Expand Down
77 changes: 77 additions & 0 deletions agent/fw_drupal8.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "php_user_instrument.h"
#include "php_execute.h"
#include "php_wrapper.h"
#include "php_error.h"
#include "fw_drupal_common.h"
#include "fw_hooks.h"
#include "fw_support.h"
Expand All @@ -20,6 +21,62 @@

#define PHP_PACKAGE_NAME "drupal/core"

NR_PHP_WRAPPER(nr_drupal_exception) {
int priority = nr_php_error_get_priority(E_ERROR);
zval* event = NULL;
zval* exception = NULL;

/* Warning avoidance */
(void)wraprec;

NR_PHP_WRAPPER_REQUIRE_FRAMEWORK(NR_FW_DRUPAL8);

if (NR_SUCCESS != nr_txn_record_error_worthy(NRPRG(txn), priority)) {
NR_PHP_WRAPPER_CALL;
goto end;
}

/* Get the event that was given. */
event = nr_php_arg_get(1, NR_EXECUTE_ORIG_ARGS);

/* Call the original function. */
NR_PHP_WRAPPER_CALL;

if (0 == nr_php_is_zval_valid_object(event)) {
nrl_verbosedebug(NRL_TXN,
"Drupal: ExceptionSubscriber::onException() does not "
"have an `event` parameter");
goto end;
}

/*
* Get the exception from the event.
*/
exception = nr_php_call(event, "getThrowable");
if (!nr_php_is_zval_valid_object(exception)) {
// be abundantly cautious: free exception before attempting to re-assign
nr_php_zval_free(&exception);
exception = nr_php_call(event, "getException");
}

if (!nr_php_is_zval_valid_object(exception)) {
nrl_verbosedebug(NRL_TXN, "Drupal: getException() returned a non-object");
goto end;
}

if (NR_SUCCESS
!= nr_php_error_record_exception(NRPRG(txn), exception, priority, true,
NULL,
&NRPRG(exception_filters))) {
nrl_verbosedebug(NRL_TXN, "Drupal: unable to record exception");
}

end:
nr_php_arg_release(&event);
nr_php_zval_free(&exception);
}
NR_PHP_WRAPPER_END

/*
* Purpose : Convenience function to handle adding a callback to a method,
* given a class entry and a method name. This will check the
Expand Down Expand Up @@ -730,6 +787,26 @@ void nr_drupal8_enable(TSRMLS_D) {
"er::getControllerFromDefinition"),
nr_drupal8_name_the_wt TSRMLS_CC);

/*
* ExceptionSubscribers handle Drupal errors and exceptions before
* the agent has the opportunity to capture them. Instrument several
* of these ExceptionSubscriber function `onException` methods in order
* to capture Exceptions and Errors in Drupal 9.x+
*/
// clang-format off
/*
* Log exceptions without further handling.
*/
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);
// clang-format on

/*
* The drupal_modules config setting controls instrumentation of modules,
* hooks, and views.
Expand Down
100 changes: 43 additions & 57 deletions agent/lib_aws_sdk_php.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,49 +22,40 @@
* In a normal course of events, the following line will always work
* zend_eval_string("Aws\\Sdk::VERSION;", &retval, "Get AWS Version")
* By the time we have detected the existence of the aws-sdk-php and with
* default composer profject settings, it callable even from
* default composer project settings, it is callable even from
* nr_aws_sdk_php_enable which will automatically load the class if it isn't
* loaded yet and then evaluate the string. However, in the rare case that files
* loaded yet and then evaluate the string. In the rare case that files
* are not loaded via autoloader and/or have non-default composer classload
* settings, if the class is not found, PHP 8.2+ will generate a fatal
* unrecoverable uncatchable error error whenever it cannot find a class. While
* calling this from nr_aws_sdk_php_enable would have been great and would allow
* the sdk version value to be set only once, to avoid the very unlikely but not
* impossible fatal error, this will be called from the
* "Aws\\ClientResolver::_apply_user_agent" wrapper which GUARANTEES that
* aws/sdk exists and is already loaded.
*
*
* Additionally given that aws-sdk-php is currently detected from the
* AwsClient.php file, this method will always be called when a client is
* created unlike Sdk::construct which doesn't show with PHP 8.2+.
*
* Using Aws/Sdk::__construct for version is currently nonviable as it is
* unreliable as a version determiner.
* Having separate functionality to extract from Aws/Sdk::__construct
* is both not required and is redundant and causes additional overhead and
* so only one function is needed to extract version.
*
* Aws\\ClientResolver::_apply_user_agent a reliable function as it is
* always called on client initialization since it is key to populating
* the request headers, and it loads Sdk by default.
*
* Concerns about future/past proofing to the checking prioritized the following
* implementation vs using the eval method.
* settings, if the class is not found, PHP 8.2+ will generate an
* error whenever it cannot find a class which must be caught. Calling this
* from nr_aws_sdk_php_enable would allow the sdk version value to be set only
* once. To avoid the VERY unlikely but not impossible fatal error, we need to
* wrap the call in a try/catch block and make it a lambda so that we avoid
* fatal errors.
*/
void nr_lib_aws_sdk_php_handle_version() {
zval* zval_version = NULL;
zend_class_entry* class_entry = NULL;
char* version = NULL;

class_entry = nr_php_find_class("aws\\sdk");
if (NULL != class_entry) {
zval_version = nr_php_get_class_constant(class_entry, "VERSION");

if (nr_php_is_zval_non_empty_string(zval_version)) {
version = Z_STRVAL_P(zval_version);
zval retval;
int result = FAILURE;

result = zend_eval_string(
"(function() {"
" $nr_aws_sdk_version = '';"
" try {"
" $nr_aws_sdk_version = Aws\\Sdk::VERSION;"
" } catch (Throwable $e) {"
" }"
" return $nr_aws_sdk_version;"
"})();",
&retval, "Get nr_aws_sdk_version");

/* See if we got a non-empty/non-null string for version. */
if (SUCCESS == result) {
if (nr_php_is_zval_non_empty_string(&retval)) {
version = Z_STRVAL(retval);
}
}

if (NRINI(vulnerability_management_package_detection_enabled)) {
/* Add php package to transaction */
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME, version);
Expand All @@ -73,7 +64,7 @@ void nr_lib_aws_sdk_php_handle_version() {
nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME,
version);

nr_php_zval_free(&zval_version);
zval_dtor(&retval);
}

void nr_lib_aws_sdk_php_add_supportability_service_metric(
Expand All @@ -96,13 +87,6 @@ void nr_lib_aws_sdk_php_add_supportability_service_metric(
nrm_force_add(NRPRG(txn) ? NRTXN(unscoped_metrics) : 0, buf, 0);
}

NR_PHP_WRAPPER(nr_create_aws_sdk_version_metrics) {
(void)wraprec;
NR_PHP_WRAPPER_CALL;
nr_lib_aws_sdk_php_handle_version();
}
NR_PHP_WRAPPER_END

/*
* AwsClient::parseClass
* This is called from the base AwsClient class for every client associated
Expand Down Expand Up @@ -144,7 +128,7 @@ NR_PHP_WRAPPER_END
* optimizable library. Small overhead incurred when encountering an autoload
* file, but detects aws-sdk-php immediately before any sdk code executes
* (changes needed for this are detailed in the original PR)
* 2. use a file that gets called later and only when AwsClient.php file file is
* 2. use a file that gets called later and only when AwsClient.php file is
* called. It's called later and we'll miss some instrumentation, but if we're
* only ever going to be interested in Client calls anyway, maybe that's ok?
* Doesn't detect Sdk.php (optimized out) so when customers only use that or
Expand All @@ -158,22 +142,24 @@ NR_PHP_WRAPPER_END
* to wrap, this will add overhead to every hash map lookup. Currently
* implemented option is 2, use the AwsClient.php as this is our main focus.
* This means until a call to an Aws/AwsClient function,
* all calls including aws\sdk calls are ignored. Version detection will be
* tied to Aws/ClientResolver::_apply_user_agent which is ALWAYS called when
* dealing with aws clients. It will not be computed from
* Aws/Sdk::__constructor which would at best be duplicate info and worst would
* never be ignored until a client is called.
* all calls including aws\sdk calls are ignored.
*
* Version detection will be called directly from Aws\Sdk.php
*/
void nr_aws_sdk_php_enable() {
/* This will be used to extract the version. */
nr_php_wrap_user_function(NR_PSTR("Aws\\ClientResolver::_apply_user_agent"),
nr_create_aws_sdk_version_metrics);
/* Called when initializing all other Clients */
nr_php_wrap_user_function(NR_PSTR("Aws\\AwsClient::parseClass"),
nr_create_aws_service_metric);

/*
* Set the UNKNOWN package first, so it doesn't overwrite what we find with
* nr_lib_aws_sdk_php_handle_version.
*/
if (NRINI(vulnerability_management_package_detection_enabled)) {
nr_txn_add_php_package(NRPRG(txn), PHP_PACKAGE_NAME,
PHP_PACKAGE_VERSION_UNKNOWN);
}

/* Extract the version for aws-sdk 3+ */
nr_lib_aws_sdk_php_handle_version();

/* Called when initializing all Clients */
nr_php_wrap_user_function(NR_PSTR("Aws\\AwsClient::parseClass"),
nr_create_aws_service_metric);
}
15 changes: 12 additions & 3 deletions agent/newrelic-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,10 @@ for pmv in "20170718" "20180731" "20190902"; do
done
fi
# Currently supported versions:
# (8.0, 8.1, 8.2, 8.3)
# (8.0, 8.1, 8.2, 8.3, 8.4)
# for x64 and aarch64
if [ ${arch} = x64 ] || [ ${arch} = aarch64 ]; then
for pmv in "20200930" "20210902" "20220829" "20230831"; do
for pmv in "20200930" "20210902" "20220829" "20230831" "20240924"; do
check_file "${ilibdir}/agent/${arch}/newrelic-${pmv}.so"
done
fi
Expand Down Expand Up @@ -542,6 +542,7 @@ add_to_path /usr/local/php-8.0/bin
add_to_path /usr/local/php-8.1/bin
add_to_path /usr/local/php-8.2/bin
add_to_path /usr/local/php-8.3/bin
add_to_path /usr/local/php-8.4/bin

add_to_path /opt/local/bin
add_to_path /usr/php/bin
Expand All @@ -553,6 +554,7 @@ add_to_path /usr/php-8.0/bin
add_to_path /usr/php-8.1/bin
add_to_path /usr/php-8.2/bin
add_to_path /usr/php-8.3/bin
add_to_path /usr/php-8.4/bin

add_to_path /usr/php/7.2/bin
add_to_path /usr/php/7.3/bin
Expand All @@ -561,6 +563,7 @@ add_to_path /usr/php/8.0/bin
add_to_path /usr/php/8.1/bin
add_to_path /usr/php/8.2/bin
add_to_path /usr/php/8.3/bin
add_to_path /usr/php/8.4/bin

add_to_path /opt/php/bin
add_to_path /opt/zend/bin
Expand All @@ -572,6 +575,7 @@ add_to_path /opt/php-8.0/bin
add_to_path /opt/php-8.1/bin
add_to_path /opt/php-8.2/bin
add_to_path /opt/php-8.3/bin
add_to_path /opt/php-8.4/bin

if [ -n "${NR_INSTALL_PATH}" ]; then
oIFS="${IFS}"
Expand Down Expand Up @@ -1052,7 +1056,11 @@ for this copy of PHP. We apologize for the inconvenience.

8.3.*)
pi_php8="yes"
;;
;;

8.4.*)
pi_php8="yes"
;;

*)
error "unsupported version '${pi_ver}' of PHP found at:
Expand Down Expand Up @@ -1232,6 +1240,7 @@ does not exist. This particular instance of PHP will be skipped.
8.1.*) pi_modver="20210902" ;;
8.2.*) pi_modver="20220829" ;;
8.3.*) pi_modver="20230831" ;;
8.4.*) pi_modver="20240924" ;;
esac
log "${pdir}: pi_modver=${pi_modver}"

Expand Down
Loading

0 comments on commit 6b87860

Please sign in to comment.