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

Remove metric telemetry for resource #38697

Merged
merged 6 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -54,14 +54,14 @@ public async Task ValidateTelemetryExport()
// Telemetry is serialized as json, and then byte encoded.
// Need to parse the request content into something assertable.
var data = ParseJsonRequestContent<ParsedData>(transport.Requests);
Assert.Equal(16, data.Count); // Total telemetry items
Assert.Equal(15, data.Count); // Total telemetry items

// Group all parsed telemetry by name and get the count per name.
var summary = data.GroupBy(x => x.name).ToDictionary(x => x.Key!, x => x.Count());

Assert.Equal(4, summary.Count); // Total unique telemetry items
Assert.Equal(8, summary["Message"]); // Count of telemetry items
Assert.Equal(6, summary["Metric"]);
Assert.Equal(5, summary["Metric"]);
Assert.Equal(1, summary["RemoteDependency"]);
Assert.Equal(1, summary["Request"]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,20 @@ internal static class ResourceExtensions
}
}

if (metricsData != null)
bool shouldReportMetricTelemetry = false;
try
{
var exportResource = Environment.GetEnvironmentVariable("EXPORT_METRIC_FOR_RESOURCE_ATTRIBUTES");
vishweshbankwar marked this conversation as resolved.
Show resolved Hide resolved
if (exportResource.Equals("true", StringComparison.OrdinalIgnoreCase))
{
shouldReportMetricTelemetry = true;
}
}
catch
{
}

if (shouldReportMetricTelemetry && metricsData != null)
{
azureMonitorResource.MetricTelemetry = new TelemetryItem(DateTime.UtcNow, azureMonitorResource, instrumentationKey!)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Net;
using Azure.Monitor.OpenTelemetry.Exporter.Internals;
Expand Down Expand Up @@ -30,12 +31,20 @@ public void NullResource(string? instrumentationKey)
[InlineData(InstrumentationKey)]
public void DefaultResource(string? instrumentationKey)
{
var resource = CreateTestResource();
var azMonResource = resource.CreateAzureMonitorResource(instrumentationKey);
try
{
Environment.SetEnvironmentVariable("EXPORT_METRIC_FOR_RESOURCE_ATTRIBUTES", "true");
vishweshbankwar marked this conversation as resolved.
Show resolved Hide resolved
var resource = CreateTestResource();
var azMonResource = resource.CreateAzureMonitorResource(instrumentationKey);

Assert.StartsWith("unknown_service", azMonResource?.RoleName);
Assert.Equal(Dns.GetHostName(), azMonResource?.RoleInstance);
Assert.Equal(instrumentationKey != null, azMonResource?.MetricTelemetry != null);
Assert.StartsWith("unknown_service", azMonResource?.RoleName);
Assert.Equal(Dns.GetHostName(), azMonResource?.RoleInstance);
Assert.Equal(instrumentationKey != null, azMonResource?.MetricTelemetry != null);
}
finally
{
Environment.SetEnvironmentVariable("EXPORT_METRIC_FOR_RESOURCE_ATTRIBUTES", null);
}
}

[Fact]
Expand Down Expand Up @@ -185,73 +194,91 @@ public void EmptyPrefixResourceDoesNotSetSdkPrefix()
[Fact]
public void SdkPrefixIsNotInResourceMetrics()
{
// SDK version is static, preserve to clean up later.
var sdkVersion = SdkVersionUtils.s_sdkVersion;
var testAttributes = new Dictionary<string, object>
try
{
{"foo", "bar" },
{ "ai.sdk.prefix", "pre_" }
};
Environment.SetEnvironmentVariable("EXPORT_METRIC_FOR_RESOURCE_ATTRIBUTES", "true");

var resource = ResourceBuilder.CreateDefault().AddAttributes(testAttributes).Build();
var azMonResource = resource.CreateAzureMonitorResource(InstrumentationKey);
// SDK version is static, preserve to clean up later.
var sdkVersion = SdkVersionUtils.s_sdkVersion;
var testAttributes = new Dictionary<string, object>
{
{"foo", "bar" },
{ "ai.sdk.prefix", "pre_" }
};

Assert.Equal("Metric", azMonResource!.MetricTelemetry!.Name);
var resource = ResourceBuilder.CreateDefault().AddAttributes(testAttributes).Build();
var azMonResource = resource.CreateAzureMonitorResource(InstrumentationKey);

var monitorBase = azMonResource.MetricTelemetry.Data;
var metricsData = monitorBase.BaseData as MetricsData;
Assert.Equal("Metric", azMonResource!.MetricTelemetry!.Name);

var metricDataPoint = metricsData?.Metrics[0];
Assert.Equal("bar", metricsData?.Properties["foo"]);
Assert.False(metricsData?.Properties.ContainsKey("ai.sdk.prefix"));
var monitorBase = azMonResource.MetricTelemetry.Data;
var metricsData = monitorBase.BaseData as MetricsData;

// Clean up
SdkVersionUtils.s_sdkVersion = sdkVersion;
var metricDataPoint = metricsData?.Metrics[0];
Assert.Equal("bar", metricsData?.Properties["foo"]);
Assert.False(metricsData?.Properties.ContainsKey("ai.sdk.prefix"));

// Clean up
SdkVersionUtils.s_sdkVersion = sdkVersion;
}
finally
{
Environment.SetEnvironmentVariable("EXPORT_METRIC_FOR_RESOURCE_ATTRIBUTES", null);
}
}

[Theory]
[InlineData(null)]
[InlineData(InstrumentationKey)]
public void MetricTelemetryHasAllResourceAttributes(string? instrumentationKey)
{
var testAttributes = new Dictionary<string, object>
try
{
{SemanticConventions.AttributeServiceName, "my-service" },
{SemanticConventions.AttributeServiceNamespace, "my-namespace" },
{SemanticConventions.AttributeServiceInstance, "my-instance" },
{SemanticConventions.AttributeK8sDeployment, "my-deployment" },
{SemanticConventions.AttributeK8sPod, "my-pod" },
{ "foo", "bar" }
};

var resource = ResourceBuilder.CreateEmpty().AddAttributes(testAttributes).Build();
var azMonResource = resource.CreateAzureMonitorResource(instrumentationKey);

Assert.Equal(instrumentationKey != null, azMonResource?.MetricTelemetry != null);

if (instrumentationKey != null)
Environment.SetEnvironmentVariable("EXPORT_METRIC_FOR_RESOURCE_ATTRIBUTES", "true");

var testAttributes = new Dictionary<string, object>
{
{SemanticConventions.AttributeServiceName, "my-service" },
{SemanticConventions.AttributeServiceNamespace, "my-namespace" },
{SemanticConventions.AttributeServiceInstance, "my-instance" },
{SemanticConventions.AttributeK8sDeployment, "my-deployment" },
{SemanticConventions.AttributeK8sPod, "my-pod" },
{ "foo", "bar" }
};

var resource = ResourceBuilder.CreateEmpty().AddAttributes(testAttributes).Build();
var azMonResource = resource.CreateAzureMonitorResource(instrumentationKey);

Assert.Equal(instrumentationKey != null, azMonResource?.MetricTelemetry != null);

if (instrumentationKey != null)
{
Assert.Equal("Metric", azMonResource!.MetricTelemetry!.Name);
Assert.Equal(3, azMonResource.MetricTelemetry.Tags.Count);
Assert.NotNull(azMonResource.MetricTelemetry.Data);

var monitorBase = azMonResource.MetricTelemetry.Data;
var metricsData = monitorBase.BaseData as MetricsData;

Assert.NotNull(metricsData?.Metrics);

var metricDataPoint = metricsData?.Metrics[0];
Assert.Equal("_OTELRESOURCE_", metricDataPoint?.Name);
Assert.Equal(0, metricDataPoint?.Value);

Assert.Equal(6, metricsData?.Properties.Count);

Assert.Equal("my-service", metricsData?.Properties[SemanticConventions.AttributeServiceName]);
Assert.Equal("my-namespace", metricsData?.Properties[SemanticConventions.AttributeServiceNamespace]);
Assert.Equal("my-instance", metricsData?.Properties[SemanticConventions.AttributeServiceInstance]);
Assert.Equal("my-deployment", metricsData?.Properties[SemanticConventions.AttributeK8sDeployment]);
Assert.Equal("my-pod", metricsData?.Properties[SemanticConventions.AttributeK8sPod]);
Assert.Equal("bar", metricsData?.Properties["foo"]);
}
}
finally
{
Assert.Equal("Metric", azMonResource!.MetricTelemetry!.Name);
Assert.Equal(3, azMonResource.MetricTelemetry.Tags.Count);
Assert.NotNull(azMonResource.MetricTelemetry.Data);

var monitorBase = azMonResource.MetricTelemetry.Data;
var metricsData = monitorBase.BaseData as MetricsData;

Assert.NotNull(metricsData?.Metrics);

var metricDataPoint = metricsData?.Metrics[0];
Assert.Equal("_OTELRESOURCE_", metricDataPoint?.Name);
Assert.Equal(0, metricDataPoint?.Value);

Assert.Equal(6, metricsData?.Properties.Count);

Assert.Equal("my-service", metricsData?.Properties[SemanticConventions.AttributeServiceName]);
Assert.Equal("my-namespace", metricsData?.Properties[SemanticConventions.AttributeServiceNamespace]);
Assert.Equal("my-instance", metricsData?.Properties[SemanticConventions.AttributeServiceInstance]);
Assert.Equal("my-deployment", metricsData?.Properties[SemanticConventions.AttributeK8sDeployment]);
Assert.Equal("my-pod", metricsData?.Properties[SemanticConventions.AttributeK8sPod]);
Assert.Equal("bar", metricsData?.Properties["foo"]);
Environment.SetEnvironmentVariable("EXPORT_METRIC_FOR_RESOURCE_ATTRIBUTES", null);
}
}

Expand Down Expand Up @@ -312,6 +339,33 @@ public void ResourceWithEmptyKubernetesAttributes()
Assert.Equal(Dns.GetHostName(), azMonResource?.RoleInstance);
}

[Theory]
[InlineData("true")]
[InlineData("false")]
public void MetricTelemetryIsAddedToResourceBasedOnEnvVar(string envVarValue)
{
try
{
Environment.SetEnvironmentVariable("EXPORT_METRIC_FOR_RESOURCE_ATTRIBUTES", envVarValue);

var resource = ResourceBuilder.CreateDefault().Build();
var azMonResource = resource.CreateAzureMonitorResource(InstrumentationKey);

if (envVarValue == "true")
{
Assert.NotNull(azMonResource?.MetricTelemetry);
}
else
{
Assert.Null(azMonResource?.MetricTelemetry);
}
}
finally
{
Environment.SetEnvironmentVariable("EXPORT_METRIC_FOR_RESOURCE_ATTRIBUTES", null);
}
}

/// <summary>
/// If SERVICE.NAME is not defined, it will fall-back to "unknown_service".
/// (https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions#semantic-attributes-with-sdk-provided-default-value).
Expand Down