Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
11.0.0
11.1.0
12 changes: 11 additions & 1 deletion agent/Makefile.frag
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,17 @@ $(PHP_MODULES): .libs/deps.mk
newrelic.la: $(PHP_AXIOM)/libaxiom.a

#
# The version number is needed by php_newrelic.c as a static string literal,
# The version number is needed by several source files as a static string literal,
# so it can be placed in the module entry.
#
include ../make/version.mk

php_newrelic.lo: CPPFLAGS += -DNR_VERSION="\"$(AGENT_VERSION)\""
php_newrelic.lo: ../VERSION

php_txn.lo: CPPFLAGS += -DNR_VERSION="\"$(AGENT_VERSION)\""
php_txn.lo: ../VERSION

#
# Unit tests!
#
Expand Down Expand Up @@ -261,6 +265,12 @@ ifeq (/opt/nr/lamp/lib,$(findstring /opt/nr/lamp/lib,$(PHP_EMBED_LIBRARY)))
endif
endif

#
# Need agent version for test_txn
#
tests/test_txn.o: EXTRA_CFLAGS += -DNR_VERSION="\"$(AGENT_VERSION)\""
tests/test_txn.o: ../VERSION

#
# Used when linking test binaries.
#
Expand Down
4 changes: 2 additions & 2 deletions agent/lib_aws_sdk_php.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ void nr_lib_aws_sdk_php_add_supportability_service_metric(
}

cp = buf;
strcpy(cp, PHP_AWS_SDK_SERVICE_NAME_METRIC_PREFIX);
nr_strcpy(cp, PHP_AWS_SDK_SERVICE_NAME_METRIC_PREFIX);
cp += PHP_AWS_SDK_SERVICE_NAME_METRIC_PREFIX_LEN - 1;
strlcpy(cp, service_name, MAX_AWS_SERVICE_NAME_LEN);
nr_strlcpy(cp, service_name, MAX_AWS_SERVICE_NAME_LEN);
nrm_force_add(NRPRG(txn) ? NRTXN(unscoped_metrics) : 0, buf, 0);
}

Expand Down
5 changes: 2 additions & 3 deletions agent/php_newrelic.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ ZEND_BEGIN_ARG_INFO_EX(newrelic_arginfo_void, 0, 0, 0)
ZEND_END_ARG_INFO()
#endif /* PHP 8.0+ */

ZEND_BEGIN_ARG_INFO_EX(newrelic_get_request_metadata_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, transport)
ZEND_BEGIN_ARG_INFO_EX(newrelic_get_request_metadata_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, transport)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(newrelic_add_custom_parameter_arginfo, 0, 0, 2)
Expand Down Expand Up @@ -223,7 +223,6 @@ ZEND_BEGIN_ARG_INFO_EX(newrelic_set_user_id_arginfo, 0, 0, 1)
ZEND_ARG_INFO(0, uuid)
ZEND_END_ARG_INFO()


ZEND_BEGIN_ARG_INFO_EX(newrelic_set_error_group_callback_arginfo, 0, 0, 1)
ZEND_ARG_INFO(0, callback)
ZEND_END_ARG_INFO()
Expand Down
45 changes: 45 additions & 0 deletions agent/php_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,48 @@ static void nr_php_txn_send_metrics_once(nrtxn_t* txn TSRMLS_DC) {
#undef FMT_BOOL
}

void nr_php_txn_create_agent_version_metric(nrtxn_t* txn) {
if (NULL == txn) {
return;
}

nrm_force_add(NRTXN(unscoped_metrics),
"Supportability/PHP/AgentVersion/" NR_VERSION, 0);
}

void nr_php_txn_create_php_version_metric(nrtxn_t* txn, const char* version) {
char* metric_name = NULL;

if (NULL == txn) {
return;
}

if (nr_strempty(version)) {
return;
}

metric_name = nr_formatf("Supportability/PHP/Version/%s", version);
nrm_force_add(NRTXN(unscoped_metrics), metric_name, 0);
nr_free(metric_name);
}

void nr_php_txn_create_agent_php_version_metrics(nrtxn_t* txn) {
char* version = NULL;

if (NULL == txn) {
return;
}
nr_php_txn_create_agent_version_metric(txn);

if (!nr_strempty(NR_PHP_PROCESS_GLOBALS(php_version))) {
version = NR_PHP_PROCESS_GLOBALS(php_version);
} else {
version = "unknown";
}

nr_php_txn_create_php_version_metric(txn, version);
}

nr_status_t nr_php_txn_begin(const char* appnames,
const char* license TSRMLS_DC) {
nrtxnopt_t opts;
Expand Down Expand Up @@ -1120,6 +1162,9 @@ nr_status_t nr_php_txn_end(int ignoretxn, int in_post_deactivate TSRMLS_DC) {
"Supportability/execute/allocated_segment_count",
nr_txn_allocated_segment_count(txn));

/* Agent and PHP version metrics*/
nr_php_txn_create_agent_php_version_metrics(txn);

/* Add CPU and memory metrics */
nr_php_resource_usage_sampler_end(TSRMLS_C);

Expand Down
29 changes: 29 additions & 0 deletions agent/php_txn_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,32 @@ nrobj_t* nr_php_txn_get_supported_security_policy_settings();
* Params : 1. The current transaction.
*/
extern void nr_php_txn_handle_fpm_error(nrtxn_t* txn TSRMLS_DC);

/*
* Purpose : Create and record metrics for the PHP and agent versions.
*
* Params : 1. The current transaction.
*
* Notes : This function relies on NR_VERSION and the value of
* NRPRG(php_version) to create the metrics.
*/
extern void nr_php_txn_create_agent_php_version_metrics(nrtxn_t* txn);

/*
* Purpose : Create and record metric for a specific agent version.
*
* Params : 1. The current transaction.
*
* Notes : This function relies on the value of the macro NR_VERSION
* to create.
*/
extern void nr_php_txn_create_agent_version_metric(nrtxn_t* txn);

/*
* Purpose : Create and record metric for a specific PHP version.
*
* Params : 1. The current transaction.
* 2. The PHP agent version.
*/
extern void nr_php_txn_create_php_version_metric(nrtxn_t* txn,
const char* version);
136 changes: 133 additions & 3 deletions agent/tests/test_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,133 @@ static void test_max_segments_config_values(TSRMLS_D) {
tlib_php_request_end();
}

#define PHP_VERSION_METRIC_BASE "Supportability/PHP/Version"
#define AGENT_VERSION_METRIC_BASE "Supportability/PHP/AgentVersion"

static void test_create_php_version_metric() {
nrtxn_t* txn;
int count;

tlib_php_request_start();
txn = NRPRG(txn);

count = nrm_table_size(txn->unscoped_metrics);

/* Test invalid values are properly handled */
nr_php_txn_create_php_version_metric(NULL, NULL);
tlib_pass_if_int_equal("PHP version metric shouldnt be created 1", count,
nrm_table_size(txn->unscoped_metrics));

nr_php_txn_create_php_version_metric(txn, NULL);
tlib_pass_if_int_equal("PHP version metric shouldnt be created 2", count,
nrm_table_size(txn->unscoped_metrics));

nr_php_txn_create_php_version_metric(NULL, "7.4.0");
tlib_pass_if_int_equal("PHP version metric shouldnt be created 3", count,
nrm_table_size(txn->unscoped_metrics));

nr_php_txn_create_php_version_metric(txn, "");
tlib_pass_if_int_equal("PHP version metric shouldnt be created 4", count,
nrm_table_size(txn->unscoped_metrics));

/* test valid values */
nr_php_txn_create_php_version_metric(txn, "7.4.0");
tlib_pass_if_int_equal("PHP version metric should be create", count + 1,
nrm_table_size(txn->unscoped_metrics));

const nrmetric_t* metric
= nrm_find(txn->unscoped_metrics, PHP_VERSION_METRIC_BASE "/7.4.0");
const char* metric_name = nrm_get_name(txn->unscoped_metrics, metric);

tlib_pass_if_not_null("PHP version metric found", metric);
tlib_pass_if_str_equal("PHP version metric name check", metric_name,
PHP_VERSION_METRIC_BASE "/7.4.0");

tlib_php_request_end();
}

static void test_create_agent_version_metric() {
nrtxn_t* txn;
int count;

tlib_php_request_start();
txn = NRPRG(txn);

count = nrm_table_size(txn->unscoped_metrics);

/* Test invalid values are properly handled */
nr_php_txn_create_agent_version_metric(NULL);
tlib_pass_if_int_equal("Agent version metric shouldnt be created - txn is NULL", count,
nrm_table_size(txn->unscoped_metrics));

/* Test valid values */
nr_php_txn_create_agent_version_metric(txn);
tlib_pass_if_int_equal("Agent version metric should be created - txn is not NULL", count + 1,
nrm_table_size(txn->unscoped_metrics));

const nrmetric_t* metric
= nrm_find(txn->unscoped_metrics, AGENT_VERSION_METRIC_BASE "/" NR_VERSION);
const char* metric_name = nrm_get_name(txn->unscoped_metrics, metric);

tlib_pass_if_not_null("Agent version metric found", metric);
tlib_pass_if_str_equal("Agent version metric name check", metric_name,
AGENT_VERSION_METRIC_BASE "/" NR_VERSION);

tlib_php_request_end();
}

static void test_create_agent_php_version_metrics() {
nrtxn_t* txn;

/*
* Test : Create agent PHP version metrics.
*/
tlib_php_request_start();
txn = NRPRG(txn);

zval* expected_php_zval = tlib_php_request_eval_expr("phpversion();");

char* php_version_name = nr_formatf(PHP_VERSION_METRIC_BASE "/%s",
Z_STRVAL_P(expected_php_zval));

nr_php_zval_free(&expected_php_zval);

char* agent_version_name
= nr_formatf(AGENT_VERSION_METRIC_BASE "/%s", NR_VERSION);

nr_php_txn_create_agent_php_version_metrics(txn);

/* Test the PHP version metric creation */
const nrmetric_t* metric = nrm_find(txn->unscoped_metrics, php_version_name);
const char* metric_name = nrm_get_name(txn->unscoped_metrics, metric);

tlib_pass_if_not_null("happy path: PHP version metric created", metric);
tlib_pass_if_not_null("happy path: PHP version metric name created",
metric_name);

tlib_pass_if_str_equal("happy path: PHP version metric name check",
metric_name, php_version_name);

/* Test the agent version metric creation*/
metric = nrm_find(txn->unscoped_metrics, agent_version_name);
metric_name = nrm_get_name(txn->unscoped_metrics, metric);

tlib_pass_if_not_null("happy path: Agent version metric created", metric);
tlib_pass_if_not_null("happy path: Agent version metric name created",
metric_name);

tlib_pass_if_str_equal("happy path: Agent version metric name check",
metric_name, agent_version_name);

nr_free(agent_version_name);
nr_free(php_version_name);

tlib_php_request_end();
}

#undef PHP_VERSION_METRIC_BASE
#undef AGENT_VERSION_METRIC_BASE

tlib_parallel_info_t parallel_info = {.suggested_nthreads = 1, .state_size = 0};

void test_main(void* p NRUNUSED) {
Expand All @@ -175,8 +302,11 @@ void test_main(void* p NRUNUSED) {
tlib_php_engine_create(
"newrelic.transaction_events.attributes.include=request.uri" PTSRMLS_CC);

test_handle_fpm_error(TSRMLS_C);
test_max_segments_config_values(TSRMLS_C);
test_handle_fpm_error();
test_max_segments_config_values();
test_create_php_version_metric();
test_create_agent_version_metric();
test_create_agent_php_version_metrics();

tlib_php_engine_destroy(TSRMLS_C);
tlib_php_engine_destroy();
}
2 changes: 1 addition & 1 deletion axiom/nr_distributed_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ void nr_distributed_trace_set_trace_id(nr_distributed_trace_t* dt,
for (int i = 0; i < padding; i++) {
dest[i] = '0';
}
strcpy(dest + padding, trace_id);
nr_strcpy(dest + padding, trace_id);
dt->trace_id = dest;
} else {
dt->trace_id = nr_strdup(trace_id);
Expand Down
3 changes: 2 additions & 1 deletion axiom/nr_version.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@
* wallflower 06May2024 (10.20)
* xerophyllum 20May2024 (10.21)
* yarrow 26Jun2024 (10.22)
* zinnia 30Jul2024 (11.0)
*/
#define NR_CODENAME "zinnia"
#define NR_CODENAME "amethyst"

const char* nr_version(void) {
return NR_STR2(NR_VERSION);
Expand Down
8 changes: 8 additions & 0 deletions daemon/cmd/integration_runner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,14 @@ func main() {
// Env vars common to all tests.
ctx.Env["EXTERNAL_HOST"] = externalHost

ctx.Env["PHP_VERSION"] = integration.GetPHPVersion()

agent_extension, ok := ctx.Settings["extension"]
if !ok {
agent_extension = "newrelic.so"
}
ctx.Env["AGENT_VERSION"] = integration.GetAgentVersion(agent_extension)

handler, err := startDaemon("unix", *flagPort, flagSecurityToken.String(), flagSecuityPolicies.String())
if err != nil {
fmt.Fprintln(os.Stderr, err)
Expand Down
9 changes: 8 additions & 1 deletion daemon/internal/newrelic/integration/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,12 @@ func (t *Test) compareMetricsExist(harvest *newrelic.Harvest) {
actualCount := int64(math.Round(actualData.([]interface{})[0].(float64)))

metricPasses := false
if (count == -1 && actualCount > 0) || (actualCount == count) {

// apdex metrics can have a count of 0 since the count field is
// actually the "satisfied" count, not a total count of metric
// as it is for other types of metrics
apdex_metric := strings.HasPrefix(expected, "Apdex/")
if (count == -1 && (apdex_metric || actualCount > 0)) || (actualCount == count) {
metricPasses = true
}

Expand Down Expand Up @@ -751,6 +756,8 @@ var (
regexp.MustCompile(`^Supportability\/InstrumentedFunction`),
regexp.MustCompile(`^Supportability\/TxnData\/.*`),
regexp.MustCompile(`^Supportability/C/NewrelicVersion/.*`),
regexp.MustCompile(`^Supportability/PHP/Version/.*`),
regexp.MustCompile(`^Supportability/PHP/AgentVersion/.*`),
}
)

Expand Down
33 changes: 33 additions & 0 deletions daemon/internal/newrelic/integration/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//

package integration

import (
"fmt"
"os/exec"
)

func GetPHPVersion() string {
cmd := exec.Command("php", "-r", "echo PHP_VERSION;")

output, err := cmd.Output()
if err != nil {
fmt.Printf("Failed to get PHP version: %v\n", err)
return "failed"
}

return string(output)
}

func GetAgentVersion(agent_extension string) string {
cmd := exec.Command("php", "-d", "extension="+agent_extension, "-r", "echo phpversion('newrelic');")

output, err := cmd.Output()
if err != nil {
return fmt.Errorf("Failed to get agent version: %v", err).Error()
}
return string(output)
}
Loading
Loading