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

[Resources.Azure] Add support for Container App Jobs #2064

Merged
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f20605c
add support for Container App Jobs
hansmbakker Sep 11, 2024
fa5e938
Update channgelog and readme
hansmbakker Sep 11, 2024
676444d
Merge branch 'main' into feature/container_app_job-detector
Kielek Sep 11, 2024
d75fa62
Fix line length in markdown
hansmbakker Sep 11, 2024
07dd520
Fix test
hansmbakker Sep 11, 2024
703447b
Merge branch 'feature/container_app_job-detector' of https://github.c…
hansmbakker Sep 11, 2024
9789fb6
Label environment variables for Azure Container Apps Jobs
hansmbakker Sep 12, 2024
2d16d93
Merge branch 'main' into feature/container_app_job-detector
hansmbakker Sep 12, 2024
31dd016
Add sample app to show the ContainerAppJob detection behavior
hansmbakker Sep 12, 2024
db4005b
Merge branch 'feature/container_app_job-detector' of https://github.c…
hansmbakker Sep 12, 2024
5fad1c6
remove example containerappjob project
hansmbakker Sep 13, 2024
51844af
Merge branch 'main' into feature/container_app_job-detector
hansmbakker Sep 13, 2024
8a5cc32
md-lint fix
Kielek Sep 16, 2024
cfdb25c
Merge branch 'main' into feature/container_app_job-detector
Kielek Sep 16, 2024
1bc40b8
Merge branch 'main' into feature/container_app_job-detector
cijothomas Sep 16, 2024
1d35b51
Merge branch 'main' into feature/container_app_job-detector
hansmbakker Sep 17, 2024
9d053ea
Merge branch 'main' into feature/container_app_job-detector
Kielek Sep 20, 2024
d6dad2c
Merge branch 'main' into feature/container_app_job-detector
hansmbakker Sep 20, 2024
f6ecf3a
Clear the container apps app / job name env vars between tests
hansmbakker Sep 20, 2024
2897aa2
Merge branch 'main' into feature/container_app_job-detector
Kielek Sep 24, 2024
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 @@ -10,35 +10,38 @@ namespace OpenTelemetry.Resources.Azure;
/// </summary>
internal sealed class AzureContainerAppsResourceDetector : IResourceDetector
{
internal static readonly IReadOnlyDictionary<string, string> AzureContainerResourceAttributes = new Dictionary<string, string>
internal static readonly IReadOnlyDictionary<string, string> AzureContainerAppResourceAttributes = new Dictionary<string, string>
{
{ ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AzureContainerAppsReplicaNameEnvVar },
{ ResourceSemanticConventions.AttributeServiceVersion, ResourceAttributeConstants.AzureContainerAppsRevisionEnvVar },
};

internal static readonly IReadOnlyDictionary<string, string> AzureContainerAppJobResourceAttributes = new Dictionary<string, string>
{
{ ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AzureContainerAppsReplicaNameEnvVar },
{ ResourceSemanticConventions.AttributeServiceVersion, ResourceAttributeConstants.AzureContainerAppJobExecutionNameEnvVar },
};

/// <inheritdoc/>
public Resource Detect()
{
List<KeyValuePair<string, object>> attributeList = new();

List<KeyValuePair<string, object>> attributeList = new List<KeyValuePair<string, object>>();
try
{
var containerAppName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar);
var containerAppJobName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppJobNameEnvVar);

if (containerAppName != null)
{
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeServiceName, containerAppName));
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.AzureCloudProviderValue));
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.AzureContainerAppsPlatformValue));

foreach (var kvp in AzureContainerResourceAttributes)
{
var attributeValue = Environment.GetEnvironmentVariable(kvp.Value);
if (attributeValue != null)
{
attributeList.Add(new KeyValuePair<string, object>(kvp.Key, attributeValue));
}
}
AddBaseAttributes(attributeList, containerAppName);

AddResourceAttributes(attributeList, AzureContainerAppResourceAttributes);
}
else if (containerAppJobName != null)
{
AddBaseAttributes(attributeList, containerAppJobName);

AddResourceAttributes(attributeList, AzureContainerAppJobResourceAttributes);
}
}
catch
Expand All @@ -49,4 +52,23 @@ public Resource Detect()

return new Resource(attributeList);
}

private static void AddResourceAttributes(List<KeyValuePair<string, object>> attributeList, IReadOnlyDictionary<string, string> resourceAttributes)
{
foreach (var kvp in resourceAttributes)
{
var attributeValue = Environment.GetEnvironmentVariable(kvp.Value);
if (attributeValue != null)
{
attributeList.Add(new KeyValuePair<string, object>(kvp.Key, attributeValue));
}
}
}

private static void AddBaseAttributes(List<KeyValuePair<string, object>> attributeList, string serviceName)
{
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeServiceName, serviceName));
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.AzureCloudProviderValue));
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.AzureContainerAppsPlatformValue));
}
}
3 changes: 3 additions & 0 deletions src/OpenTelemetry.Resources.Azure/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Added support for [Azure Container Apps jobs](https://learn.microsoft.com/en-us/azure/container-apps/jobs?tabs=azure-cli).
([#2064](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2064))

* Added direct reference to `System.Text.Encodings.Web` with minimum version of
`4.7.2` in response to [CVE-2021-26701](https://github.com/dotnet/runtime/issues/49377).
([#2056](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2056))
Expand Down
10 changes: 5 additions & 5 deletions src/OpenTelemetry.Resources.Azure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder()

## Azure Container Apps Resource Detector

Adds resource attributes for the applications running in Azure Container Apps.
The following example shows how to add `AzureContainerAppsResourceDetector` to
the `ResourceBuilder`.
Adds resource attributes for the applications running in Azure Container Apps
or Azure Container App jobs. The following example shows how to add
`AzureContainerAppsResourceDetector` to the `ResourceBuilder`.

```csharp
using OpenTelemetry;
Expand All @@ -122,5 +122,5 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder()
| cloud.platform | The cloud platform. Here, it's always "azure_container_apps". |
| cloud.provider | The cloud service provider. In this context, it's always "azure". |
| service.instance.id | Represents the specific instance ID of Azure Container Apps, useful in scaled-out configurations. |
| service.name | The name of the Azure Container Apps. |
| service.version | The current revision or version of Azure Container Apps. |
| service.name | The name of the Azure Container Apps or Azure Container Apps job. |
| service.version | The current revision or version of Azure Container Apps, or in case of a Azure Container Apps job - the job execution name. |
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ internal sealed class ResourceAttributeConstants
internal const string AzureContainerAppsReplicaNameEnvVar = "CONTAINER_APP_REPLICA_NAME";
internal const string AzureContainerAppsRevisionEnvVar = "CONTAINER_APP_REVISION";

// Azure Container Apps Jobs environment variables
internal const string AzureContainerAppJobNameEnvVar = "CONTAINER_APP_JOB_NAME";
internal const string AzureContainerAppJobExecutionNameEnvVar = "CONTAINER_APP_JOB_EXECUTION_NAME";
hansmbakker marked this conversation as resolved.
Show resolved Hide resolved

// Azure resource attributes constant values
internal const string AzureAppServicePlatformValue = "azure_app_service";
internal const string AzureCloudProviderValue = "azure";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public void AzureContainerAppsResourceDetectorReturnsResourceWithAttributes()
{
try
{
foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerResourceAttributes)
foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes)
{
Environment.SetEnvironmentVariable(kvp.Value, kvp.Key);
}
Expand All @@ -113,7 +113,34 @@ public void AzureContainerAppsResourceDetectorReturnsResourceWithAttributes()

Assert.Contains(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeServiceName, "containerAppName"), resource.Attributes);

foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerResourceAttributes)
foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes)
{
Assert.Contains(new KeyValuePair<string, object>(kvp.Key, kvp.Key), resource.Attributes);
}
}

[Fact]
public void AzureContainerAppsJobResourceDetectorReturnsResourceWithAttributes()
{
try
{
foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes)
{
Environment.SetEnvironmentVariable(kvp.Value, kvp.Key);
}

Environment.SetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppJobNameEnvVar, "containerAppJobName");
}
catch
{
}
hansmbakker marked this conversation as resolved.
Show resolved Hide resolved

var resource = ResourceBuilder.CreateEmpty().AddAzureContainerAppsDetector().Build();
Assert.NotNull(resource);

Assert.Contains(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeServiceName, "containerAppJobName"), resource.Attributes);

foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes)
{
Assert.Contains(new KeyValuePair<string, object>(kvp.Key, kvp.Key), resource.Attributes);
}
Expand All @@ -126,7 +153,12 @@ public void Dispose()
Environment.SetEnvironmentVariable(kvp.Value, null);
}

foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerResourceAttributes)
foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes)
{
Environment.SetEnvironmentVariable(kvp.Value, null);
}

foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes)
{
Environment.SetEnvironmentVariable(kvp.Value, null);
}
Expand Down