-
Notifications
You must be signed in to change notification settings - Fork 0
feat(instrumentation-aws-sdk): add bedrock extension #1
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
Conversation
codefromthecrypt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will leave up to @trentm about js style, but this looks to be the same pattern as Python, where the aws sdk instrumentation is extended to include genai spans when working in bedrock.
Probably a good idea to make an issue like the "toehold" on in python in the genai instrumentation repo and mention this once it becomes a real pr.
Mentioning this beforehand could be confusing to non developers who may miss this is a sort of 'preflight' PR made to reduce back and forth in otel upstream repo.
trentm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice.
I have a number of nits/JS/style suggestions below.
A more general question: It is intentional (for now at least) that this isn't getting into emitting events (per https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md) and metrics?
| const SEMATTRS_GEN_AI_RESPONSE_FINISH_REASONS = | ||
| 'gen_ai.response.finish_reasons'; | ||
|
|
||
| export class BedrockRuntimeExtension implements ServiceExtension { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
| export class BedrockRuntimeExtension implements ServiceExtension { | |
| export class BedrockRuntimeServiceExtension implements ServiceExtension { |
The naming pattern from the others seems to be [ClientName]ServiceExtension.
| const SEMATTRS_GEN_AI_USAGE_INPUT_TOKENS = 'gen_ai.usage.input_tokens'; | ||
| const SEMATTRS_GEN_AI_USAGE_OUTPUT_TOKENS = 'gen_ai.usage.output_tokens'; | ||
| const SEMATTRS_GEN_AI_RESPONSE_FINISH_REASONS = | ||
| 'gen_ai.response.finish_reasons'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: We are close to having a pattern and a tool (open-telemetry#2669) to help generate a local src/semconv.ts to hold unstable semconv constants. However, I don't think this PR should get into handling that for all of instrumentation-aws-sdk. Better to do that in a separate PR. In other words: this is all good here.
We could update this to the newer-style constant names, if you like, e.g.:
const ATTR_GEN_AI_SYSTEM = 'gen_ai.system';
const ATTR_GEN_AI_OPERATION_NAME = 'gen_ai.operation.name';etc. https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions/#migrating-from-semattrs_-semresattrs_- for details on that deprecation.
However, no need to do so now. Happy to help with that migration.
| ): RequestMetadata { | ||
| let spanName: string | undefined; | ||
| const spanAttributes: Attributes = { | ||
| [SEMATTRS_GEN_AI_SYSTEM]: 'bedrock', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per open-telemetry/semantic-conventions#1574 (in semconv v1.29.0) the name for this is 'aws.bedrock'.
| [SEMATTRS_GEN_AI_SYSTEM]: 'bedrock', | |
| [SEMATTRS_GEN_AI_SYSTEM]: 'aws.bedrock', |
| ATTR_GEN_AI_USAGE_INPUT_TOKENS, | ||
| ATTR_GEN_AI_USAGE_OUTPUT_TOKENS, | ||
| ATTR_GEN_AI_RESPONSE_FINISH_REASONS, | ||
| } from '@opentelemetry/semantic-conventions/incubating'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that you are using the newer form of exported constants here.
We have a (recent) rule that "thou shalt not import the .../incubating" entry-point. Instead the recommendation is to have a copy of used attributes in a local src/semconv.ts. Docs on this here: https://github.com/open-telemetry/opentelemetry-js/blob/main/semantic-conventions/README.md#unstable-semconv
I pointed to a tool to help generate this semconv.ts file above. My PR to add that tool is here: open-telemetry#2669
(I'm having trouble getting reviews on my semconv-related PRs of late, because of the OTel JS focus on an "SDK 2.0" milestone right now.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I imported here only for the test, which checks for typos in the attribute names of the local definitions. With a tool to mostly guarantee no typos it might not matter, but is it intended to forbid importing incubating in tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but is it intended to forbid importing incubating in tests?
Heh, I figured you might ask.
I don't actually recall. It took a lot of back and forth to settle on the current advice. (Discussion was at open-telemetry/opentelemetry-js#5182).
My inclination is not use it in tests either. The scenario I'm thinking of is that, say a handful of instrumentations in opentelemetry-js-contrib.git are using .../incubating in their tests. Then it comes to a time when someone is updating the version of @opentelemetry/semantic-conventions used in the repo. This update would want to update the verison for all packages in the repo, because one of the goals of not ever pinning the dep of this package is to avoid having many copies of it installed in a user's node_modules/....
So if that update introduces breaking changes in the incubating entry-point (which is explicitly allowed), then it is the person updating the semconv dep for the whole repo that needs to go work through any package tests that happen to break.
As you say, if the src/semconv.ts files are generated with a tool, then there shouldn't be much/any need to be double-checking them by comparing with the incubating exports in tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, FWIW, the PR that I have to add a lint step to check on our intended usage of the semconv dep will break on test files attempting to use the incubating endpoint: open-telemetry#2569
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd consider renaming this file "bedrock-runtime.test.ts" to keep the name match with the @aws-sdk/bedrock-runtime package name.
| nockBack.fixtures = path.join(__dirname, 'mock-responses'); | ||
| if (!process.env.NOCK_BACK_MODE) { | ||
| nockBack.setMode('record'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it would be worth a short explanation of NOCK_BACK_MODE usage for re-generating the mock response file for this test. Those unfamiliar with nock.back will need to do some digging/reading. There isn't a current place in the README for this and it is internal detail stuff. I think a block comment at/near the top of the file would be useful.
| ConverseCommand, | ||
| ConversationRole, | ||
| } from '@aws-sdk/client-bedrock-runtime'; | ||
| import * as path from 'node:path'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import * as path from 'node:path'; | |
| import * as path from 'path'; |
Support for the node: prefix for builtin modules was added in v14.18.0, but "engines" for this package is currently "14", so it could fail for the poor sap still using the ancient early v14 version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ZOMG big change here.
I think this is almost certainly because the added @aws-sdk/client-bedrock-runtime dep is of a much more recent generation than all the other deps. That means we'll be getting between 2 and 7 installations of all the transitive deps.
"@aws-sdk/client-bedrock-runtime": "3.587.0",
"@aws-sdk/client-dynamodb": "3.85.0",
"@aws-sdk/client-kinesis": "3.85.0",
"@aws-sdk/client-lambda": "3.85.0",
"@aws-sdk/client-s3": "3.85.0",
"@aws-sdk/client-sns": "3.85.0",
"@aws-sdk/client-sqs": "3.85.0",
AFAIK there is no reason to have these other aws-sdk deps sitting at ancient versions. We should bump them up... perhaps even in this change.
Or if that gets gross, I'd be happy to do a PR to upstream that bumps the aws-sdk/client-* deps to recent versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Playing locally I upgraded all these deps as follows:
First apply this diff:
diff --git a/plugins/node/opentelemetry-instrumentation-aws-sdk/package.json b/plugins/node/opentelemetry-instrumentation-aws-sdk/package.json
index 80a8d7cf..2f2fad89 100644
--- a/plugins/node/opentelemetry-instrumentation-aws-sdk/package.json
+++ b/plugins/node/opentelemetry-instrumentation-aws-sdk/package.json
@@ -50,14 +50,14 @@
"@opentelemetry/semantic-conventions": "^1.27.0"
},
"devDependencies": {
- "@aws-sdk/client-bedrock-runtime": "3.587.0",
- "@aws-sdk/client-dynamodb": "3.85.0",
- "@aws-sdk/client-kinesis": "3.85.0",
- "@aws-sdk/client-lambda": "3.85.0",
- "@aws-sdk/client-s3": "3.85.0",
- "@aws-sdk/client-sns": "3.85.0",
- "@aws-sdk/client-sqs": "3.85.0",
- "@aws-sdk/types": "3.78.0",
+ "@aws-sdk/client-bedrock-runtime": "^3.587.0",
+ "@aws-sdk/client-dynamodb": "^3.85.0",
+ "@aws-sdk/client-kinesis": "^3.85.0",
+ "@aws-sdk/client-lambda": "^3.85.0",
+ "@aws-sdk/client-s3": "^3.85.0",
+ "@aws-sdk/client-sns": "^3.85.0",
+ "@aws-sdk/client-sqs": "^3.85.0",
+ "@aws-sdk/types": "^3.78.0",
"@opentelemetry/api": "^1.3.0",
"@opentelemetry/contrib-test-utils": "^0.45.0",
"@opentelemetry/sdk-trace-base": "^1.8.0",
diff --git a/plugins/node/opentelemetry-instrumentation-aws-sdk/src/aws-sdk.ts b/plugins/node/opentelemetry-instrumentation-aws-sdk/src/aws-sdk.ts
index a3040a15..f5e0ebc5 100644
--- a/plugins/node/opentelemetry-instrumentation-aws-sdk/src/aws-sdk.ts
+++ b/plugins/node/opentelemetry-instrumentation-aws-sdk/src/aws-sdk.ts
@@ -446,7 +446,11 @@ export class AwsInstrumentation extends InstrumentationBase<AwsSdkInstrumentatio
const serviceName =
clientConfig?.serviceId ??
removeSuffixFromStringIfExists(
- awsExecutionContext.clientName,
+ // Use 'AWS' as a fallback serviceName. I'm not sure of a case where
+ // an aws-sdk-v3 client does not have a `clientName`. The relevant
+ // `@aws-sdk/types` change to `interface HandlerExecutionContext` is
+ // https://github.com/smithy-lang/smithy-typescript/pull/931
+ awsExecutionContext.clientName || 'AWS',
'Client'
);
const commandName =Then update the deps:
cd plugins/node/opentelemetry-instrumentation-aws-sdk
npm update $(npm outdated | rg ^@aws-sdk | cut -d' ' -f1 | xargs)
It would be a cleaner change to have me (or someone) do that upgrade of deps in a separate PR to upstream.
|
thanks tons for the feedback, which looked to take a fair amount of time but a good investment @trentm! |
@trentm Yeah, this is meant to be an initial step with still (hopefully) reasonable implementation of required genai attributes on spans. Will follow up with more to keep the diffs smaller |
|
Thanks @trentm - I have applied all the changes and will go ahead and send this upstream where we can iterate more as needed |
|
@trentm Having your attention, was wondering if you can help with this mostly unrelated PR to the SDK open-telemetry/opentelemetry-js#5303 My sense is PRs without auto assigned reviewers never get reviewed so trying to see if some backchanneling can help... |
@codefromthecrypt @trentm This is a PR to my fork for initial bedrock extension for JS. I can send it upstream if it generally looks OK