Skip to content

Conversation

@Miqueasher
Copy link
Contributor

@Miqueasher Miqueasher commented Oct 30, 2025

This PR adds custom metrics to the existing sample app to verify public documentation is correct and functionality continues to work as changes happen in the future (Regression testing). Specifically for OpenTelemetry metrics using the CloudWatch Agent.

The changes made in this PR are:

New imports to index.js and dependencies to package.json (sample app's frontend service for the 'main' instance and the dependency installer)
Global meter, and gauge/histogram/counter added to FrontendServiceController.java from OTEL SDK Metrics page
Update to environment variables in main.tf
Update to jobs & env sections in node-ec2-default-test
Update to Cloudwatch agent config to include otlp ports
New Validator file to call updated predefined template file
Update to PredefinedExpectedTemplate to include new mustache file
New mustache file for validation of custom metrics

Git revert back to last passing CSHA: af399c7

Rollback procedure:

<Can we safely revert this commit if needed? If not, detail what must be done to safely revert and why it is needed.>

Ensure you've run the following tests on your changes and include the link below:

To do so, create a test.yml file with name: Test and workflow description to test your changes, then remove the file for your PR. Link your test run in your PR description. This process is a short term solution while we work on creating a staging environment for testing.

ADOT-SIGV4
EC2-DEFAULT
ASG

ECS
EKS
K8s

NOTE: TESTS RUNNING ON A SINGLE EKS CLUSTER CANNOT BE RUN IN PARALLEL. See the needs keyword to run tests in succession.

  • Run Java EKS on e2e-playground in us-east-1 and eu-central-2
  • Run Python EKS on e2e-playground in us-east-1 and eu-central-2
  • Run metric limiter on EKS cluster e2e-playground in us-east-1 and eu-central-2
  • Run EC2 tests in all regions
  • Run K8s on a separate K8s cluster (check IAD test account for master node endpoints; these will change as we create and destroy clusters for OS patching)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Comment on lines +190 to +191


Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Remove whitespace changes

Copy link
Contributor

@thpierce thpierce left a comment

Choose a reason for hiding this comment

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

Pretty high level review, didn't go into great detail, but a few comments nonetheless

tmux send-keys -t frontend 'export AWS_REGION="$${AWS_REGION}"' C-m
tmux send-keys -t frontend 'export TESTING_ID="$${TESTING_ID}"' C-m
tmux send-keys -t frontend 'export OTEL_NODE_DISABLED_INSTRUMENTATIONS=fs,dns,express' C-m
tmux send-keys -t frontend 'export OTEL_SERVICE_NAME=node-sample-application-${var.test_id}' C-m
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Should use SERVICE_NAME

"dependencies": {
"@aws-sdk/client-s3": "3.621.0",
"@aws-sdk/client-s3": "^3.621.0",
"@aws/aws-distro-opentelemetry-node-autoinstrumentation": "^0.8.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is @aws/aws-distro-opentelemetry-node-autoinstrumentation needed?

"express": "^4.21.2",
"mysql2": "^3.11.0",
"bunyan": "^1.8.15"
"mysql2": "^3.15.3"
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is an update to mysql2 needed?

Comment on lines 117 to 191

try {
await s3Client.send(
new GetBucketLocationCommand({
Bucket: bucketName,
}),
).then((data) => {
const msg = '/aws-sdk-call called successfully; UNEXPECTEDLY RETURNED DATA: ' + data;
logger.info(msg);
res.send(msg);
});
} catch (e) {
if (e instanceof Error) {
const msg = '/aws-sdk-call called successfully';
logger.info(msg);
res.send(msg);
}
}
});

app.get('/remote-service', (req, res) => {
const endpoint = req.query.ip || 'localhost';
const options = {
hostname: endpoint,
port: 8001,
method: 'GET',
path: '/healthcheck'
};

const request = http.request(options, (rs) => {
rs.setEncoding('utf8');
rs.on('data', (result) => {
const msg = `/remote-service called successfully: ${result}`;
logger.info(msg);
res.send(msg);
});
});
request.on('error', (err) => {
const msg = '/remote-service called with errors: ' + err.errors;
logger.error(msg);
res.send(msg);
});
request.end();
});

// The following logic serves as the async call made by the /client-call API
let makeAsyncCall = false;
setInterval(() => {
if (makeAsyncCall) {
makeAsyncCall = false;
logger.info('Async call triggered by /client-call API');

const request = http.get('http://local-root-client-call', (rs) => {
rs.setEncoding('utf8');
rs.on('data', (result) => {
const msg = `GET local-root-client-call response: ${result}`;
logger.info(msg);
res.send(msg);
});
});
request.on('error', (err) => {}); // Expected
request.end();
}
}, 5000); // Check every 5 seconds

app.get('/client-call', (req, res) => {
const msg = '/client-call called successfully';
logger.info(msg);
res.send(msg);
// Trigger async call to generate telemetry for InternalOperation use case
makeAsyncCall = true;
});



Copy link
Contributor

Choose a reason for hiding this comment

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

Try to avoid unrelated changes

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants