Skip to content
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
10 changes: 10 additions & 0 deletions src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ internal void ExtractMetadataV4ResourceAttributes(AWSSemanticConventions.Attribu
using var containerResponse = JsonDocument.Parse(metadataV4ContainerResponse);
using var taskResponse = JsonDocument.Parse(metadataV4TaskResponse);

// On Linux the container ID is obtained from a file which does not exist on Windows.
// The ECS Metadata V4 container endpoint always carries the same ID in the "DockerId" field.
// See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint-v4-response.html.
if (OperatingSystem.IsWindows() &&
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I was intentionally conservative here to not change the existing behaviour for Linux.

containerResponse.RootElement.TryGetProperty("DockerId", out var dockerIdElement) &&
dockerIdElement.GetString() is string { Length: > 0 } dockerId)
{
resourceAttributes.AddAttributeContainerId(dockerId);
}
Comment on lines +111 to +119
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

Detect() still attempts to read /proc/self/cgroup on all OSes (via GetECSContainerId(AWSECSMetadataPath)), which will throw on Windows and gets logged as an extraction exception. Now that Windows container ID is obtained from Metadata V4, consider skipping the cgroup file read when OperatingSystem.IsWindows() (or otherwise avoiding the exception path) to prevent noisy logs and exception overhead on every detection run.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Open to changing this if wanted. I wanted to minimise the diff.


if (!containerResponse.RootElement.TryGetProperty("ContainerARN", out var containerArnElement)
|| containerArnElement.GetString() is not string containerArn)
{
Expand Down
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Resources.AWS/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
* Updated OpenTelemetry core component version(s) to `1.15.1`.
([#4020](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4020))

* Extract `container.id` from the ECS Metadata V4 `DockerId` field for
Windows containers running on AWS ECS.
([#4028](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4028))

## 1.15.0

Released 2026-Jan-21
Expand Down
15 changes: 12 additions & 3 deletions test/OpenTelemetry.Resources.AWS.Tests/AWSECSDetectorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ public void TestNotOnEcs()

[Fact]
public void TestGetECSContainerId()
{
Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", AWSECSDetector.GetECSContainerId(AWSECSMetadataFilePath));
}
=> Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", AWSECSDetector.GetECSContainerId(AWSECSMetadataFilePath));

[Fact]
public void TestEcsMetadataV3()
Expand Down Expand Up @@ -89,6 +87,11 @@ public async Task TestEcsMetadataV4Ec2()
Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/8f03e41243824aea923aca126495f665" });
Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata:log-stream:ecs/curl/8f03e41243824aea923aca126495f665" });
#pragma warning restore CA1861 // Avoid constant arrays as arguments

if (OperatingSystem.IsWindows())
{
Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeContainerId], "ea32192c8553fbff06c9340478a2ff089b2bb5646fb718b4ee206641c9086d66");
}
}
}
}
Expand Down Expand Up @@ -126,6 +129,11 @@ public async Task TestEcsMetadataV4Fargate()
Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/cd189a933e5849daa93386466019ab50" });
Assert.NotStrictEqual(resourceAttributes[ExpectedSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/containerlogs:log-stream:ecs/curl/cd189a933e5849daa93386466019ab50" });
#pragma warning restore CA1861 // Avoid constant arrays as arguments

if (OperatingSystem.IsWindows())
{
Assert.Equal(resourceAttributes[ExpectedSemanticConventions.AttributeContainerId], "cd189a933e5849daa93386466019ab50-2495160603");
}
}
}
}
Expand Down Expand Up @@ -187,6 +195,7 @@ private static class ExpectedSemanticConventions
public const string AttributeCloudAvailabilityZone = "cloud.availability_zone";
public const string AttributeCloudRegion = "cloud.region";
public const string AttributeCloudResourceId = "cloud.resource_id";
public const string AttributeContainerId = "container.id";
public const string AttributeEcsContainerArn = "aws.ecs.container.arn";
public const string AttributeEcsLaunchtype = "aws.ecs.launchtype";
public const string AttributeEcsTaskArn = "aws.ecs.task.arn";
Expand Down
Loading