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

Resource Attributes allow Primitive Arrays #1852

Merged
merged 13 commits into from
Mar 4, 2021
1 change: 1 addition & 0 deletions src/OpenTelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ please check the latest changes
## Unreleased

* Added `ForceFlush` to `TracerProvider`. ([#1837](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1837))
* Resource Attributes can take primitive arrays as values now ([#1852](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1852))

## 1.0.1

Expand Down
10 changes: 7 additions & 3 deletions src/OpenTelemetry/Resources/Resource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ private static KeyValuePair<string, object> SanitizeAttribute(KeyValuePair<strin
string sanitizedKey;
if (attribute.Key == null)
{
OpenTelemetrySdkEventSource.Log.InvalidArgument("Create resource", "attribute key", "Attribute key should be non-null string.");
sanitizedKey = string.Empty;
throw new System.ArgumentException("Resource's attributes contains a null key");
Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

The message might be misleading since it is talking about "attributes on the resource" but the method is only focusing on one attribute.
One possible way is to put something like nameof(attribute) has a null key here.

Copy link
Member Author

Choose a reason for hiding this comment

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

I might be misunderstanding but each attribute is just a key and value, so a null key makes it impossible to do that right? I could print the Value instead since Key is null, but it may also be null and would then require checking and formatting

Copy link
Member Author

Choose a reason for hiding this comment

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

Found out C# prevents you from instantiating any dictionary where the key is null, it'll throw its own ArgumentNullException. Might be the reason we originally didn't check for key == null, and I'm happy to just remove this change if that makes sense.

}
else
{
Expand All @@ -109,7 +108,12 @@ private static object SanitizeValue(object value, string keyName)
{
if (value != null)
{
if (value is string || value is bool || value is long || value is double)
if (value is string || value is bool || value is double || value is long)
cijothomas marked this conversation as resolved.
Show resolved Hide resolved
{
return value;
}

if (value is string[] || value is bool[] || value is double[] || value is long[])
Austin-Tan marked this conversation as resolved.
Show resolved Hide resolved
{
return value;
}
Expand Down
33 changes: 30 additions & 3 deletions test/OpenTelemetry.Tests/Resources/ResourceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ public void CreateResource_EmptyAttributeValue()
Assert.Contains(new KeyValuePair<string, object>("EmptyValue", string.Empty), resource.Attributes);
}

[Fact]
public void CreateResource_EmptyArray()
{
// Arrange
var attributes = new Dictionary<string, object> { { "EmptyArray", new string[0] } };

// does not throw
var resource = new Resource(attributes);

// Assert
Assert.Single(resource.Attributes);
Assert.Equal(new string[0], resource.Attributes.Where<KeyValuePair<string, object>>(x => x.Key == "EmptyArray").FirstOrDefault().Value);
}

[Fact]
public void CreateResource_EmptyAttribute()
{
Expand Down Expand Up @@ -129,28 +143,41 @@ public void CreateResource_SupportedAttributeTypes()
var attributes = new Dictionary<string, object>
{
{ "string", "stringValue" },
{ "long", 1L },
{ "bool", true },
{ "double", 0.1d },
{ "long", 1L },

// int and float supported by conversion to long and double
{ "int", 1 },
Austin-Tan marked this conversation as resolved.
Show resolved Hide resolved
{ "short", (short)1 },
{ "float", 0.1f },

// primitive array types supported
{ "string arr", new string[] { "stringValue" } },
{ "bool arr", new bool[] { true } },
{ "double arr", new double[] { 0.1d } },
{ "long arr", new long[] { 1L } },
};

var resource = new Resource(attributes);

Assert.Equal(7, resource.Attributes.Count());
Assert.Equal(11, resource.Attributes.Count());
Assert.Contains(new KeyValuePair<string, object>("string", "stringValue"), resource.Attributes);
Assert.Contains(new KeyValuePair<string, object>("long", 1L), resource.Attributes);
Assert.Contains(new KeyValuePair<string, object>("bool", true), resource.Attributes);
Assert.Contains(new KeyValuePair<string, object>("double", 0.1d), resource.Attributes);
Assert.Contains(new KeyValuePair<string, object>("long", 1L), resource.Attributes);

Assert.Contains(new KeyValuePair<string, object>("int", 1L), resource.Attributes);
Assert.Contains(new KeyValuePair<string, object>("short", 1L), resource.Attributes);

double convertedFloat = Convert.ToDouble(0.1f, System.Globalization.CultureInfo.InvariantCulture);
Assert.Contains(new KeyValuePair<string, object>("float", convertedFloat), resource.Attributes);

var toCheckArray = new KeyValuePair<string, object>("string arr", new string[] { "stringValue" });
Assert.Equal(new string[] { "stringValue" }, resource.Attributes.Where<KeyValuePair<string, object>>(x => x.Key == "string arr").FirstOrDefault().Value);
Assert.Equal(new bool[] { true }, resource.Attributes.Where<KeyValuePair<string, object>>(x => x.Key == "bool arr").FirstOrDefault().Value);
Assert.Equal(new double[] { 0.1d }, resource.Attributes.Where<KeyValuePair<string, object>>(x => x.Key == "double arr").FirstOrDefault().Value);
Assert.Equal(new long[] { 1L }, resource.Attributes.Where<KeyValuePair<string, object>>(x => x.Key == "long arr").FirstOrDefault().Value);
}

[Fact]
Expand Down