Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(agent): Add AWS DynamoDb Instrumentation #1037

Open
wants to merge 13 commits into
base: dev
Choose a base branch
from

Conversation

zsistla
Copy link
Contributor

@zsistla zsistla commented Mar 14, 2025

Added functionality to instrument

Call	                 collection(tablename)	operation	product

Create Table	TableName parameter	create_table	DynamoDB
Delete Item	TableName parameter	delete_item	DynamoDB
Delete Table	TableName parameter	delete_table	DynamoDB
Get Item	TableName parameter	get_item	DynamoDB
Put Item	TableName parameter	put_item	DynamoDB
Query	        TableName parameter	query	        DynamoDB
Scan	        TableName parameter	scan	        DynamoDB
Update Item	TableName parameter	update_item	DynamoDB

Unit tests added.
See also relevant multiverse PR.

Needed a modification to axiom to:

  • add db.system
  • modify datastore to allow for datastore that don't have concept of database name

zsistla added 2 commits March 14, 2025 09:33
* add db.system
* modify datastore to allow for datastore that don't have concept of database name
* Added instrumentation to handle the calls specified in the agent spec
* Added unit tests
@newrelic-php-agent-bot
Copy link

newrelic-php-agent-bot commented Mar 14, 2025

Test Suite Status Result
Multiverse 8/8 passing
SOAK 76/79 passing

@codecov-commenter
Copy link

codecov-commenter commented Mar 14, 2025

Codecov Report

Attention: Patch coverage is 54.05405% with 51 lines in your changes missing coverage. Please review.

Project coverage is 77.79%. Comparing base (8124792) to head (ea34ac0).

Files with missing lines Patch % Lines
agent/lib_aws_sdk_php.c 47.42% 51 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1037      +/-   ##
==========================================
- Coverage   77.87%   77.79%   -0.09%     
==========================================
  Files         198      198              
  Lines       27899    27991      +92     
==========================================
+ Hits        21727    21775      +48     
- Misses       6172     6216      +44     
Flag Coverage Δ
agent-for-php-7.2 78.14% <100.00%> (+<0.01%) ⬆️
agent-for-php-7.3 78.16% <100.00%> (+<0.01%) ⬆️
agent-for-php-7.4 77.87% <100.00%> (+<0.01%) ⬆️
agent-for-php-8.0 77.26% <100.00%> (+<0.01%) ⬆️
agent-for-php-8.1 77.57% <54.05%> (-0.08%) ⬇️
agent-for-php-8.2 77.18% <54.05%> (-0.08%) ⬇️
agent-for-php-8.3 77.18% <54.05%> (-0.08%) ⬇️
agent-for-php-8.4 77.20% <54.05%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mfulb mfulb self-requested a review March 28, 2025 16:51
if (NULL != datastore_params->collection && NULL != account_id
&& NULL != cloud_attrs->cloud_region) {
/* Must be freed by caller */
cloud_attrs->cloud_resource_id = nr_formatf(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be the best behavior here if cloud_attrs->cloud_resource_id was non-NULL?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best behavior? if non-NULL it gets passed back to caller who uses it to end the segment before freeing it.

Comment on lines +20 to +26
#define AWS_LAMBDA_ARN_REGEX \
"(arn:(aws[a-zA-Z-]*)?:lambda:)?" \
"((?<region>[a-z]{2}((-gov)|(-iso([a-z]?)))?-[a-z]+-\\d{1}):)?" \
"((?<accountId>\\d{12}):)?" \
"(function:)?" \
"(?<functionName>[a-zA-Z0-9-\\.]+)" \
"(:(?<qualifier>\\$LATEST|[a-zA-Z0-9-]+))?"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format only.

} else {
/* In case where host was found but port was not, spec says return
* unknown for port. */
datastore_params->instance->port_path_or_id = nr_strdup("unknown");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this just be the default port if unset?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No because we were able to extract a host just not a port. Once we've extracted a host, we cannot assume a port to go with it. Default port only ever pairs with default host.

nr_segment_cloud_attrs_t cloud_attrs = {
.cloud_platform = "aws_lambda"
};
nr_segment_cloud_attrs_t cloud_attrs = {.cloud_platform = "aws_lambda"};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format only

}
nr_segment_external_end(&external_segment, &external_params);
nr_free(cloud_attrs.cloud_resource_id);
}

/* This stores the compiled regex to parse AWS ARNs. The compilation happens when
* it is first needed and is destroyed in mshutdown
/* This stores the compiled regex to parse AWS ARNs. The compilation happens
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format only

Comment on lines +390 to +392
void nr_aws_sdk_lambda_client_invoke_parse_args(
NR_EXECUTE_PROTO,
nr_segment_cloud_attrs_t* cloud_attrs) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format only

Comment on lines +411 to +412
zval* lambda_name
= nr_php_zend_hash_find(Z_ARRVAL_P(lambda_args), "FunctionName");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format only

Comment on lines +423 to +424
nr_regex_substrings_t* matches = nr_regex_match_capture(
aws_arn_regex, Z_STRVAL_P(lambda_name), Z_STRLEN_P(lambda_name));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format only

Comment on lines +450 to +452
if (NULL != execute_data->func
&& NULL != execute_data->func->common.scope) {
base_class = execute_data->func->common.scope;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format only

Comment on lines +469 to +473
arn = nr_formatf("arn:aws:lambda:%s:%s:function:%s:%s", region, accountID,
function_name, qualifier);
} else {
arn = nr_formatf("arn:aws:lambda:%s:%s:function:%s",
region, accountID, function_name);
arn = nr_formatf("arn:aws:lambda:%s:%s:function:%s", region, accountID,
function_name);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format only

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants