Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function assertBedrockSpans(transaction: TransactionEvent): void {
expect(spans, 'expected a Bedrock Converse span').toContainEqual(
expect.objectContaining({
description: `chat ${MODEL_ID}`,
op: 'chat',
origin: ORIGIN,
status: 'ok',
data: expect.objectContaining({
Expand All @@ -39,6 +40,7 @@ function assertBedrockSpans(transaction: TransactionEvent): void {
// InvokeModel (non-streaming, anthropic.claude request/response body)
expect(spans, 'expected a Bedrock InvokeModel span').toContainEqual(
expect.objectContaining({
op: 'generate_content',
Comment on lines 22 to +43

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

m: Hm, we typically prefix these with gen_ai., I don't know enough about bedrock but maybe we can align here with the other ai instrumentations?

origin: ORIGIN,
status: 'ok',
data: expect.objectContaining({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import {
GEN_AI_SYSTEM,
GEN_AI_USAGE_INPUT_TOKENS,
GEN_AI_USAGE_OUTPUT_TOKENS,
SENTRY_OP,
} from '@sentry/conventions/attributes';
import { GEN_AI_CHAT_SPAN_OP } from '@sentry/conventions/op';
import {
ATTR_GEN_AI_REQUEST_STOP_SEQUENCES,
GEN_AI_OPERATION_NAME_VALUE_CHAT,
Expand All @@ -41,6 +43,8 @@ interface ConverseStreamOutput {
[key: string]: any;
}

const GEN_AI_GENERATE_CONTENT_SPAN_OP = 'generate_content';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

q: Do we have a task to add this to sentry conventions?


export class BedrockRuntimeServiceExtension implements ServiceExtension {
private _diag: DiagLogger = diag;

Expand Down Expand Up @@ -76,6 +80,7 @@ export class BedrockRuntimeServiceExtension implements ServiceExtension {
// oxlint-disable-next-line typescript/no-deprecated
[GEN_AI_SYSTEM]: GEN_AI_SYSTEM_VALUE_AWS_BEDROCK,
[GEN_AI_OPERATION_NAME]: GEN_AI_OPERATION_NAME_VALUE_CHAT,
[SENTRY_OP]: GEN_AI_CHAT_SPAN_OP,
};

const modelId = request.commandInput.modelId;
Expand Down Expand Up @@ -120,6 +125,7 @@ export class BedrockRuntimeServiceExtension implements ServiceExtension {
const spanAttributes: Attributes = {
// oxlint-disable-next-line typescript/no-deprecated
[GEN_AI_SYSTEM]: GEN_AI_SYSTEM_VALUE_AWS_BEDROCK,
[SENTRY_OP]: GEN_AI_GENERATE_CONTENT_SPAN_OP,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

GenAI span ops missing prefix

High Severity

Bedrock spans set sentry.op to bare chat / generate_content, but every other GenAI integration in this SDK uses gen_ai.chat / gen_ai.generate_content. Core GenAI handling (extractGenAiSpansFromEvent, hasGenAiSpans, conversation ID attachment) keys off the gen_ai. prefix, so these inference spans stay misclassified and miss GenAI-specific processing.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 36653f4. Configure here.

// add operation name for InvokeModel API
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
CLOUD_REGION,
HTTP_STATUS_CODE,
SENTRY_KIND,
SENTRY_OP,
} from '@sentry/conventions/attributes';
import { DEBUG_BUILD } from '../../../debug-build';
import { CHANNELS } from '../../../orchestrion/channels';
Expand Down Expand Up @@ -110,10 +111,10 @@ const _awsIntegration = (() => {

const span = startInactiveSpan({
name: requestMetadata.spanName ?? `${normalizedRequest.serviceName}.${normalizedRequest.commandName}`,
// `rpc` matches what the exporter infers from `rpc.service` for the OTel aws-sdk spans;
// service extensions override it where inference yields a different op (DynamoDB: `db`).
op: requestMetadata.spanOp || 'rpc',
attributes: {
// `rpc` matches what the exporter infers from `rpc.service` for the OTel aws-sdk spans;
// service extensions override it where inference yields a different op (DynamoDB: `db`).
[SENTRY_OP]: requestMetadata.spanOp || 'rpc',
[SENTRY_KIND]: 'client',
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: AWS_SDK_ORIGIN,
...extractAttributesFromNormalizedRequest(normalizedRequest),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {
GEN_AI_SYSTEM,
GEN_AI_USAGE_INPUT_TOKENS,
GEN_AI_USAGE_OUTPUT_TOKENS,
SENTRY_OP,
} from '@sentry/conventions/attributes';
import { GEN_AI_CHAT_SPAN_OP } from '@sentry/conventions/op';
import { DEBUG_BUILD } from '../../../../debug-build';
import { GEN_AI_OPERATION_NAME_VALUE_CHAT, GEN_AI_SYSTEM_VALUE_AWS_BEDROCK } from '../constants';
import type { NormalizedRequest, NormalizedResponse } from '../types';
Expand All @@ -36,6 +38,8 @@ interface ConverseStreamOutput {
// of one structural type per family.
type ParsedChunk = any;

const GEN_AI_GENERATE_CONTENT_SPAN_OP = 'generate_content';

const textDecoder = new TextDecoder();

export class BedrockRuntimeServiceExtension implements ServiceExtension {
Expand Down Expand Up @@ -85,6 +89,7 @@ export class BedrockRuntimeServiceExtension implements ServiceExtension {
// oxlint-disable-next-line typescript/no-deprecated
[GEN_AI_SYSTEM]: GEN_AI_SYSTEM_VALUE_AWS_BEDROCK,
[GEN_AI_OPERATION_NAME]: GEN_AI_OPERATION_NAME_VALUE_CHAT,
[SENTRY_OP]: GEN_AI_CHAT_SPAN_OP,
};

const modelId = request.commandInput.modelId;
Expand Down Expand Up @@ -123,6 +128,7 @@ export class BedrockRuntimeServiceExtension implements ServiceExtension {
const spanAttributes: Record<string, unknown> = {
// oxlint-disable-next-line typescript/no-deprecated
[GEN_AI_SYSTEM]: GEN_AI_SYSTEM_VALUE_AWS_BEDROCK,
[SENTRY_OP]: GEN_AI_GENERATE_CONTENT_SPAN_OP,
};

const modelId = request.commandInput?.modelId;
Expand Down
Loading