diff --git a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts index 56977c2c01..dea8034d68 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts +++ b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts @@ -46,8 +46,6 @@ import { // Patch until the OpenTelemetry SDK is updated to ship this attribute import { SemanticResourceAttributes as AdditionalSemanticResourceAttributes } from './SemanticResourceAttributes'; import * as http from 'http'; -import * as util from 'util'; -import * as fs from 'fs'; import * as os from 'os'; import { getEnv } from '@opentelemetry/core'; @@ -65,11 +63,6 @@ interface AwsLogOptions { * plugins of AWS X-Ray. Returns an empty Resource if detection fails. */ export class AwsEcsDetectorSync implements DetectorSync { - static readonly CONTAINER_ID_LENGTH = 64; - static readonly DEFAULT_CGROUP_PATH = '/proc/self/cgroup'; - - private static readFileAsync = util.promisify(fs.readFile); - detect(): IResource { const attributes = context.with(suppressTracing(context.active()), () => this._getAttributes() @@ -88,7 +81,7 @@ export class AwsEcsDetectorSync implements DetectorSync { let resource = new Resource({ [SEMRESATTRS_CLOUD_PROVIDER]: CLOUDPROVIDERVALUES_AWS, [SEMRESATTRS_CLOUD_PLATFORM]: CLOUDPLATFORMVALUES_AWS_ECS, - }).merge(await AwsEcsDetectorSync._getContainerIdAndHostnameResource()); + }).merge(await AwsEcsDetectorSync._getHostnameResource()); const metadataUrl = getEnv().ECS_CONTAINER_METADATA_URI_V4; if (metadataUrl) { @@ -115,43 +108,16 @@ export class AwsEcsDetectorSync implements DetectorSync { } } - /** - * Read container ID from cgroup file - * In ECS, even if we fail to find target file - * or target file does not contain container ID - * we do not throw an error but throw warning message - * and then return null string - */ - private static async _getContainerIdAndHostnameResource(): Promise { - const hostName = os.hostname(); - - let containerId = ''; - try { - const rawData = await AwsEcsDetectorSync.readFileAsync( - AwsEcsDetectorSync.DEFAULT_CGROUP_PATH, - 'utf8' - ); - const splitData = rawData.trim().split('\n'); - for (const str of splitData) { - if (str.length > AwsEcsDetectorSync.CONTAINER_ID_LENGTH) { - containerId = str.substring( - str.length - AwsEcsDetectorSync.CONTAINER_ID_LENGTH - ); - break; - } - } - } catch (e) { - diag.debug('AwsEcsDetector failed to read container ID', e); - } + private static async _getHostnameResource(): Promise { + const hostName = os.hostname(); - if (hostName || containerId) { - return new Resource({ - [SEMRESATTRS_CONTAINER_NAME]: hostName || '', - [SEMRESATTRS_CONTAINER_ID]: containerId || '', - }); - } + if (hostName) { + return new Resource({ + [SEMRESATTRS_CONTAINER_NAME]: hostName || '' + }); + } - return Resource.empty(); + return Resource.empty(); } private static async _getMetadataV4Resource( @@ -174,10 +140,12 @@ export class AwsEcsDetectorSync implements DetectorSync { : `${baseArn}:cluster/${cluster}`; const containerArn: string = containerMetadata['ContainerARN']; + const containerId: string = containerMetadata['DockerId']; // https://github.com/open-telemetry/semantic-conventions/blob/main/semantic_conventions/resource/cloud_provider/aws/ecs.yaml const attributes: ResourceAttributes = { [SEMRESATTRS_AWS_ECS_CONTAINER_ARN]: containerArn, + [SEMRESATTRS_CONTAINER_ID]: containerId, [SEMRESATTRS_AWS_ECS_CLUSTER_ARN]: clusterArn, [SEMRESATTRS_AWS_ECS_LAUNCHTYPE]: launchType?.toLowerCase(), [SEMRESATTRS_AWS_ECS_TASK_ARN]: taskArn, diff --git a/detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsEcsDetector.test.ts b/detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsEcsDetector.test.ts index 6a019fc82f..6f28d6530b 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsEcsDetector.test.ts +++ b/detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsEcsDetector.test.ts @@ -25,6 +25,7 @@ import { } from '@opentelemetry/contrib-test-utils'; import { Resource } from '@opentelemetry/resources'; import { + SEMRESATTRS_CONTAINER_ID, SEMRESATTRS_CLOUD_PLATFORM, SEMRESATTRS_AWS_ECS_CONTAINER_ARN, SEMRESATTRS_AWS_ECS_CLUSTER_ARN, @@ -51,6 +52,7 @@ interface EcsResourceAttributes { readonly zone?: string; readonly clusterArn?: string; readonly containerArn?: string; + readonly containerId?: string; readonly launchType?: 'ec2' | 'fargate'; readonly taskArn?: string; readonly taskFamily?: string; @@ -80,6 +82,11 @@ const assertEcsResource = ( resource.attributes[SEMRESATTRS_AWS_ECS_CONTAINER_ARN], validations.containerArn ); + if (validations.containerId) + assert.strictEqual( + resource.attributes[SEMRESATTRS_CONTAINER_ID], + validations.containerId + ); assert.strictEqual( resource.attributes[AdditionalSemanticResourceAttributes.CLOUD_RESOURCE_ID], validations.containerArn @@ -343,6 +350,7 @@ describe('AwsEcsResourceDetector', () => { clusterArn: 'arn:aws:ecs:us-west-2:111122223333:cluster/default', containerArn: 'arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9', + containerId: 'ea32192c8553fbff06c9340478a2ff089b2bb5646fb718b4ee206641c9086d66', launchType: 'ec2', taskArn: 'arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c', @@ -369,6 +377,7 @@ describe('AwsEcsResourceDetector', () => { clusterArn: 'arn:aws:ecs:us-west-2:111122223333:cluster/default', containerArn: 'arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1', + containerId: 'cd189a933e5849daa93386466019ab50-2495160603', launchType: 'fargate', taskArn: 'arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3', @@ -391,6 +400,7 @@ describe('AwsEcsResourceDetector', () => { clusterArn: 'arn:aws:ecs:us-west-2:111122223333:cluster/default', containerArn: 'arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1', + containerId: 'cd189a933e5849daa93386466019ab50-2495160603', launchType: 'fargate', taskArn: 'arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3', diff --git a/detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsEcsDetectorSync.test.ts b/detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsEcsDetectorSync.test.ts index 171804bf1b..a6f23b4c24 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsEcsDetectorSync.test.ts +++ b/detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsEcsDetectorSync.test.ts @@ -25,6 +25,7 @@ import { } from '@opentelemetry/contrib-test-utils'; import { Resource } from '@opentelemetry/resources'; import { + SEMRESATTRS_CONTAINER_ID, SEMRESATTRS_CLOUD_PLATFORM, SEMRESATTRS_AWS_ECS_CONTAINER_ARN, SEMRESATTRS_AWS_ECS_CLUSTER_ARN, @@ -51,6 +52,7 @@ interface EcsResourceAttributes { readonly zone?: string; readonly clusterArn?: string; readonly containerArn?: string; + readonly containerId?: string; readonly launchType?: 'ec2' | 'fargate'; readonly taskArn?: string; readonly taskFamily?: string; @@ -80,6 +82,11 @@ const assertEcsResource = ( resource.attributes[SEMRESATTRS_AWS_ECS_CONTAINER_ARN], validations.containerArn ); + if (validations.containerId) + assert.strictEqual( + resource.attributes[SEMRESATTRS_CONTAINER_ID], + validations.containerId + ); assert.strictEqual( resource.attributes[AdditionalSemanticResourceAttributes.CLOUD_RESOURCE_ID], validations.containerArn @@ -343,6 +350,7 @@ describe('AwsEcsResourceDetectorSync', () => { clusterArn: 'arn:aws:ecs:us-west-2:111122223333:cluster/default', containerArn: 'arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9', + containerId: 'ea32192c8553fbff06c9340478a2ff089b2bb5646fb718b4ee206641c9086d66', launchType: 'ec2', taskArn: 'arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c', @@ -369,6 +377,7 @@ describe('AwsEcsResourceDetectorSync', () => { clusterArn: 'arn:aws:ecs:us-west-2:111122223333:cluster/default', containerArn: 'arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1', + containerId: 'cd189a933e5849daa93386466019ab50-2495160603', launchType: 'fargate', taskArn: 'arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3', @@ -391,6 +400,7 @@ describe('AwsEcsResourceDetectorSync', () => { clusterArn: 'arn:aws:ecs:us-west-2:111122223333:cluster/default', containerArn: 'arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1', + containerId: 'cd189a933e5849daa93386466019ab50-2495160603', launchType: 'fargate', taskArn: 'arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3',