Skip to content

Commit

Permalink
Add new API to set a custom span name (#1238)
Browse files Browse the repository at this point in the history
* Add new API to set a custom span name.

* Changelog

* Add metric renaming for a missed segment type
  • Loading branch information
JcolemanNR authored Sep 12, 2022
1 parent ad8a975 commit a632894
Show file tree
Hide file tree
Showing 22 changed files with 255 additions and 29 deletions.
1 change: 1 addition & 0 deletions src/Agent/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Forwarded application logs now capture exception details including, error message, error stack, and error class. [#1228](https://github.com/newrelic/newrelic-dotnet-agent/pull/1228)
* Log events with no message will now be accepted if an exception is present in the log event.
* The error stack is created using the stack of the inner exception, up to 5 levels deep, just like existing Agent error reporting.
* Adds a new `SetName()` method to the Agent API for spans which allows customization of segment/span/metric names. [#1238](https://github.com/newrelic/newrelic-dotnet-agent/pull/1238)

### Fixes
* Resolves an issue where log forwarding could drop logs in async scenarios. [#1174](https://github.com/newrelic/newrelic-dotnet-agent/pull/1201)
Expand Down
18 changes: 13 additions & 5 deletions src/Agent/NewRelic.Api.Agent/ISpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@ namespace NewRelic.Api.Agent
/// </summary>
public interface ISpan
{
/// <summary> Add a key/value pair to the transaction. These are reported in errors and
/// transaction traces.</summary>
///
/// <param name="key"> The key name to add to the span attributes. Limited to 255-bytes.</param>
/// <param name="value"> The value to add to the current span. Values are limited to 255-bytes.</param>
/// <summary>
/// Add a key/value pair to the span.
/// </summary>
/// <param name="key"> The key name to add to the span attributes. Limited to 255-bytes.</param>
/// <param name="value"> The value to add to the current span. Limited to 255-bytes.</param>
/// <returns>ISpan to support builder pattern</returns>
ISpan AddCustomAttribute(string key, object value);

/// <summary>
/// Sets the name of the current span.
/// </summary>
/// <param name="name">The new name for the span.</param>
/// <returns>ISpan to support builder pattern</returns>
ISpan SetName(string name);
}
}
5 changes: 5 additions & 0 deletions src/Agent/NewRelic.Api.Agent/NoOpSpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@ public ISpan AddCustomAttribute(string key, object value)
{
return this;
}

public ISpan SetName(string name)
{
return this;
}
}
}
22 changes: 21 additions & 1 deletion src/Agent/NewRelic.Api.Agent/Span.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public ISpan AddCustomAttribute(string key, object value)
try
{
_wrappedSpan.AddCustomAttribute(key, value);
return this;
}
catch (RuntimeBinderException)
{
Expand All @@ -36,5 +35,26 @@ public ISpan AddCustomAttribute(string key, object value)

return this;
}

private static bool _isSetNameAvailable = true;

public ISpan SetName(string name)
{
if (!_isSetNameAvailable)
{
return _noOpSpan.SetName(name);
}

try
{
_wrappedSpan.SetName(name);
}
catch (RuntimeBinderException)
{
_isSetNameAvailable = false;
}

return this;
}
}
}
25 changes: 23 additions & 2 deletions src/Agent/NewRelic/Agent/Core/Api/SpanBridgeApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace NewRelic.Agent.Core.Api
{
public class SpanBridgeApi
{

private readonly ISpan _span;
private readonly IApiSupportabilityMetricCounters _apiSupportabilityMetricCounters;
private readonly IConfigurationService _configSvc;
Expand Down Expand Up @@ -44,9 +43,31 @@ public object AddCustomAttribute(string key, object value)
}
catch (Exception)
{
//Swallow the error
// Swallow the error.. nom nom
}
}

return _span;
}

public object SetName(string name)
{
try
{
_apiSupportabilityMetricCounters.Record(ApiMethod.SpanSetName);

_span.SetName(name);
}
catch (Exception ex)
{
try
{
Log.Error($"Error in SetName: {ex}");
}
catch (Exception)
{
// Swallow the error.. nom nom
}
}

return _span;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public enum ApiMethod
TransactionGetCurrentSpan = 22,
SpanAddCustomAttribute = 23,
InsertDistributedTraceHeaders = 24,
AcceptDistributedTraceHeaders = 25
AcceptDistributedTraceHeaders = 25,
SpanSetName = 26
}

public interface IApiSupportabilityMetricCounters : IOutOfBandMetricSource
Expand Down
8 changes: 7 additions & 1 deletion src/Agent/NewRelic/Agent/Core/Segments/CustomSegmentData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ public override void AddMetricStats(Segment segment, TimeSpan durationOfChildren
var duration = segment.Duration.Value;
var exclusiveDuration = TimeSpanMath.Max(TimeSpan.Zero, duration - durationOfChildren);

MetricBuilder.TryBuildCustomSegmentMetrics(Name, duration, exclusiveDuration, txStats);
var name = Name;
if (!string.IsNullOrWhiteSpace(segment.SegmentNameOverride))
{
name = segment.SegmentNameOverride;
}

MetricBuilder.TryBuildCustomSegmentMetrics(name, duration, exclusiveDuration, txStats);
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/Agent/NewRelic/Agent/Core/Segments/MethodSegmentData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,16 @@ public override void AddMetricStats(Segment segment, TimeSpan durationOfChildren
{
var duration = segment.Duration.Value;
var exclusiveDuration = TimeSpanMath.Max(TimeSpan.Zero, duration - durationOfChildren);
MetricBuilder.TryBuildMethodSegmentMetric(Type, Method, duration, exclusiveDuration, txStats);

if (!string.IsNullOrWhiteSpace(segment.SegmentNameOverride))
{
MetricBuilder.TryBuildSimpleSegmentMetric(segment.SegmentNameOverride, duration, exclusiveDuration, txStats);
}
else
{
MetricBuilder.TryBuildMethodSegmentMetric(Type, Method, duration, exclusiveDuration, txStats);
}

}
}
}
7 changes: 7 additions & 0 deletions src/Agent/NewRelic/Agent/Core/Segments/NoOpSegment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class NoOpSegment : ISegment, ISegmentExperimental, ISegmentDataState
public string UserCodeFunction { get => string.Empty; set { } }
public string UserCodeNamespace { get => string.Empty; set { } }

public string SegmentNameOverride { get; set; } = null;

public void End() { }
public void End(Exception ex) { }
public void MakeCombinable() { }
Expand All @@ -56,5 +58,10 @@ public ISpan AddCustomAttribute(string key, object value)
{
return this;
}

public ISpan SetName(string name)
{
return this;
}
}
}
18 changes: 16 additions & 2 deletions src/Agent/NewRelic/Agent/Core/Segments/Segment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public Segment(TimeSpan relativeStartTime, TimeSpan? duration, Segment segment,
UniqueId = segment.UniqueId;
ParentUniqueId = segment.ParentUniqueId;
MethodCallData = segment.MethodCallData;
SegmentNameOverride = segment.SegmentNameOverride;
_parameters = parameters;
Combinable = segment.Combinable;
IsLeaf = false;
Expand Down Expand Up @@ -225,8 +226,10 @@ public TimeSpan ExclusiveDurationOrZero
// customer code.
public string UserCodeNamespace { get; set; } = null;
public string UserCodeFunction { get; set; } = null;

private void Finish()

public string SegmentNameOverride { get; set; }

private void Finish()
{
var endTime = _transactionSegmentState.GetRelativeTime();
RelativeEndTime = endTime;
Expand Down Expand Up @@ -328,6 +331,11 @@ public void AddMetricStats(TransactionMetricStatsCollection txStats, IConfigurat

public string GetTransactionTraceName()
{
if(!string.IsNullOrWhiteSpace(SegmentNameOverride))
{
return SegmentNameOverride;
}

return Data.GetTransactionTraceName();
}

Expand Down Expand Up @@ -379,5 +387,11 @@ public ISpan AddCustomAttribute(string key, object value)

return this;
}

public ISpan SetName(string name)
{
SegmentNameOverride = name;
return this;
}
}
}
8 changes: 7 additions & 1 deletion src/Agent/NewRelic/Agent/Core/Segments/SimpleSegmentData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ public override void AddMetricStats(Segment segment, TimeSpan durationOfChildren
var duration = segment.Duration.Value;
var exclusiveDuration = TimeSpanMath.Max(TimeSpan.Zero, duration - durationOfChildren);

MetricBuilder.TryBuildSimpleSegmentMetric(Name, duration, exclusiveDuration, txStats);
var name = Name;
if (!string.IsNullOrWhiteSpace(segment.SegmentNameOverride))
{
name = segment.SegmentNameOverride;
}

MetricBuilder.TryBuildSimpleSegmentMetric(name, duration, exclusiveDuration, txStats);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ public interface ISegment : ISpan
/// </summary>
string SpanId { get; }

/// <summary>
/// Provides the ability to override a segment name. If this is anything other than null or empty,
/// then this value should be used as the segment/span name.
/// </summary>
string SegmentNameOverride { get; set; }

/// <summary>
/// Ends this transaction segment.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ namespace NewRelic.Agent.Api
public interface ISpan
{
ISpan AddCustomAttribute(string key, object value);

ISpan SetName(string name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NewRelic.Agent.Api" Version="8.41.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Shared\Shared.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<AssemblyName>NewRelic.Agent.IntegrationTestHelpers</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NewRelic.Agent.Api" Version="8.41.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="xunit" version="2.4.0" />
Expand Down
9 changes: 9 additions & 0 deletions tests/Agent/IntegrationTests/IntegrationTests.sln
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleMultiFunctionApplicationCore", "SharedApplications\ConsoleMultiFunctionApplicationCore\ConsoleMultiFunctionApplicationCore.csproj", "{4213F281-732C-4447-B347-1C46E3609986}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultiFunctionApplicationHelpers", "SharedApplications\Common\MultiFunctionApplicationHelpers\MultiFunctionApplicationHelpers.csproj", "{882747A5-5B57-4AD9-B209-D1F03A657DB9}"
ProjectSection(ProjectDependencies) = postProject
{B187563A-795B-4C70-A525-6470B88AD341} = {B187563A-795B-4C70-A525-6470B88AD341}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCoreMvcCoreFrameworkApplication", "Applications\AspNetCoreMvcCoreFrameworkApplication\AspNetCoreMvcCoreFrameworkApplication.csproj", "{63EC546C-650D-4CF4-94C4-A350D1D491FD}"
EndProject
Expand All @@ -131,6 +134,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore5BasicWebApiAppli
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore6BasicWebApiApplication", "Applications\AspNetCore6BasicWebApiApplication\AspNetCore6BasicWebApiApplication.csproj", "{66138A9F-0B28-4CB3-9DF9-D22C19641043}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NewRelic.Api.Agent", "..\..\..\src\Agent\NewRelic.Api.Agent\NewRelic.Api.Agent.csproj", "{B187563A-795B-4C70-A525-6470B88AD341}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -349,6 +354,10 @@ Global
{66138A9F-0B28-4CB3-9DF9-D22C19641043}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66138A9F-0B28-4CB3-9DF9-D22C19641043}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66138A9F-0B28-4CB3-9DF9-D22C19641043}.Release|Any CPU.Build.0 = Release|Any CPU
{B187563A-795B-4C70-A525-6470B88AD341}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B187563A-795B-4C70-A525-6470B88AD341}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B187563A-795B-4C70-A525-6470B88AD341}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B187563A-795B-4C70-A525-6470B88AD341}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit a632894

Please sign in to comment.