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

[Performance] added SpanAttributes.Add(string,object) method for deferred string-ification #4672

Closed
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,4 @@ OpenTelemetry.Logs.LogRecordSeverityExtensions
static OpenTelemetry.Logs.LogRecordAttributeList.CreateFromEnumerable(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string!, object?>>! attributes) -> OpenTelemetry.Logs.LogRecordAttributeList
static OpenTelemetry.Logs.LogRecordSeverityExtensions.ToShortName(this OpenTelemetry.Logs.LogRecordSeverity logRecordSeverity) -> string!
virtual OpenTelemetry.Logs.LoggerProvider.TryCreateLogger(string? name, out OpenTelemetry.Logs.Logger? logger) -> bool
~OpenTelemetry.Trace.SpanAttributes.Add(string key, object value) -> void
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ virtual OpenTelemetry.Logs.LoggerProvider.TryCreateLogger(string? name, out Open
~OpenTelemetry.Trace.SpanAttributes.Add(string key, double[] values) -> void
~OpenTelemetry.Trace.SpanAttributes.Add(string key, long value) -> void
~OpenTelemetry.Trace.SpanAttributes.Add(string key, long[] values) -> void
~OpenTelemetry.Trace.SpanAttributes.Add(string key, object value) -> void
~OpenTelemetry.Trace.SpanAttributes.Add(string key, string value) -> void
~OpenTelemetry.Trace.SpanAttributes.Add(string key, string[] values) -> void
~OpenTelemetry.Trace.SpanAttributes.SpanAttributes(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object>> attributes) -> void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,4 @@ OpenTelemetry.Logs.LogRecordSeverityExtensions
static OpenTelemetry.Logs.LogRecordAttributeList.CreateFromEnumerable(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string!, object?>>! attributes) -> OpenTelemetry.Logs.LogRecordAttributeList
static OpenTelemetry.Logs.LogRecordSeverityExtensions.ToShortName(this OpenTelemetry.Logs.LogRecordSeverity logRecordSeverity) -> string!
virtual OpenTelemetry.Logs.LoggerProvider.TryCreateLogger(string? name, out OpenTelemetry.Logs.Logger? logger) -> bool
~OpenTelemetry.Trace.SpanAttributes.Add(string key, object value) -> void
10 changes: 10 additions & 0 deletions src/OpenTelemetry.Api/Trace/SpanAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ public void Add(string key, double[] values)
this.AddInternal(key, values);
}

/// <summary>
/// Add entry to the attributes.
/// </summary>
/// <param name="key">Entry key.</param>
/// <param name="value">Entry value.</param>
public void Add(string key, object value)
Copy link
Member

Choose a reason for hiding this comment

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

what is the use case for this? Though Activity allow object type, OTel only allows a specific set of types here, which is already supported in this class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In this case, it was to be able to have an object rendered into a string out of band with the hot path being traced. I'm on mobile now so I can't provide a code sample, but you can already accomplish this by passing an IEnumerable of KV<string,object> into the constructor.

Exposing this method eliminates the need to do that and writes to the underlying collection.

Copy link
Member

Choose a reason for hiding this comment

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

Having looked at the spec, it doesn't preclude SDKs from having this method, just that the others MUST exist. I don't see a reason that the .NET SDK can't have extra stuff that isn't in the base spec?

Copy link
Contributor

@utpilla utpilla Jul 26, 2023

Choose a reason for hiding this comment

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

I don't think we should be adding this overload for the following reasons:

  1. You don't need a new API to defer the ToString() call. You should be able to use the existing SpanAttributes ctor that takes in an IEnumerable<KeyValuePair<string, object>> to directly pass in a complex type. Could you talk more about why this option wouldn't work for you?
  2. Just because .NET's Activity API deviates from the spec by allowing an arbitrary object as an attribute value, doesn't mean we should give up on keeping the Span and related APIs conform to the spec.
  3. What's the amount of perf improvement expected by this? Does the magnitude of perf improvement justify adding the new public API?

{
this.AddInternal(key, value);
}

private void AddInternal(string key, object value)
{
Guard.ThrowIfNull(key);
Expand Down
4 changes: 3 additions & 1 deletion test/OpenTelemetry.Api.Tests/Trace/SpanAttributesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ public void ValidateAddMethods()
spanAttribute.Add("key_long", 1);
spanAttribute.Add("key_a_long", new long[] { 1 });

Assert.Equal(8, spanAttribute.Attributes.Count);
spanAttribute.Add("key_object", new object());

Assert.Equal(9, spanAttribute.Attributes.Count);
}

[Fact]
Expand Down
Loading