Skip to content

Commit 263681e

Browse files
authored
Merge pull request #951 from newrelic/dev
Release 11.1
2 parents ef7200a + 0ba870b commit 263681e

File tree

13 files changed

+302
-13
lines changed

13 files changed

+302
-13
lines changed

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
11.0.0
1+
11.1.0

agent/Makefile.frag

+11-1
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,17 @@ $(PHP_MODULES): .libs/deps.mk
4949
newrelic.la: $(PHP_AXIOM)/libaxiom.a
5050

5151
#
52-
# The version number is needed by php_newrelic.c as a static string literal,
52+
# The version number is needed by several source files as a static string literal,
5353
# so it can be placed in the module entry.
5454
#
5555
include ../make/version.mk
56+
5657
php_newrelic.lo: CPPFLAGS += -DNR_VERSION="\"$(AGENT_VERSION)\""
5758
php_newrelic.lo: ../VERSION
5859

60+
php_txn.lo: CPPFLAGS += -DNR_VERSION="\"$(AGENT_VERSION)\""
61+
php_txn.lo: ../VERSION
62+
5963
#
6064
# Unit tests!
6165
#
@@ -261,6 +265,12 @@ ifeq (/opt/nr/lamp/lib,$(findstring /opt/nr/lamp/lib,$(PHP_EMBED_LIBRARY)))
261265
endif
262266
endif
263267

268+
#
269+
# Need agent version for test_txn
270+
#
271+
tests/test_txn.o: EXTRA_CFLAGS += -DNR_VERSION="\"$(AGENT_VERSION)\""
272+
tests/test_txn.o: ../VERSION
273+
264274
#
265275
# Used when linking test binaries.
266276
#

agent/lib_aws_sdk_php.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ void nr_lib_aws_sdk_php_add_supportability_service_metric(
8888
}
8989

9090
cp = buf;
91-
strcpy(cp, PHP_AWS_SDK_SERVICE_NAME_METRIC_PREFIX);
91+
nr_strcpy(cp, PHP_AWS_SDK_SERVICE_NAME_METRIC_PREFIX);
9292
cp += PHP_AWS_SDK_SERVICE_NAME_METRIC_PREFIX_LEN - 1;
93-
strlcpy(cp, service_name, MAX_AWS_SERVICE_NAME_LEN);
93+
nr_strlcpy(cp, service_name, MAX_AWS_SERVICE_NAME_LEN);
9494
nrm_force_add(NRPRG(txn) ? NRTXN(unscoped_metrics) : 0, buf, 0);
9595
}
9696

agent/php_newrelic.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ ZEND_BEGIN_ARG_INFO_EX(newrelic_arginfo_void, 0, 0, 0)
120120
ZEND_END_ARG_INFO()
121121
#endif /* PHP 8.0+ */
122122

123-
ZEND_BEGIN_ARG_INFO_EX(newrelic_get_request_metadata_arginfo, 0, 0, 0)
124-
ZEND_ARG_INFO(0, transport)
123+
ZEND_BEGIN_ARG_INFO_EX(newrelic_get_request_metadata_arginfo, 0, 0, 0)
124+
ZEND_ARG_INFO(0, transport)
125125
ZEND_END_ARG_INFO()
126126

127127
ZEND_BEGIN_ARG_INFO_EX(newrelic_add_custom_parameter_arginfo, 0, 0, 2)
@@ -223,7 +223,6 @@ ZEND_BEGIN_ARG_INFO_EX(newrelic_set_user_id_arginfo, 0, 0, 1)
223223
ZEND_ARG_INFO(0, uuid)
224224
ZEND_END_ARG_INFO()
225225

226-
227226
ZEND_BEGIN_ARG_INFO_EX(newrelic_set_error_group_callback_arginfo, 0, 0, 1)
228227
ZEND_ARG_INFO(0, callback)
229228
ZEND_END_ARG_INFO()

agent/php_txn.c

+45
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,48 @@ static void nr_php_txn_send_metrics_once(nrtxn_t* txn TSRMLS_DC) {
669669
#undef FMT_BOOL
670670
}
671671

672+
void nr_php_txn_create_agent_version_metric(nrtxn_t* txn) {
673+
if (NULL == txn) {
674+
return;
675+
}
676+
677+
nrm_force_add(NRTXN(unscoped_metrics),
678+
"Supportability/PHP/AgentVersion/" NR_VERSION, 0);
679+
}
680+
681+
void nr_php_txn_create_php_version_metric(nrtxn_t* txn, const char* version) {
682+
char* metric_name = NULL;
683+
684+
if (NULL == txn) {
685+
return;
686+
}
687+
688+
if (nr_strempty(version)) {
689+
return;
690+
}
691+
692+
metric_name = nr_formatf("Supportability/PHP/Version/%s", version);
693+
nrm_force_add(NRTXN(unscoped_metrics), metric_name, 0);
694+
nr_free(metric_name);
695+
}
696+
697+
void nr_php_txn_create_agent_php_version_metrics(nrtxn_t* txn) {
698+
char* version = NULL;
699+
700+
if (NULL == txn) {
701+
return;
702+
}
703+
nr_php_txn_create_agent_version_metric(txn);
704+
705+
if (!nr_strempty(NR_PHP_PROCESS_GLOBALS(php_version))) {
706+
version = NR_PHP_PROCESS_GLOBALS(php_version);
707+
} else {
708+
version = "unknown";
709+
}
710+
711+
nr_php_txn_create_php_version_metric(txn, version);
712+
}
713+
672714
nr_status_t nr_php_txn_begin(const char* appnames,
673715
const char* license TSRMLS_DC) {
674716
nrtxnopt_t opts;
@@ -1120,6 +1162,9 @@ nr_status_t nr_php_txn_end(int ignoretxn, int in_post_deactivate TSRMLS_DC) {
11201162
"Supportability/execute/allocated_segment_count",
11211163
nr_txn_allocated_segment_count(txn));
11221164

1165+
/* Agent and PHP version metrics*/
1166+
nr_php_txn_create_agent_php_version_metrics(txn);
1167+
11231168
/* Add CPU and memory metrics */
11241169
nr_php_resource_usage_sampler_end(TSRMLS_C);
11251170

agent/php_txn_private.h

+29
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,32 @@ nrobj_t* nr_php_txn_get_supported_security_policy_settings();
3636
* Params : 1. The current transaction.
3737
*/
3838
extern void nr_php_txn_handle_fpm_error(nrtxn_t* txn TSRMLS_DC);
39+
40+
/*
41+
* Purpose : Create and record metrics for the PHP and agent versions.
42+
*
43+
* Params : 1. The current transaction.
44+
*
45+
* Notes : This function relies on NR_VERSION and the value of
46+
* NRPRG(php_version) to create the metrics.
47+
*/
48+
extern void nr_php_txn_create_agent_php_version_metrics(nrtxn_t* txn);
49+
50+
/*
51+
* Purpose : Create and record metric for a specific agent version.
52+
*
53+
* Params : 1. The current transaction.
54+
*
55+
* Notes : This function relies on the value of the macro NR_VERSION
56+
* to create.
57+
*/
58+
extern void nr_php_txn_create_agent_version_metric(nrtxn_t* txn);
59+
60+
/*
61+
* Purpose : Create and record metric for a specific PHP version.
62+
*
63+
* Params : 1. The current transaction.
64+
* 2. The PHP agent version.
65+
*/
66+
extern void nr_php_txn_create_php_version_metric(nrtxn_t* txn,
67+
const char* version);

agent/tests/test_txn.c

+133-3
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,133 @@ static void test_max_segments_config_values(TSRMLS_D) {
161161
tlib_php_request_end();
162162
}
163163

164+
#define PHP_VERSION_METRIC_BASE "Supportability/PHP/Version"
165+
#define AGENT_VERSION_METRIC_BASE "Supportability/PHP/AgentVersion"
166+
167+
static void test_create_php_version_metric() {
168+
nrtxn_t* txn;
169+
int count;
170+
171+
tlib_php_request_start();
172+
txn = NRPRG(txn);
173+
174+
count = nrm_table_size(txn->unscoped_metrics);
175+
176+
/* Test invalid values are properly handled */
177+
nr_php_txn_create_php_version_metric(NULL, NULL);
178+
tlib_pass_if_int_equal("PHP version metric shouldnt be created 1", count,
179+
nrm_table_size(txn->unscoped_metrics));
180+
181+
nr_php_txn_create_php_version_metric(txn, NULL);
182+
tlib_pass_if_int_equal("PHP version metric shouldnt be created 2", count,
183+
nrm_table_size(txn->unscoped_metrics));
184+
185+
nr_php_txn_create_php_version_metric(NULL, "7.4.0");
186+
tlib_pass_if_int_equal("PHP version metric shouldnt be created 3", count,
187+
nrm_table_size(txn->unscoped_metrics));
188+
189+
nr_php_txn_create_php_version_metric(txn, "");
190+
tlib_pass_if_int_equal("PHP version metric shouldnt be created 4", count,
191+
nrm_table_size(txn->unscoped_metrics));
192+
193+
/* test valid values */
194+
nr_php_txn_create_php_version_metric(txn, "7.4.0");
195+
tlib_pass_if_int_equal("PHP version metric should be create", count + 1,
196+
nrm_table_size(txn->unscoped_metrics));
197+
198+
const nrmetric_t* metric
199+
= nrm_find(txn->unscoped_metrics, PHP_VERSION_METRIC_BASE "/7.4.0");
200+
const char* metric_name = nrm_get_name(txn->unscoped_metrics, metric);
201+
202+
tlib_pass_if_not_null("PHP version metric found", metric);
203+
tlib_pass_if_str_equal("PHP version metric name check", metric_name,
204+
PHP_VERSION_METRIC_BASE "/7.4.0");
205+
206+
tlib_php_request_end();
207+
}
208+
209+
static void test_create_agent_version_metric() {
210+
nrtxn_t* txn;
211+
int count;
212+
213+
tlib_php_request_start();
214+
txn = NRPRG(txn);
215+
216+
count = nrm_table_size(txn->unscoped_metrics);
217+
218+
/* Test invalid values are properly handled */
219+
nr_php_txn_create_agent_version_metric(NULL);
220+
tlib_pass_if_int_equal("Agent version metric shouldnt be created - txn is NULL", count,
221+
nrm_table_size(txn->unscoped_metrics));
222+
223+
/* Test valid values */
224+
nr_php_txn_create_agent_version_metric(txn);
225+
tlib_pass_if_int_equal("Agent version metric should be created - txn is not NULL", count + 1,
226+
nrm_table_size(txn->unscoped_metrics));
227+
228+
const nrmetric_t* metric
229+
= nrm_find(txn->unscoped_metrics, AGENT_VERSION_METRIC_BASE "/" NR_VERSION);
230+
const char* metric_name = nrm_get_name(txn->unscoped_metrics, metric);
231+
232+
tlib_pass_if_not_null("Agent version metric found", metric);
233+
tlib_pass_if_str_equal("Agent version metric name check", metric_name,
234+
AGENT_VERSION_METRIC_BASE "/" NR_VERSION);
235+
236+
tlib_php_request_end();
237+
}
238+
239+
static void test_create_agent_php_version_metrics() {
240+
nrtxn_t* txn;
241+
242+
/*
243+
* Test : Create agent PHP version metrics.
244+
*/
245+
tlib_php_request_start();
246+
txn = NRPRG(txn);
247+
248+
zval* expected_php_zval = tlib_php_request_eval_expr("phpversion();");
249+
250+
char* php_version_name = nr_formatf(PHP_VERSION_METRIC_BASE "/%s",
251+
Z_STRVAL_P(expected_php_zval));
252+
253+
nr_php_zval_free(&expected_php_zval);
254+
255+
char* agent_version_name
256+
= nr_formatf(AGENT_VERSION_METRIC_BASE "/%s", NR_VERSION);
257+
258+
nr_php_txn_create_agent_php_version_metrics(txn);
259+
260+
/* Test the PHP version metric creation */
261+
const nrmetric_t* metric = nrm_find(txn->unscoped_metrics, php_version_name);
262+
const char* metric_name = nrm_get_name(txn->unscoped_metrics, metric);
263+
264+
tlib_pass_if_not_null("happy path: PHP version metric created", metric);
265+
tlib_pass_if_not_null("happy path: PHP version metric name created",
266+
metric_name);
267+
268+
tlib_pass_if_str_equal("happy path: PHP version metric name check",
269+
metric_name, php_version_name);
270+
271+
/* Test the agent version metric creation*/
272+
metric = nrm_find(txn->unscoped_metrics, agent_version_name);
273+
metric_name = nrm_get_name(txn->unscoped_metrics, metric);
274+
275+
tlib_pass_if_not_null("happy path: Agent version metric created", metric);
276+
tlib_pass_if_not_null("happy path: Agent version metric name created",
277+
metric_name);
278+
279+
tlib_pass_if_str_equal("happy path: Agent version metric name check",
280+
metric_name, agent_version_name);
281+
282+
nr_free(agent_version_name);
283+
nr_free(php_version_name);
284+
285+
tlib_php_request_end();
286+
}
287+
288+
#undef PHP_VERSION_METRIC_BASE
289+
#undef AGENT_VERSION_METRIC_BASE
290+
164291
tlib_parallel_info_t parallel_info = {.suggested_nthreads = 1, .state_size = 0};
165292

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

178-
test_handle_fpm_error(TSRMLS_C);
179-
test_max_segments_config_values(TSRMLS_C);
305+
test_handle_fpm_error();
306+
test_max_segments_config_values();
307+
test_create_php_version_metric();
308+
test_create_agent_version_metric();
309+
test_create_agent_php_version_metrics();
180310

181-
tlib_php_engine_destroy(TSRMLS_C);
311+
tlib_php_engine_destroy();
182312
}

axiom/nr_distributed_trace.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ void nr_distributed_trace_set_trace_id(nr_distributed_trace_t* dt,
497497
for (int i = 0; i < padding; i++) {
498498
dest[i] = '0';
499499
}
500-
strcpy(dest + padding, trace_id);
500+
nr_strcpy(dest + padding, trace_id);
501501
dt->trace_id = dest;
502502
} else {
503503
dt->trace_id = nr_strdup(trace_id);

axiom/nr_version.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@
4646
* wallflower 06May2024 (10.20)
4747
* xerophyllum 20May2024 (10.21)
4848
* yarrow 26Jun2024 (10.22)
49+
* zinnia 30Jul2024 (11.0)
4950
*/
50-
#define NR_CODENAME "zinnia"
51+
#define NR_CODENAME "amethyst"
5152

5253
const char* nr_version(void) {
5354
return NR_STR2(NR_VERSION);

daemon/cmd/integration_runner/main.go

+8
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,14 @@ func main() {
376376
// Env vars common to all tests.
377377
ctx.Env["EXTERNAL_HOST"] = externalHost
378378

379+
ctx.Env["PHP_VERSION"] = integration.GetPHPVersion()
380+
381+
agent_extension, ok := ctx.Settings["extension"]
382+
if !ok {
383+
agent_extension = "newrelic.so"
384+
}
385+
ctx.Env["AGENT_VERSION"] = integration.GetAgentVersion(agent_extension)
386+
379387
handler, err := startDaemon("unix", *flagPort, flagSecurityToken.String(), flagSecuityPolicies.String())
380388
if err != nil {
381389
fmt.Fprintln(os.Stderr, err)

daemon/internal/newrelic/integration/test.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,12 @@ func (t *Test) compareMetricsExist(harvest *newrelic.Harvest) {
544544
actualCount := int64(math.Round(actualData.([]interface{})[0].(float64)))
545545

546546
metricPasses := false
547-
if (count == -1 && actualCount > 0) || (actualCount == count) {
547+
548+
// apdex metrics can have a count of 0 since the count field is
549+
// actually the "satisfied" count, not a total count of metric
550+
// as it is for other types of metrics
551+
apdex_metric := strings.HasPrefix(expected, "Apdex/")
552+
if (count == -1 && (apdex_metric || actualCount > 0)) || (actualCount == count) {
548553
metricPasses = true
549554
}
550555

@@ -751,6 +756,8 @@ var (
751756
regexp.MustCompile(`^Supportability\/InstrumentedFunction`),
752757
regexp.MustCompile(`^Supportability\/TxnData\/.*`),
753758
regexp.MustCompile(`^Supportability/C/NewrelicVersion/.*`),
759+
regexp.MustCompile(`^Supportability/PHP/Version/.*`),
760+
regexp.MustCompile(`^Supportability/PHP/AgentVersion/.*`),
754761
}
755762
)
756763

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// Copyright 2020 New Relic Corporation. All rights reserved.
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
6+
package integration
7+
8+
import (
9+
"fmt"
10+
"os/exec"
11+
)
12+
13+
func GetPHPVersion() string {
14+
cmd := exec.Command("php", "-r", "echo PHP_VERSION;")
15+
16+
output, err := cmd.Output()
17+
if err != nil {
18+
fmt.Printf("Failed to get PHP version: %v\n", err)
19+
return "failed"
20+
}
21+
22+
return string(output)
23+
}
24+
25+
func GetAgentVersion(agent_extension string) string {
26+
cmd := exec.Command("php", "-d", "extension="+agent_extension, "-r", "echo phpversion('newrelic');")
27+
28+
output, err := cmd.Output()
29+
if err != nil {
30+
return fmt.Errorf("Failed to get agent version: %v", err).Error()
31+
}
32+
return string(output)
33+
}

0 commit comments

Comments
 (0)