Skip to content

Commit e1b01d8

Browse files
authored
Merge branch 'main' into main
2 parents 600972b + 71dfe82 commit e1b01d8

File tree

14 files changed

+967
-315
lines changed

14 files changed

+967
-315
lines changed

.github/workflows/release-lambda.yml

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
- name: Setup Node
4040
uses: actions/setup-node@v4
4141
with:
42-
node-version: 20
42+
node-version: 22
4343
- name: NPM Clean Install
4444
# https://docs.npmjs.com/cli/v10/commands/npm-ci
4545
run: npm ci
@@ -100,7 +100,7 @@ jobs:
100100
aws lambda publish-layer-version \
101101
--layer-name ${{ env.LAYER_NAME }} \
102102
--content S3Bucket=${{ env.BUCKET_NAME }},S3Key=layer.zip \
103-
--compatible-runtimes nodejs18.x nodejs20.x \
103+
--compatible-runtimes nodejs18.x nodejs20.x nodejs22.x \
104104
--compatible-architectures "arm64" "x86_64" \
105105
--license-info "Apache-2.0" \
106106
--description "AWS Distro of OpenTelemetry Lambda Layer for NodeJs Runtime" \
@@ -186,16 +186,6 @@ jobs:
186186
with:
187187
name: layer.tf
188188
path: layer.tf
189-
- name: Commit changes
190-
env:
191-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
192-
run: |
193-
git config user.name "github-actions[bot]"
194-
git config user.email "github-actions[bot]@users.noreply.github.com"
195-
mv layer.tf lambda-layer/terraform/lambda/
196-
git add lambda-layer/terraform/lambda/layer.tf
197-
git commit -m "Update Lambda layer ARNs for releasing" || echo "No changes to commit"
198-
git push
199189
create-release:
200190
runs-on: ubuntu-latest
201191
needs: generate-release-note
@@ -207,23 +197,12 @@ jobs:
207197
echo "COMMIT_SHA=${GITHUB_SHA}" >> $GITHUB_ENV
208198
SHORT_SHA=$(echo $GITHUB_SHA | cut -c1-7)
209199
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
210-
- name: Create Tag
211-
run: |
212-
git config user.name "github-actions[bot]"
213-
git config user.email "github-actions[bot]@users.noreply.github.com"
214-
TAG_NAME="lambda-${SHORT_SHA}"
215-
git tag -a "$TAG_NAME" -m "Release Lambda layer based on commit $TAG_NAME"
216-
git push origin "$TAG_NAME"
217-
echo "TAG_NAME=${TAG_NAME}" >> $GITHUB_ENV
218-
env:
219-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
220200
- name: Create Release
221201
id: create_release
222202
uses: actions/create-release@v1
223203
env:
224204
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
225205
with:
226-
tag_name: ${{ env.TAG_NAME }}
227206
release_name: "Release AWSOpenTelemetryDistroPython Lambda Layer"
228207
body_path: lambda-layer/terraform/lambda/layer.tf
229208
draft: true

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

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
"@aws-sdk/client-bedrock-runtime": "3.632.0",
6666
"@aws-sdk/client-kinesis": "3.632.0",
6767
"@aws-sdk/client-s3": "3.632.0",
68-
"@aws-sdk/client-sqs": "3.632.0",
6968
"@opentelemetry/contrib-test-utils": "0.41.0",
7069
"@types/mocha": "7.0.2",
7170
"@types/node": "18.6.5",
@@ -99,57 +98,6 @@
9998
"@opentelemetry/sdk-trace-base": "1.26.0",
10099
"@opentelemetry/semantic-conventions": "1.27.0"
101100
},
102-
"overrides": {
103-
"@opentelemetry/auto-instrumentations-node": {
104-
"@opentelemetry/instrumentation": "0.53.0",
105-
"@opentelemetry/instrumentation-amqplib": "0.42.0",
106-
"@opentelemetry/instrumentation-aws-lambda": "0.44.0",
107-
"@opentelemetry/instrumentation-aws-sdk": "0.44.0",
108-
"@opentelemetry/instrumentation-bunyan": "0.41.0",
109-
"@opentelemetry/instrumentation-cassandra-driver": "0.41.0",
110-
"@opentelemetry/instrumentation-connect": "0.39.0",
111-
"@opentelemetry/instrumentation-cucumber": "0.9.0",
112-
"@opentelemetry/instrumentation-dataloader": "0.12.0",
113-
"@opentelemetry/instrumentation-dns": "0.39.0",
114-
"@opentelemetry/instrumentation-express": "0.42.0",
115-
"@opentelemetry/instrumentation-fastify": "0.39.0",
116-
"@opentelemetry/instrumentation-fs": "0.15.0",
117-
"@opentelemetry/instrumentation-generic-pool": "0.39.0",
118-
"@opentelemetry/instrumentation-graphql": "0.43.0",
119-
"@opentelemetry/instrumentation-grpc": "0.53.0",
120-
"@opentelemetry/instrumentation-hapi": "0.41.0",
121-
"@opentelemetry/instrumentation-http": "0.53.0",
122-
"@opentelemetry/instrumentation-ioredis": "0.43.0",
123-
"@opentelemetry/instrumentation-kafkajs": "0.3.0",
124-
"@opentelemetry/instrumentation-knex": "0.40.0",
125-
"@opentelemetry/instrumentation-koa": "0.43.0",
126-
"@opentelemetry/instrumentation-lru-memoizer": "0.40.0",
127-
"@opentelemetry/instrumentation-memcached": "0.39.0",
128-
"@opentelemetry/instrumentation-mongodb": "0.47.0",
129-
"@opentelemetry/instrumentation-mongoose": "0.42.0",
130-
"@opentelemetry/instrumentation-mysql": "0.41.0",
131-
"@opentelemetry/instrumentation-mysql2": "0.41.0",
132-
"@opentelemetry/instrumentation-nestjs-core": "0.40.0",
133-
"@opentelemetry/instrumentation-net": "0.39.0",
134-
"@opentelemetry/instrumentation-pg": "0.44.0",
135-
"@opentelemetry/instrumentation-pino": "0.42.0",
136-
"@opentelemetry/instrumentation-redis": "0.42.0",
137-
"@opentelemetry/instrumentation-redis-4": "0.42.0",
138-
"@opentelemetry/instrumentation-restify": "0.41.0",
139-
"@opentelemetry/instrumentation-router": "0.40.0",
140-
"@opentelemetry/instrumentation-socket.io": "0.42.0",
141-
"@opentelemetry/instrumentation-tedious": "0.14.0",
142-
"@opentelemetry/instrumentation-undici": "0.6.0",
143-
"@opentelemetry/instrumentation-winston": "0.40.0",
144-
"@opentelemetry/resource-detector-alibaba-cloud": "0.29.1",
145-
"@opentelemetry/resource-detector-aws": "1.6.1",
146-
"@opentelemetry/resource-detector-azure": "0.2.11",
147-
"@opentelemetry/resource-detector-container": "0.4.1",
148-
"@opentelemetry/resource-detector-gcp": "0.29.11",
149-
"@opentelemetry/resources": "1.26.0",
150-
"@opentelemetry/sdk-node": "0.53.0"
151-
}
152-
},
153101
"files": [
154102
"build/src/**/*.js",
155103
"build/src/**/*.js.map",

aws-distro-opentelemetry-node-autoinstrumentation/src/aws-span-processing-util.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ export class AwsSpanProcessingUtil {
4747
// TODO: Use Semantic Conventions once upgraded
4848
static GEN_AI_REQUEST_MODEL: string = 'gen_ai.request.model';
4949
static GEN_AI_SYSTEM: string = 'gen_ai.system';
50+
static GEN_AI_REQUEST_MAX_TOKENS: string = 'gen_ai.request.max_tokens';
51+
static GEN_AI_REQUEST_TEMPERATURE: string = 'gen_ai.request.temperature';
52+
static GEN_AI_REQUEST_TOP_P: string = 'gen_ai.request.top_p';
53+
static GEN_AI_RESPONSE_FINISH_REASONS: string = 'gen_ai.response.finish_reasons';
54+
static GEN_AI_USAGE_INPUT_TOKENS: string = 'gen_ai.usage.input_tokens';
55+
static GEN_AI_USAGE_OUTPUT_TOKENS: string = 'gen_ai.usage.output_tokens';
5056

5157
static getDialectKeywords(): string[] {
5258
return SQL_DIALECT_KEYWORDS_JSON.keywords;

aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/bedrock.ts

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,196 @@ export class BedrockRuntimeServiceExtension implements ServiceExtension {
211211
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MODEL] = modelId;
212212
}
213213

214+
if (request.commandInput?.body) {
215+
const requestBody = JSON.parse(request.commandInput.body);
216+
if (modelId.includes('amazon.titan')) {
217+
if (requestBody.textGenerationConfig?.temperature !== undefined) {
218+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE] =
219+
requestBody.textGenerationConfig.temperature;
220+
}
221+
if (requestBody.textGenerationConfig?.topP !== undefined) {
222+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TOP_P] = requestBody.textGenerationConfig.topP;
223+
}
224+
if (requestBody.textGenerationConfig?.maxTokenCount !== undefined) {
225+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS] =
226+
requestBody.textGenerationConfig.maxTokenCount;
227+
}
228+
} else if (modelId.includes('anthropic.claude')) {
229+
if (requestBody.max_tokens !== undefined) {
230+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS] = requestBody.max_tokens;
231+
}
232+
if (requestBody.temperature !== undefined) {
233+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE] = requestBody.temperature;
234+
}
235+
if (requestBody.top_p !== undefined) {
236+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TOP_P] = requestBody.top_p;
237+
}
238+
} else if (modelId.includes('meta.llama')) {
239+
if (requestBody.max_gen_len !== undefined) {
240+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS] = requestBody.max_gen_len;
241+
}
242+
if (requestBody.temperature !== undefined) {
243+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE] = requestBody.temperature;
244+
}
245+
if (requestBody.top_p !== undefined) {
246+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TOP_P] = requestBody.top_p;
247+
}
248+
} else if (modelId.includes('cohere.command-r')) {
249+
if (requestBody.max_tokens !== undefined) {
250+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS] = requestBody.max_tokens;
251+
}
252+
if (requestBody.temperature !== undefined) {
253+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE] = requestBody.temperature;
254+
}
255+
if (requestBody.p !== undefined) {
256+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TOP_P] = requestBody.p;
257+
}
258+
if (requestBody.message !== undefined) {
259+
// NOTE: We approximate the token count since this value is not directly available in the body
260+
// According to Bedrock docs they use (total_chars / 6) to approximate token count for pricing.
261+
// https://docs.aws.amazon.com/bedrock/latest/userguide/model-customization-prepare.html
262+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_USAGE_INPUT_TOKENS] = Math.ceil(requestBody.message.length / 6);
263+
}
264+
} else if (modelId.includes('cohere.command')) {
265+
if (requestBody.max_tokens !== undefined) {
266+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS] = requestBody.max_tokens;
267+
}
268+
if (requestBody.temperature !== undefined) {
269+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE] = requestBody.temperature;
270+
}
271+
if (requestBody.p !== undefined) {
272+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TOP_P] = requestBody.p;
273+
}
274+
if (requestBody.prompt !== undefined) {
275+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_USAGE_INPUT_TOKENS] = Math.ceil(requestBody.prompt.length / 6);
276+
}
277+
} else if (modelId.includes('ai21.jamba')) {
278+
if (requestBody.max_tokens !== undefined) {
279+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS] = requestBody.max_tokens;
280+
}
281+
if (requestBody.temperature !== undefined) {
282+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE] = requestBody.temperature;
283+
}
284+
if (requestBody.top_p !== undefined) {
285+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TOP_P] = requestBody.top_p;
286+
}
287+
} else if (modelId.includes('mistral')) {
288+
if (requestBody.prompt !== undefined) {
289+
// NOTE: We approximate the token count since this value is not directly available in the body
290+
// According to Bedrock docs they use (total_chars / 6) to approximate token count for pricing.
291+
// https://docs.aws.amazon.com/bedrock/latest/userguide/model-customization-prepare.html
292+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_USAGE_INPUT_TOKENS] = Math.ceil(requestBody.prompt.length / 6);
293+
}
294+
if (requestBody.max_tokens !== undefined) {
295+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS] = requestBody.max_tokens;
296+
}
297+
if (requestBody.temperature !== undefined) {
298+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE] = requestBody.temperature;
299+
}
300+
if (requestBody.top_p !== undefined) {
301+
spanAttributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TOP_P] = requestBody.top_p;
302+
}
303+
}
304+
}
305+
214306
return {
215307
isIncoming,
216308
spanAttributes,
217309
spanKind,
218310
spanName,
219311
};
220312
}
313+
314+
responseHook(response: NormalizedResponse, span: Span, tracer: Tracer, config: AwsSdkInstrumentationConfig): void {
315+
const currentModelId = response.request.commandInput?.modelId;
316+
if (response.data?.body) {
317+
const decodedResponseBody = new TextDecoder().decode(response.data.body);
318+
const responseBody = JSON.parse(decodedResponseBody);
319+
if (currentModelId.includes('amazon.titan')) {
320+
if (responseBody.inputTextTokenCount !== undefined) {
321+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_USAGE_INPUT_TOKENS, responseBody.inputTextTokenCount);
322+
}
323+
if (responseBody.results?.[0]?.tokenCount !== undefined) {
324+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_USAGE_OUTPUT_TOKENS, responseBody.results[0].tokenCount);
325+
}
326+
if (responseBody.results?.[0]?.completionReason !== undefined) {
327+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_RESPONSE_FINISH_REASONS, [
328+
responseBody.results[0].completionReason,
329+
]);
330+
}
331+
} else if (currentModelId.includes('anthropic.claude')) {
332+
if (responseBody.usage?.input_tokens !== undefined) {
333+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_USAGE_INPUT_TOKENS, responseBody.usage.input_tokens);
334+
}
335+
if (responseBody.usage?.output_tokens !== undefined) {
336+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_USAGE_OUTPUT_TOKENS, responseBody.usage.output_tokens);
337+
}
338+
if (responseBody.stop_reason !== undefined) {
339+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_RESPONSE_FINISH_REASONS, [responseBody.stop_reason]);
340+
}
341+
} else if (currentModelId.includes('meta.llama')) {
342+
if (responseBody.prompt_token_count !== undefined) {
343+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_USAGE_INPUT_TOKENS, responseBody.prompt_token_count);
344+
}
345+
if (responseBody.generation_token_count !== undefined) {
346+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_USAGE_OUTPUT_TOKENS, responseBody.generation_token_count);
347+
}
348+
if (responseBody.stop_reason !== undefined) {
349+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_RESPONSE_FINISH_REASONS, [responseBody.stop_reason]);
350+
}
351+
} else if (currentModelId.includes('cohere.command-r')) {
352+
if (responseBody.text !== undefined) {
353+
// NOTE: We approximate the token count since this value is not directly available in the body
354+
// According to Bedrock docs they use (total_chars / 6) to approximate token count for pricing.
355+
// https://docs.aws.amazon.com/bedrock/latest/userguide/model-customization-prepare.html
356+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_USAGE_OUTPUT_TOKENS, Math.ceil(responseBody.text.length / 6));
357+
}
358+
if (responseBody.finish_reason !== undefined) {
359+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_RESPONSE_FINISH_REASONS, [responseBody.finish_reason]);
360+
}
361+
} else if (currentModelId.includes('cohere.command')) {
362+
if (responseBody.generations?.[0]?.text !== undefined) {
363+
span.setAttribute(
364+
AwsSpanProcessingUtil.GEN_AI_USAGE_OUTPUT_TOKENS,
365+
// NOTE: We approximate the token count since this value is not directly available in the body
366+
// According to Bedrock docs they use (total_chars / 6) to approximate token count for pricing.
367+
// https://docs.aws.amazon.com/bedrock/latest/userguide/model-customization-prepare.html
368+
Math.ceil(responseBody.generations[0].text.length / 6)
369+
);
370+
}
371+
if (responseBody.generations?.[0]?.finish_reason !== undefined) {
372+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_RESPONSE_FINISH_REASONS, [
373+
responseBody.generations[0].finish_reason,
374+
]);
375+
}
376+
} else if (currentModelId.includes('ai21.jamba')) {
377+
if (responseBody.usage?.prompt_tokens !== undefined) {
378+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_USAGE_INPUT_TOKENS, responseBody.usage.prompt_tokens);
379+
}
380+
if (responseBody.usage?.completion_tokens !== undefined) {
381+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_USAGE_OUTPUT_TOKENS, responseBody.usage.completion_tokens);
382+
}
383+
if (responseBody.choices?.[0]?.finish_reason !== undefined) {
384+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_RESPONSE_FINISH_REASONS, [
385+
responseBody.choices[0].finish_reason,
386+
]);
387+
}
388+
} else if (currentModelId.includes('mistral')) {
389+
if (responseBody.outputs?.[0]?.text !== undefined) {
390+
span.setAttribute(
391+
AwsSpanProcessingUtil.GEN_AI_USAGE_OUTPUT_TOKENS,
392+
// NOTE: We approximate the token count since this value is not directly available in the body
393+
// According to Bedrock docs they use (total_chars / 6) to approximate token count for pricing.
394+
// https://docs.aws.amazon.com/bedrock/latest/userguide/model-customization-prepare.html
395+
Math.ceil(responseBody.outputs[0].text.length / 6)
396+
);
397+
}
398+
if (responseBody.outputs?.[0]?.stop_reason !== undefined) {
399+
span.setAttribute(AwsSpanProcessingUtil.GEN_AI_RESPONSE_FINISH_REASONS, [
400+
responseBody.outputs[0].stop_reason,
401+
]);
402+
}
403+
}
404+
}
405+
}
221406
}

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,11 @@ diag.setLogger(new DiagConsoleLogger(), opentelemetry.core.getEnv().OTEL_LOG_LEV
2525
/*
2626
Sets up default environment variables and apply patches
2727
28-
Set default OTEL_EXPORTER_OTLP_PROTOCOL to be `http/protobuf`. This must be run before `configurator.configure()`, which will use this value to
29-
create an OTel Metric Exporter that is used for the customized AWS Span Procesors. The default value of OTEL_EXPORTER_OTLP_PROTOCOL should be `http/protobuf`:
28+
Set default OTEL_EXPORTER_OTLP_PROTOCOL to be `http/protobuf` to remain consistent with other ADOT languages. This must be run before
29+
`configurator.configure()`, which will use this value to create an OTel Metric Exporter that is used for the customized AWS Span Procesors.
30+
The default value of OTEL_EXPORTER_OTLP_PROTOCOL should be `http/protobuf`:
3031
https://github.com/open-telemetry/opentelemetry-js/blob/34003c9b7ef7e7e95e86986550d1c7fb6c1c56c6/packages/opentelemetry-core/src/utils/environment.ts#L233
3132
32-
We are setting OTEL_EXPORTER_OTLP_PROTOCOL to HTTP to avoid any potential issues with gRPC. In the ADOT Python SDKs, gRPC did not not work out of the box for
33-
the vended docker image, due to gRPC having a strict dependency on the Python version the artifact was built for (OTEL observed this:
34-
https://github.com/open-telemetry/opentelemetry-operator/blob/461ba68e80e8ac6bf2603eb353547cd026119ed2/autoinstrumentation/python/requirements.txt#L2-L3)
35-
3633
Also sets default OTEL_PROPAGATORS to ensure good compatibility with X-Ray and Application Signals.
3734
3835
This file may also be used to apply patches to upstream instrumentation - usually these are stopgap measures until we can contribute

0 commit comments

Comments
 (0)