Skip to content
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

fix(detector-aws): Get ECS Container ID from metadata #2509

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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 @@ -46,8 +46,6 @@
// 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';

Expand All @@ -65,11 +63,6 @@
* 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()
Expand All @@ -88,7 +81,7 @@
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) {
Expand All @@ -115,43 +108,16 @@
}
}

/**
* 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<Resource> {
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<Resource> {
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();

Check warning on line 120 in detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts

View check run for this annotation

Codecov / codecov/patch

detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts#L120

Added line #L120 was not covered by tests
}

private static async _getMetadataV4Resource(
Expand All @@ -174,10 +140,12 @@
: `${baseArn}:cluster/${cluster}`;

const containerArn: string = containerMetadata['ContainerARN'];
const containerId: string = containerMetadata['DockerId'];

Check warning on line 143 in detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts

View check run for this annotation

Codecov / codecov/patch

detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts#L143

Added line #L143 was not covered by tests

// 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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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',
Expand All @@ -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',
Expand All @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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',
Expand All @@ -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',
Expand All @@ -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',
Expand Down
Loading