Skip to content

Commit 9aa8086

Browse files
authored
AppSignals Functionality - add AlwaysRecordSampler and Utility files, add pr-build workflow (#9)
*Issue #, if available:* *Description of changes:* Implement the following files in TypeScript ``` always-record-sampler.ts aws-attribute-keys.ts aws-span-processing-util.ts configuration/sql_dialect_keywords.json sqs-url-parser.ts ``` - [Java Comparison](https://github.com/aws-observability/aws-otel-java-instrumentation/tree/main/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers) - [Python Comparison](https://github.com/aws-observability/aws-otel-python-instrumentation/tree/main/aws-opentelemetry-distro/src/amazon/opentelemetry/distro) By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
1 parent a25c3d4 commit 9aa8086

21 files changed

+2171
-26
lines changed

.github/workflows/pr-build.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: JavaScript Instrumentation PR Build
2+
on:
3+
pull_request:
4+
branches:
5+
- main
6+
- "release/v*"
7+
8+
permissions:
9+
id-token: write
10+
contents: read
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
fail-fast: false # ensures the entire test matrix is run, even if one permutation fails
17+
matrix:
18+
node: ["14", "16", "18", "20", "22"]
19+
env:
20+
NPM_CONFIG_UNSAFE_PERM: true
21+
steps:
22+
- name: Checkout Repo @ SHA - ${{ github.sha }}
23+
uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 0
26+
- name: Setup Node
27+
uses: actions/setup-node@v4
28+
with:
29+
node-version: ${{ matrix.node }}
30+
- name: Update npm to a version that supports workspaces (v7 or later)
31+
if: ${{ matrix.node < 16 }}
32+
run: npm install -g npm@9 # npm@9 supports node >=14.17.0
33+
- name: NPM Clean Install
34+
# https://docs.npmjs.com/cli/v10/commands/npm-ci
35+
run: npm ci
36+
- name: Compile all NPM projects
37+
run: npm run compile
38+
- name: Unit tests (Full)
39+
if: matrix.code-coverage
40+
run: npm run test
41+
- name: Report Coverage
42+
if: ${{ matrix.code-coverage && !cancelled()}}
43+
uses: codecov/codecov-action@v4
44+
with:
45+
verbose: true
46+
47+
lint:
48+
runs-on: ubuntu-latest
49+
steps:
50+
- uses: actions/checkout@v4
51+
- uses: actions/setup-node@v4
52+
with:
53+
node-version: 18
54+
cache: 'npm'
55+
- run: npm ci
56+
- name: Lint
57+
run: |
58+
npm run lint
59+
npm run lint:markdown
60+
npm run lint:readme

.markdownlint-cli2.jsonc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// https://github.com/open-telemetry/opentelemetry-js-contrib/blob/d52d4218235528dcecc706867425b86bac49b1f0/.markdownlint-cli2.jsonc
2+
{
3+
"config": {
4+
// https://github.com/DavidAnson/markdownlint/blob/main/README.md#rules--aliases
5+
"MD013": false,
6+
"MD024": false,
7+
"MD033": false,
8+
"MD041": false,
9+
// MD004/ul-style. We prefer dash, but generated CHANGELOG.md files use
10+
// asterisk. The default "consistent" is a good compromise.
11+
"MD004": { "style": "consistent" },
12+
// This setting is for a future potential CHANGELOG.md file, which doesn't exist yet
13+
"MD012": false // no-multiple-blanks; disabled because common in CHANGELOG.md files
14+
},
15+
"gitignore": true,
16+
"noBanner": true,
17+
"noProgress": true
18+
}

CODE_OF_CONDUCT.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
## Code of Conduct
2+
23
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
34
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4-
[email protected] with any additional questions or comments.
5+
<[email protected]> with any additional questions or comments.

CONTRIBUTING.md

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ reported the issue. Please try to include as much information as you can. Detail
2121

2222

2323
## Contributing via Pull Requests
24+
2425
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
2526

2627
1. You are working against the latest source on the *main* branch.
@@ -47,52 +48,67 @@ The following are useful commands that can be run within the `root` directory of
4748
Use `npm install` within the root directory to initialize all package directories before running any of the following commands.
4849

4950
### Build TypeScript into JavaScript
50-
```
51+
52+
```shell
5153
npm run compile
5254
```
5355

5456
### Lint
55-
```
57+
58+
```shell
5659
npm run lint
5760
```
5861

5962
### Lint automatic fixing
60-
```
63+
64+
```shell
6165
npm run lint:fix
6266
```
67+
68+
### Run unit tests
69+
70+
```shell
71+
npm run tests
72+
```
73+
6374
### Test the local ADOT JS package with your own local NodeJS project
6475

6576
In the `./aws-distro-opentelemetry-node-autoinstrumentation` directory, run:
66-
```
77+
78+
```shell
6779
npm install
6880
npm run compile
6981
npm link
7082
```
7183

7284
In the target local NodeJS project to be instrumented, run
7385

74-
```
86+
```shell
7587
npm install
7688
npm link @aws/aws-distro-opentelemetry-node-autoinstrumentation
7789
```
7890

7991
Your NodeJS project can now be run with your local copy of the ADOT NodeJS code with:
80-
```
92+
93+
```shell
8194
node --require '@aws/aws-distro-opentelemetry-node-autoinstrumentation/register' your-application.js.js
8295
```
8396

8497

8598
## Finding contributions to work on
99+
86100
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
87101

88102

89103
## Code of Conduct
104+
90105
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
91106
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
92-
[email protected] with any additional questions or comments.
107+
<[email protected]> with any additional questions or comments.
93108

94109

95110
## Security issue notifications
111+
96112
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
97113

98114

aws-distro-opentelemetry-node-autoinstrumentation/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
# AWS Distro for OpenTelemetry (ADOT) NodeJS Auto-Instrumentation
22

33
Install this package into your NodeJS project with:
4-
```
4+
5+
```shell
56
npm install --save @aws/aws-distro-opentelemetry-node-autoinstrumentation
67
```
78

89
Run your application with ADOT NodeJS with:
9-
```
10+
11+
```shell
1012
node --require '@aws/aws-distro-opentelemetry-node-autoinstrumentation/register' your-application.js
1113
```
1214

1315
## Sample Environment Variables for Application Signals
1416

15-
```
17+
```shell
1618
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
1719
export OTEL_PROPAGATORS=xray,tracecontext,b3,b3multi \
1820
export OTEL_TRACES_EXPORTER=console,otlp \

aws-distro-opentelemetry-node-autoinstrumentation/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
"rimraf": "5.0.5",
4646
"sinon": "15.2.0",
4747
"ts-mocha": "10.0.0",
48-
"typescript": "4.4.4"
48+
"typescript": "4.4.4",
49+
"expect": "29.2.0"
4950
},
5051
"dependencies": {
5152
"@opentelemetry/api": "1.9.0",
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import { Context, Link, SpanAttributes, SpanKind } from '@opentelemetry/api';
5+
import { Sampler, SamplingDecision, SamplingResult } from '@opentelemetry/sdk-trace-base';
6+
7+
/**
8+
* This sampler will return the sampling result of the provided {@link #rootSampler}, unless the
9+
* sampling result contains the sampling decision {@link SamplingDecision.NOT_RECORD}, in which case, a
10+
* new sampling result will be returned that is functionally equivalent to the original, except that
11+
* it contains the sampling decision {@link SamplingDecision.RECORD}. This ensures that all
12+
* spans are recorded, with no change to sampling.
13+
*
14+
* <p>The intended use case of this sampler is to provide a means of sending all spans to a
15+
* processor without having an impact on the sampling rate. This may be desirable if a user wishes
16+
* to count or otherwise measure all spans produced in a service, without incurring the cost of 100%
17+
* sampling.
18+
*/
19+
export class AlwaysRecordSampler implements Sampler {
20+
private rootSampler: Sampler;
21+
22+
public static create(rootSampler: Sampler): AlwaysRecordSampler {
23+
return new AlwaysRecordSampler(rootSampler);
24+
}
25+
26+
private constructor(rootSampler: Sampler) {
27+
if (rootSampler === null) {
28+
throw new Error('rootSampler is null. It must be provided');
29+
}
30+
this.rootSampler = rootSampler;
31+
}
32+
33+
shouldSample(
34+
context: Context,
35+
traceId: string,
36+
spanName: string,
37+
spanKind: SpanKind,
38+
attributes: SpanAttributes,
39+
links: Link[]
40+
): SamplingResult {
41+
const rootSamplerSamplingResult: SamplingResult = this.rootSampler.shouldSample(
42+
context,
43+
traceId,
44+
spanName,
45+
spanKind,
46+
attributes,
47+
links
48+
);
49+
if (rootSamplerSamplingResult.decision === SamplingDecision.NOT_RECORD) {
50+
return this.wrapResultWithRecordOnlyResult(rootSamplerSamplingResult);
51+
}
52+
return rootSamplerSamplingResult;
53+
}
54+
55+
toString(): string {
56+
return `AlwaysRecordSampler{${this.rootSampler.toString()}}`;
57+
}
58+
59+
wrapResultWithRecordOnlyResult(result: SamplingResult) {
60+
const wrappedResult: SamplingResult = {
61+
decision: SamplingDecision.RECORD,
62+
attributes: result.attributes,
63+
traceState: result.traceState,
64+
};
65+
return wrappedResult;
66+
}
67+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
// Utility class holding attribute keys with special meaning to AWS components
5+
export const AWS_ATTRIBUTE_KEYS: { [key: string]: string } = {
6+
AWS_SPAN_KIND: 'aws.span.kind',
7+
AWS_LOCAL_SERVICE: 'aws.local.service',
8+
AWS_LOCAL_OPERATION: 'aws.local.operation',
9+
AWS_REMOTE_SERVICE: 'aws.remote.service',
10+
AWS_REMOTE_OPERATION: 'aws.remote.operation',
11+
AWS_REMOTE_RESOURCE_TYPE: 'aws.remote.resource.type',
12+
AWS_REMOTE_RESOURCE_IDENTIFIER: 'aws.remote.resource.identifier',
13+
AWS_SDK_DESCENDANT: 'aws.sdk.descendant',
14+
AWS_CONSUMER_PARENT_SPAN_KIND: 'aws.consumer.parent.span.kind',
15+
16+
AWS_REMOTE_TARGET: 'aws.remote.target',
17+
AWS_REMOTE_DB_USER: 'aws.remote.db.user',
18+
19+
// Used for JavaScript workaround - attribute for pre-calculated value of isLocalRoot
20+
AWS_IS_LOCAL_ROOT: 'aws.is.local.root',
21+
22+
// Divergence from Java/Python
23+
// TODO: Audit this: These will most definitely be different in JavaScript.
24+
// For example:
25+
// - `messaging.url` for AWS_QUEUE_URL
26+
// - `aws.dynamodb.table_names` for AWS_TABLE_NAME
27+
AWS_BUCKET_NAME: 'aws.bucket.name',
28+
AWS_QUEUE_URL: 'aws.queue.url',
29+
AWS_QUEUE_NAME: 'aws.queue.name',
30+
AWS_STREAM_NAME: 'aws.stream.name',
31+
AWS_TABLE_NAME: 'aws.table.name',
32+
};

aws-distro-opentelemetry-node-autoinstrumentation/src/aws-opentelemetry-configurator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2-
//SPDX-License-Identifier: Apache-2.0
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
33

44
import { diag } from '@opentelemetry/api';
55
import {

0 commit comments

Comments
 (0)