open-telemetry / opentelemetry-dotnet-contrib

This repository contains set of components extending functionality of the OpenTelemetry .NET SDK. Instrumentation libraries, exporters, and other components can find their home here.
https://opentelemetry.io
Apache License 2.0
478 stars 285 forks source link

[feature request] Avoid overwriting the deployment.environment in AppServiceResourceDetector #2357

Open dmitchsplunk opened 15 hours ago

dmitchsplunk commented 15 hours ago

Component

OpenTelemetry.Resources.Azure

Is your feature request related to a problem?

While instrumenting a .NET Azure function, I noticed that the deployment.environment resource attribute got set to "Production", but couldn't figure out why.

It appears that it's being set in the AppServiceResourceDetector class.

First, the WEBSITE_SLOT_NAME environment variable value is loaded into a dictionary:

    internal static readonly IReadOnlyDictionary<string, string> AppServiceResourceAttributes = new Dictionary<string, string>
    {
        { ResourceSemanticConventions.AttributeCloudRegion, ResourceAttributeConstants.AppServiceRegionNameEnvVar },
   ->   { ResourceSemanticConventions.AttributeDeploymentEnvironment, ResourceAttributeConstants.AppServiceSlotNameEnvVar },
        { ResourceSemanticConventions.AttributeHostId, ResourceAttributeConstants.AppServiceHostNameEnvVar },
        { ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AppServiceInstanceIdEnvVar },
        { ResourceAttributeConstants.AzureAppServiceStamp, ResourceAttributeConstants.AppServiceStampNameEnvVar },
    };

It turns out that the default deployment slot for an Azure function is "Production", so the default value for WEBSITE_SLOT_NAME is also "Production".

The resource attribute then gets added as follows:

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

Note that the code doesn't current check to see if a resource attribute with the same name already exists.

What is the expected behavior?

If the deployment.environment resource attribute is already set, either via the OTEL_RESOURCE_ATTRIBUTES environment variable or via code, it should not be overwritten.

Which alternative solutions or features have you considered?

For now, I've created another deployment slot which indirectly produces the desired deployment.environment name. I may also be able to manually override the value of the WEBSITE_SLOT_NAME environment variable.

Additional context

No response

github-actions[bot] commented 15 hours ago

Tagging component owner(s).

@rajkumar-rangaraj @TimothyMothra

Kielek commented 8 hours ago

@dmitchsplunk, as I remember the order of the resource detectors meters.

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .ConfigureResource(resource => 
              resource.AddLowestPriorityResources()
              resource.AddHighestPriorityResources()
)
    // other configurations
    .Build();

The resources from the AddHighestPriorityResources resource detector will take precedence. You can consider changing the order of the registered resources.

I am not telling that the feature is not valid :- )