Skip to content
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
52bc284
feat(agent): Add nr_message_segment.o to Makefile
zsistla Oct 23, 2024
11d5f20
feat(agent): Add message segment to enums, unions, structs
zsistla Oct 24, 2024
a4effd7
fix(agent): typo
zsistla Oct 24, 2024
8924003
feat(agent): Destroy Message Segment metadata
zsistla Oct 24, 2024
5402097
feat(agent): Add message typed attributes to a hash in the buffer
zsistla Oct 24, 2024
21217c3
feat(agent): add message parameters ini (#981)
ZNeumann Oct 30, 2024
1dda889
feat(agent): Add entity relationship building attributes to message s…
zsistla Nov 26, 2024
bb671d0
Merge branch 'feat/message_segment' of github.com:newrelic/newrelic-p…
zsistla Nov 26, 2024
d47ff53
feat(agent): Add message attribute functionality for message spans
zsistla Dec 2, 2024
149064c
feat(agent): Add nr_span_event_set_spankind
zsistla Dec 3, 2024
870830e
feat(agent): Add span handling for message segments
zsistla Dec 3, 2024
76b66b0
feat(agent): Add new ini value to opts so axiom can see it
zsistla Dec 5, 2024
8d9d949
feat(axiom): Add nr_segment_message functionality
zsistla Dec 6, 2024
9f7e561
feat(axiom): Added message getters to span_event
zsistla Dec 9, 2024
95077b1
feat(axiom): Add span message related span get/set functionality
zsistla Dec 9, 2024
5554ee2
feat(axiom): Add message segment tests
zsistla Dec 9, 2024
d22cbc9
feat(axiom): Add tests to ensure message segment destroy clean up pro…
zsistla Dec 9, 2024
88abff8
feat(axiom): Handle message segment metric rollups
zsistla Dec 9, 2024
3e78de6
feat(axiom): tests for rollup metrics for message segment
zsistla Dec 9, 2024
7802981
feat(axiom): Stronger handling of NULL/empty str for message attributes
zsistla Dec 10, 2024
a12ddeb
feat(axiom): message segment rollup metrics
zsistla Dec 10, 2024
882689a
feat(axiom): add message rollup metric to test case
zsistla Dec 10, 2024
3e448d0
feat(axiom): Add unit tests for nr_segment_message
zsistla Dec 10, 2024
2dd2a33
feat(agent): Add nr_message_segment.o to Makefile
zsistla Oct 23, 2024
3e89fcf
feat(agent): Add message segment to enums, unions, structs
zsistla Oct 24, 2024
a7ada88
fix(agent): typo
zsistla Oct 24, 2024
fef9fb2
feat(agent): Destroy Message Segment metadata
zsistla Oct 24, 2024
ede290e
feat(agent): Add message typed attributes to a hash in the buffer
zsistla Oct 24, 2024
4d02091
feat(agent): add message parameters ini (#981)
ZNeumann Oct 30, 2024
470d63d
feat(agent): Add entity relationship building attributes to message s…
zsistla Nov 26, 2024
5555b57
feat(agent): Add message attribute functionality for message spans
zsistla Dec 2, 2024
2c92b63
feat(agent): Add nr_span_event_set_spankind
zsistla Dec 3, 2024
33f7ef2
feat(agent): Add span handling for message segments
zsistla Dec 3, 2024
7305105
feat(agent): Add new ini value to opts so axiom can see it
zsistla Dec 5, 2024
b296507
feat(axiom): Add nr_segment_message functionality
zsistla Dec 6, 2024
d511086
feat(axiom): Added message getters to span_event
zsistla Dec 9, 2024
fc43234
feat(axiom): Add span message related span get/set functionality
zsistla Dec 9, 2024
d8522f7
feat(axiom): Add message segment tests
zsistla Dec 9, 2024
9ab2928
feat(axiom): Add tests to ensure message segment destroy clean up pro…
zsistla Dec 9, 2024
6932595
feat(axiom): Handle message segment metric rollups
zsistla Dec 9, 2024
9168e47
feat(axiom): tests for rollup metrics for message segment
zsistla Dec 9, 2024
ba40124
feat(axiom): Stronger handling of NULL/empty str for message attributes
zsistla Dec 10, 2024
d0b2a55
feat(axiom): message segment rollup metrics
zsistla Dec 10, 2024
4fc9bce
feat(axiom): add message rollup metric to test case
zsistla Dec 10, 2024
c8d2db1
feat(axiom): Add unit tests for nr_segment_message
zsistla Dec 10, 2024
53aefce
Merge branch 'feat/message_segment' of github.com:newrelic/newrelic-p…
zsistla Dec 10, 2024
a0a61a2
feat(axiom): Update integration test for externalCallCount
zsistla Dec 10, 2024
1135d39
fix(test): NOT a string...
zsistla Dec 10, 2024
b7ffa6c
chore(axiom): Comment update
zsistla Dec 13, 2024
9f66375
Merge branch 'dev' into feat/message_segment
zsistla Dec 20, 2024
6b7eaf0
Merge branch 'dev' into feat/message_segment
zsistla Dec 20, 2024
d7c4d79
fix(axiom): Correct the attribute bucket.
zsistla Dec 24, 2024
1ffa5d7
feat(axiom): Add aws_operation to message segment attributes.
zsistla Dec 24, 2024
c972a35
fix(axiom): Fixes
zsistla Dec 24, 2024
11480f4
fix(axiom): copypaste error
zsistla Dec 25, 2024
a91b708
refactor(axiom): decoupled cloud attributes from message segment
zsistla Dec 30, 2024
2568161
revert(axiom): externalCallCount fix in lieu of another PR
zsistla Jan 8, 2025
fd2a67f
Revert "revert(axiom): externalCallCount fix in lieu of another PR"
zsistla Jan 8, 2025
e709661
Update axiom/nr_segment_message.c
zsistla Jan 8, 2025
fde6d51
chore(axiom): Update comment
zsistla Jan 8, 2025
12af96f
chore(axiom): Fixed comment to account for wraparound formatting issue
zsistla Jan 8, 2025
6aec35d
refactor(axiom): move strempty check to nr_segment_set_message
zsistla Jan 8, 2025
97218d6
fix(axiom): Clarify comment about NULL assumptions
zsistla Jan 9, 2025
862604b
fix(axiom): PR responses
zsistla Jan 9, 2025
925b94c
fix(axiom): comment update
zsistla Jan 9, 2025
cf172d3
Merge branch 'dev' into feat/message_segment
zsistla Jan 9, 2025
4f91a63
chore(axiom): Comment update
zsistla Jan 10, 2025
0670292
test(axiom): Ensure typed_attributes is NULL after destruction
zsistla Jan 10, 2025
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
6 changes: 6 additions & 0 deletions agent/php_newrelic.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,12 @@ nrinibool_t
nrinibool_t
vulnerability_management_composer_api_enabled; /* newrelic.vulnerability_management.composer_api.enabled */

/*
* Configuration options for recording Messaging APIs
*/
nrinibool_t
message_tracer_segment_parameters_enabled; /* newrelic.segment_tracer.segment_parameters.enabled */

#if ZEND_MODULE_API_NO < ZEND_7_4_X_API_NO
/*
* pid and user_function_wrappers are used to store user function wrappers.
Expand Down
11 changes: 11 additions & 0 deletions agent/php_nrini.c
Original file line number Diff line number Diff line change
Expand Up @@ -3100,6 +3100,17 @@ STD_PHP_INI_ENTRY_EX("newrelic.vulnerability_management.composer_api.enabled",
newrelic_globals,
nr_enabled_disabled_dh)

/*
* Messaging API
*/
STD_PHP_INI_ENTRY_EX("newrelic.message_tracer.segment_parameters.enabled",
"1",
NR_PHP_REQUEST,
nr_boolean_mh,
message_tracer_segment_parameters_enabled,
zend_newrelic_globals,
newrelic_globals,
nr_enabled_disabled_dh)
PHP_INI_END() /* } */

void nr_php_register_ini_entries(int module_number TSRMLS_DC) {
Expand Down
4 changes: 3 additions & 1 deletion agent/php_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,8 @@ nr_status_t nr_php_txn_begin(const char* appnames,
opts.log_forwarding_log_level = NRINI(log_forwarding_log_level);
opts.log_events_max_samples_stored = NRINI(log_events_max_samples_stored);
opts.log_metrics_enabled = NRINI(log_metrics_enabled);
opts.message_tracer_segment_parameters_enabled
= NRINI(message_tracer_segment_parameters_enabled);

/*
* Enable the behaviour whereby asynchronous time is discounted from the total
Expand Down Expand Up @@ -1165,7 +1167,7 @@ nr_status_t nr_php_txn_end(int ignoretxn, int in_post_deactivate TSRMLS_DC) {
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
nr_segment_t* segment = nr_txn_get_current_segment(NRPRG(txn), NULL);
while(NULL != segment && segment != NRTXN(segment_root)) {
while (NULL != segment && segment != NRTXN(segment_root)) {
nr_segment_end(&segment);
segment = nr_txn_get_current_segment(NRPRG(txn), NULL);
}
Expand Down
11 changes: 11 additions & 0 deletions agent/scripts/newrelic.ini.template
Original file line number Diff line number Diff line change
Expand Up @@ -1341,3 +1341,14 @@ newrelic.daemon.logfile = "/var/log/newrelic/newrelic-daemon.log"
; to gather package information for vulnerability management.
;
;newrelic.vulnerability_management.composer_api.enabled = false

; Setting: newrelic.message_tracer.segment_parameters.enabled
; Type : boolean
; Scope : per-directory
; Default: true
; Info : If this setting is true, then message parameters will be captured and
; stored on their respective segments. While enabled, specific attributes
; can be filtered by using newrelic.attributes.include/exclude and
; newrelic.span_events.attributes.include/exclude
;
;newrelic.message_tracer.segment_parameters.enabled = true
2 changes: 1 addition & 1 deletion axiom/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
# Useful variables:
#
# AR: The archiver used to build a static library (default: ar).
# CC: The C compiler to use (default: gcc).
# CFLAGS: Flags to give the C compiler when building object files.
#

Expand Down Expand Up @@ -113,6 +112,7 @@ OBJS := \
nr_segment_children.o \
nr_segment_datastore.o \
nr_segment_external.o \
nr_segment_message.o \
nr_segment_private.o \
nr_segment_terms.o \
nr_segment_traces.o \
Expand Down
52 changes: 50 additions & 2 deletions axiom/nr_segment.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,26 @@ static void nr_populate_http_spans(nr_span_event_t* span_event,
segment->typed_attributes->external.status);
}

static void nr_populate_message_spans(nr_span_event_t* span_event,
const nr_segment_t* segment) {
nr_span_event_set_category(span_event, NR_SPAN_MESSAGE);

if (nrunlikely(NULL == segment || NULL == segment->typed_attributes)) {
return;
}

nr_span_event_set_spankind(span_event,
segment->typed_attributes->message.message_action);
nr_span_event_set_message(
span_event, NR_SPAN_MESSAGE_DESTINATION_NAME,
segment->typed_attributes->message.destination_name);
nr_span_event_set_message(
span_event, NR_SPAN_MESSAGE_MESSAGING_SYSTEM,
segment->typed_attributes->message.messaging_system);
nr_span_event_set_message(span_event, NR_SPAN_MESSAGE_SERVER_ADDRESS,
segment->typed_attributes->message.server_address);
}

static nr_status_t add_user_attribute_to_span_event(const char* key,
const nrobj_t* val,
void* ptr) {
Expand Down Expand Up @@ -431,8 +451,8 @@ nr_span_event_t* nr_segment_to_span_event(nr_segment_t* segment) {
nr_span_event_set_trusted_parent_id(
event, nr_distributed_trace_inbound_get_trusted_parent_id(
segment->txn->distributed_trace));
nr_span_event_set_parent_id(event,
nr_distributed_trace_inbound_get_guid(segment->txn->distributed_trace));
nr_span_event_set_parent_id(event, nr_distributed_trace_inbound_get_guid(
segment->txn->distributed_trace));

nr_span_event_set_transaction_name(event, segment->txn->name);

Expand Down Expand Up @@ -482,6 +502,10 @@ nr_span_event_t* nr_segment_to_span_event(nr_segment_t* segment) {
nr_populate_http_spans(event, segment);
break;

case NR_SEGMENT_MESSAGE:
nr_populate_message_spans(event, segment);
break;

case NR_SEGMENT_CUSTOM:
nr_span_event_set_category(event, NR_SPAN_GENERIC);
break;
Expand Down Expand Up @@ -599,6 +623,30 @@ bool nr_segment_set_external(nr_segment_t* segment,
return true;
}

bool nr_segment_set_message(nr_segment_t* segment,
const nr_segment_message_t* message) {
if (nrunlikely((NULL == segment) || (NULL == message))) {
return false;
}

nr_segment_destroy_typed_attributes(segment->type,
&segment->typed_attributes);
segment->type = NR_SEGMENT_MESSAGE;
segment->typed_attributes = nr_zalloc(sizeof(nr_segment_typed_attributes_t));

// clang-format off
// Initialize the fields of the message attributes, one field per line.
segment->typed_attributes->message = (nr_segment_message_t){
.message_action = message->message_action,
.destination_name = nr_strempty(message->destination_name) ? NULL: nr_strdup(message->destination_name),
.messaging_system = nr_strempty(message->messaging_system) ? NULL: nr_strdup(message->messaging_system),
.server_address = nr_strempty(message->server_address) ? NULL: nr_strdup(message->server_address),
};
// clang-format on

return true;
}

bool nr_segment_add_child(nr_segment_t* parent, nr_segment_t* child) {
if (nrunlikely((NULL == parent) || (NULL == child))) {
return false;
Expand Down
61 changes: 58 additions & 3 deletions axiom/nr_segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ typedef struct _nrtxn_t nrtxn_t;
typedef enum _nr_segment_type_t {
NR_SEGMENT_CUSTOM,
NR_SEGMENT_DATASTORE,
NR_SEGMENT_EXTERNAL
NR_SEGMENT_EXTERNAL,
NR_SEGMENT_MESSAGE
} nr_segment_type_t;

/*
Expand Down Expand Up @@ -109,6 +110,48 @@ typedef struct _nr_segment_external_t {
uint64_t status;
} nr_segment_external_t;

typedef struct _nr_segment_message_t {
/*
* Attributes needed for entity relationship building.
* Compare to OTEL attributes:
* https://opentelemetry.io/docs/specs/semconv/attributes-registry/cloud/
* cloud.account.id, cloud.region, messaging.system and server.address are
* used to create relationships between APM and cloud services. It may not
* make sense to add these attributes unless they are used for creating one of
* the relationships in Entity Relationships.
*/

nr_span_spankind_t
message_action; /*The action of the message, e.g.,Produce/Consume.*/
char* destination_name; /*The name of the Queue, Topic, or Exchange;
otherwise, Temp. Needed for SQS relationship.*/
char* messaging_system; /* for ex: aws_sqs. Needed for SQS relationship.*/
char* server_address; /*The server domain name or IP address. Needed for
MQBROKER relationship.*/
} nr_segment_message_t;

typedef struct _nr_segment_cloud_attrs_t {
/*
* Attributes needed for entity relationship building.
* Compare to OTEL attributes:
* https://opentelemetry.io/docs/specs/semconv/attributes-registry/cloud/
* cloud.account.id, cloud.region, messaging.system and server.address are
* used to create relationships between APM and cloud services. It may not
* make sense to add these attributes unless they are used for creating one of
* the relationships in Entity Relationships.
* These attributes aren't specific to a segment category so don't belong as
* typed attributes and can be added whenever they are available.
*/
char* cloud_region; /*Targeted region; ex:us-east-1*. Needed for SQS
relationship.*/
char* cloud_account_id; /*The cloud provider account ID. Needed for SQS
relationship.*/
char* cloud_resource_id; /*Unique cloud provider identifier. For AWS, this is
the ARN of the AWS resource being accessed.*/
char* aws_operation; /*AWS specific operation name.*/

} nr_segment_cloud_attrs_t;

typedef struct _nr_segment_metric_t {
char* name;
bool scoped;
Expand All @@ -132,6 +175,7 @@ typedef struct _nr_segment_error_t {
typedef union {
nr_segment_datastore_t datastore;
nr_segment_external_t external;
nr_segment_message_t message;
} nr_segment_typed_attributes_t;

typedef struct _nr_segment_t {
Expand Down Expand Up @@ -179,8 +223,8 @@ typedef struct _nr_segment_t {
int priority; /* Used to determine which segments are preferred for span event
creation */
nr_segment_typed_attributes_t* typed_attributes; /* Attributes specific to
external or datastore
segments. */
external, datastore,
or message segments. */
nr_segment_error_t* error; /* segment error attributes */
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
&& !defined OVERWRITE_ZEND_EXECUTE_DATA /* PHP 8.0+ and OAPI */
Expand Down Expand Up @@ -314,6 +358,17 @@ extern bool nr_segment_set_datastore(nr_segment_t* segment,
*/
extern bool nr_segment_set_external(nr_segment_t* segment,
const nr_segment_external_t* external);

/*
* Purpose : Mark the segment as being a message segment.
*
* Params : 1. The pointer to the segment.
* 2. The message attributes, which will be copied into the segment.
*
* Returns : true if successful, false otherwise.
*/
extern bool nr_segment_set_message(nr_segment_t* segment,
const nr_segment_message_t* message);
/*
* Purpose : Add a child to a segment.
*
Expand Down
4 changes: 2 additions & 2 deletions axiom/nr_segment_external.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ static void nr_segment_external_set_attrs(
* External/{host}/all non-CAT
* ExternalTransaction/{host}/{external_id}/{external_txnname} CAT
*
* These metrics are dictated by the spec located here:
* https://source.datanerd.us/agents/agent-specs/blob/master/Cross-Application-Tracing-PORTED.md
* These metrics are dictated by the agent-spec in this file:
* Cross-Application-Tracing-PORTED.md
*/
static void nr_segment_external_create_metrics(nr_segment_t* segment,
const char* uri,
Expand Down
Loading
Loading