From 9c5a661fc5435c33769e847fbb5ea9d38d6ec748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Sumis=C5=82awski?= Date: Thu, 4 Jul 2024 15:52:52 +0200 Subject: [PATCH] Avoid issues with cyclic jsons when instrumentig S3 by replicating python's logic (#38) * Introduce cx-wrapper wrapping handler function without using require/import hooks * back to main branch * fix otel-handler * Avoid issues with cyclic jsons when instrumentig S3 by replicating python's logic --- .../cx-wrapper/instrumentation-init.ts | 43 ++++++++++++++----- nodejs/packages/cx-wrapper/package-lock.json | 4 +- nodejs/packages/layer/package-lock.json | 4 +- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/nodejs/packages/cx-wrapper/instrumentation-init.ts b/nodejs/packages/cx-wrapper/instrumentation-init.ts index a39c584233..ed775c2778 100644 --- a/nodejs/packages/cx-wrapper/instrumentation-init.ts +++ b/nodejs/packages/cx-wrapper/instrumentation-init.ts @@ -1,6 +1,6 @@ import { diag, Span } from '@opentelemetry/api'; import { Instrumentation, registerInstrumentations } from '@opentelemetry/instrumentation'; -import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'; +import { AwsInstrumentation, NormalizedResponse } from '@opentelemetry/instrumentation-aws-sdk'; import { PgResponseHookInformation } from '@opentelemetry/instrumentation-pg'; import { OTEL_PAYLOAD_SIZE_LIMIT, OtelAttributes } from './common'; @@ -15,6 +15,8 @@ export function initializeInstrumentations(): any[] { new AwsInstrumentation({ suppressInternalInstrumentation: true, preRequestHook: (span: Span, { request }) => { + diag.debug(`preRequestHook for ${request.serviceName}.${request.commandName}`) + const data = JSON.stringify(request.commandInput); if (data !== undefined) { span.setAttribute( @@ -24,15 +26,21 @@ export function initializeInstrumentations(): any[] { } }, responseHook: (span, { response }) => { - const data = - 'data' in response && typeof response.data === 'object' - ? JSON.stringify(response.data) - : response?.data?.toString(); - if (data !== undefined) { - span.setAttribute( - OtelAttributes.RPC_RESPONSE_PAYLOAD, - data.substring(0, OTEL_PAYLOAD_SIZE_LIMIT) - ); + diag.debug(`responseHook for ${response.request.serviceName}.${response.request.commandName}`) + if (response.request.serviceName === 'S3') { + if ('buckets' in response && Array.isArray(response.buckets)) { + setResponsePayloadAttribute(span, JSON.stringify(response.buckets.map(b => b.Name))) + } else if ('contents' in response && Array.isArray(response.contents)) { + setResponsePayloadAttribute(span, JSON.stringify(response.contents.map(b => b.Key))) + } else if ('data' in response && typeof response.data === 'object') { + // data is too large and it contains cycles + } else { + const payload = responseDataToString(response) + setResponsePayloadAttribute(span, payload) + } + } else { + const payload = responseDataToString(response) + setResponsePayloadAttribute(span, payload) } }, }), @@ -47,6 +55,21 @@ export function initializeInstrumentations(): any[] { return instrumentations; } +function responseDataToString(response: NormalizedResponse): string { + return 'data' in response && typeof response.data === 'object' + ? JSON.stringify(response.data) + : response?.data?.toString(); +} + +function setResponsePayloadAttribute(span: Span, payload: string | undefined) { + if (payload !== undefined) { + span.setAttribute( + OtelAttributes.RPC_RESPONSE_PAYLOAD, + payload.substring(0, OTEL_PAYLOAD_SIZE_LIMIT) + ); + } +} + function defaultConfigureInstrumentations() { // Use require statements for instrumentation to avoid having to have transitive dependencies on all the typescript // definitions. diff --git a/nodejs/packages/cx-wrapper/package-lock.json b/nodejs/packages/cx-wrapper/package-lock.json index f82d5af8ad..73ea247861 100644 --- a/nodejs/packages/cx-wrapper/package-lock.json +++ b/nodejs/packages/cx-wrapper/package-lock.json @@ -287,7 +287,7 @@ "node_modules/@opentelemetry/instrumentation-aws-lambda": { "version": "0.39.0", "resolved": "file:../../../../opentelemetry-js-contrib-cx/plugins/node/opentelemetry-instrumentation-aws-lambda/opentelemetry-instrumentation-aws-lambda-0.39.0.tgz", - "integrity": "sha512-1QuJBHSXJ+mTSlLOs+lHVGplfDHZRinD8bnXPqjDu8VJnH48LaAdWKtvlbGvq25sefyYJnGMtXhqCVJS27HdfQ==", + "integrity": "sha512-jQxaSeuBI05oWHMGId/4ieS3cdGRiGKaXTVdFlpJnVdpzfPXXj6FfDXPpUDO6dvHPmYmSNe30VhnxAcCX1JwfA==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/instrumentation": "^0.49.1", @@ -1726,7 +1726,7 @@ }, "@opentelemetry/instrumentation-aws-lambda": { "version": "file:../../../../opentelemetry-js-contrib-cx/plugins/node/opentelemetry-instrumentation-aws-lambda/opentelemetry-instrumentation-aws-lambda-0.39.0.tgz", - "integrity": "sha512-1QuJBHSXJ+mTSlLOs+lHVGplfDHZRinD8bnXPqjDu8VJnH48LaAdWKtvlbGvq25sefyYJnGMtXhqCVJS27HdfQ==", + "integrity": "sha512-jQxaSeuBI05oWHMGId/4ieS3cdGRiGKaXTVdFlpJnVdpzfPXXj6FfDXPpUDO6dvHPmYmSNe30VhnxAcCX1JwfA==", "requires": { "@opentelemetry/instrumentation": "^0.49.1", "@opentelemetry/propagator-aws-xray": "^1.3.1", diff --git a/nodejs/packages/layer/package-lock.json b/nodejs/packages/layer/package-lock.json index 593f2af1b8..52ddbc0a88 100644 --- a/nodejs/packages/layer/package-lock.json +++ b/nodejs/packages/layer/package-lock.json @@ -288,7 +288,7 @@ "node_modules/@opentelemetry/instrumentation-aws-lambda": { "version": "0.39.0", "resolved": "file:../../../../opentelemetry-js-contrib-cx/plugins/node/opentelemetry-instrumentation-aws-lambda/opentelemetry-instrumentation-aws-lambda-0.39.0.tgz", - "integrity": "sha512-1QuJBHSXJ+mTSlLOs+lHVGplfDHZRinD8bnXPqjDu8VJnH48LaAdWKtvlbGvq25sefyYJnGMtXhqCVJS27HdfQ==", + "integrity": "sha512-jQxaSeuBI05oWHMGId/4ieS3cdGRiGKaXTVdFlpJnVdpzfPXXj6FfDXPpUDO6dvHPmYmSNe30VhnxAcCX1JwfA==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/instrumentation": "^0.49.1", @@ -1150,7 +1150,7 @@ "node_modules/cx-wrapper": { "version": "0.0.1", "resolved": "file:../cx-wrapper/cx-wrapper-0.0.1.tgz", - "integrity": "sha512-8YLhhs1zJuH+NB3SAMZ5moJkj55l9i8jFm4VMfFBeC2/dtLWq2NLhi1SaV1I2mEh+tlSMCJM0HTJk7SzcyVrrg==", + "integrity": "sha512-9CnHuCHZs+2a/XwAW13mfzshDnpibPEKUcjD+DFtTvUKOgvKqzT4QS3X2keuoQ6C6ueXiJ5e8/GVvPZwuoXCxQ==", "dependencies": { "@opentelemetry/api": "^1.7.0", "@opentelemetry/core": "1.22.0",