Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
tippmar-nr committed Jul 16, 2024
1 parent a08b0e9 commit 6eb3026
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public interface IAttributeDefinitions
AttributeDefinition<TypeAttributeValue, string> GetTypeAttribute(TypeAttributeValue destination);

AttributeDefinition<bool, bool> LlmTransaction { get; }

public AttributeDefinition<string, string> CloudAccountId { get; }
public AttributeDefinition<string, string> CloudRegion { get; }
public AttributeDefinition<string, string> MessagingSystemName { get; }
AttributeDefinition<string, string> MessagingDesignationName { get; }
}


Expand Down Expand Up @@ -177,7 +182,7 @@ public AttributeDefinitions(IAttributeFilter attribFilter)
private readonly ConcurrentDictionary<string, AttributeDefinition<string, string>> _requestParameterAttributes = new ConcurrentDictionary<string, AttributeDefinition<string, string>>();
private readonly ConcurrentDictionary<string, AttributeDefinition<string, string>> _requestHeadersAttributes = new ConcurrentDictionary<string, AttributeDefinition<string, string>>();
private readonly ConcurrentDictionary<string, AttributeDefinition<object, object>> _lambdaAttributes = new ConcurrentDictionary<string, AttributeDefinition<object, object>>();

private readonly ConcurrentDictionary<TypeAttributeValue, AttributeDefinition<TypeAttributeValue, string>> _typeAttributes = new ConcurrentDictionary<TypeAttributeValue, AttributeDefinition<TypeAttributeValue, string>>();


Expand Down Expand Up @@ -1079,5 +1084,33 @@ private static string IgnoreEmptyAndWhitespaceErrorGroupValues(string errorGroup
.AppliesTo(AttributeDestinations.TransactionEvent)
.AppliesTo(AttributeDestinations.TransactionTrace)
.Build(_attribFilter));

private AttributeDefinition<string, string> _cloudAccountId;
public AttributeDefinition<string, string> CloudAccountId => _cloudAccountId ?? (_cloudAccountId =
AttributeDefinitionBuilder.CreateString("cloud.account.id", AttributeClassification.AgentAttributes)
.AppliesTo(AttributeDestinations.SpanEvent)
.AppliesTo(AttributeDestinations.TransactionTrace)
.Build(_attribFilter));

private AttributeDefinition<string, string> _cloudRegion;
public AttributeDefinition<string, string> CloudRegion => _cloudRegion ?? (_cloudRegion =
AttributeDefinitionBuilder.CreateString("cloud.region", AttributeClassification.AgentAttributes)
.AppliesTo(AttributeDestinations.SpanEvent)
.AppliesTo(AttributeDestinations.TransactionTrace)
.Build(_attribFilter));

private AttributeDefinition<string, string> _messagingSystem;
public AttributeDefinition<string, string> MessagingSystemName => _messagingSystem ?? (_messagingSystem =
AttributeDefinitionBuilder.CreateString("messaging.system", AttributeClassification.AgentAttributes)
.AppliesTo(AttributeDestinations.SpanEvent)
.AppliesTo(AttributeDestinations.TransactionTrace)
.Build(_attribFilter));

private AttributeDefinition<string, string> _messagingDestinationName;
public AttributeDefinition<string, string> MessagingDesignationName => _messagingDestinationName ?? (_messagingDestinationName =
AttributeDefinitionBuilder.CreateString("messaging.destination.name", AttributeClassification.AgentAttributes)
.AppliesTo(AttributeDestinations.SpanEvent)
.AppliesTo(AttributeDestinations.TransactionTrace)
.Build(_attribFilter));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,26 @@ public class MessageBrokerSegmentData : AbstractSegmentData

public MetricNames.MessageBrokerAction Action { get; set; }

public string MessagingSystemName {get; set;}
public string CloudAccountId {get; set;}
public string CloudRegion {get; set;}

public MessageBrokerSegmentData(string vendor, string destination, MetricNames.MessageBrokerDestinationType destinationType, MetricNames.MessageBrokerAction action)


public MessageBrokerSegmentData(string vendor, string destination, MetricNames.MessageBrokerDestinationType destinationType, MetricNames.MessageBrokerAction action, string messagingSystemName = null, string cloudAccountId = null, string cloudRegion = null)
{
Vendor = vendor;
Destination = destination;
DestinationType = destinationType;
Action = action;

// attributes required for entity relationship mapping
MessagingSystemName = messagingSystemName;
CloudAccountId = cloudAccountId;
CloudRegion = cloudRegion;
}


public override bool IsCombinableWith(AbstractSegmentData otherData)
{
var otherTypedSegment = otherData as MessageBrokerSegmentData;
Expand All @@ -51,6 +62,15 @@ public override bool IsCombinableWith(AbstractSegmentData otherData)
if (Action != otherTypedSegment.Action)
return false;

if (MessagingSystemName != otherTypedSegment.MessagingSystemName)
return false;

if (CloudAccountId != otherTypedSegment.CloudAccountId)
return false;

if (CloudRegion != otherTypedSegment.CloudRegion)
return false;

return true;
}

Expand All @@ -65,7 +85,14 @@ public override void AddMetricStats(Segment segment, TimeSpan durationOfChildren
var exclusiveDuration = TimeSpanMath.Max(TimeSpan.Zero, duration - durationOfChildren);

MetricBuilder.TryBuildMessageBrokerSegmentMetric(Vendor, Destination, DestinationType, Action, duration, exclusiveDuration, txStats);
}

public override void SetSpanTypeSpecificAttributes(SpanAttributeValueCollection attribVals)
{
AttribDefs.MessagingSystemName.TrySetValue(attribVals, MessagingSystemName);
AttribDefs.MessagingDesignationName.TrySetValue(attribVals, Destination);
AttribDefs.CloudRegion.TrySetValue(attribVals, CloudRegion);
AttribDefs.CloudAccountId.TrySetValue(attribVals, CloudAccountId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ public ISegment StartExternalRequestSegment(MethodCall methodCall, Uri destinati
return Segment.NoOpSegment;
}

public ISegment StartMessageBrokerSegment(MethodCall methodCall, MessageBrokerDestinationType destinationType, MessageBrokerAction operation, string brokerVendorName, string destinationName)
public ISegment StartMessageBrokerSegment(MethodCall methodCall, MessageBrokerDestinationType destinationType,
MessageBrokerAction operation, string brokerVendorName, string destinationName,
string messagingSystemName = null, string cloudAccountId = null,
string cloudRegion = null)
{
#if DEBUG
Log.Finest("Skipping StartMessageBrokerSegment outside of a transaction");
Expand Down
15 changes: 9 additions & 6 deletions src/Agent/NewRelic/Agent/Core/Transactions/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,10 @@ public AbstractSegmentData CreateCustomSegmentData(string segmentName)
return new CustomSegmentData(segmentName);
}

public ISegment StartMessageBrokerSegment(MethodCall methodCall, MessageBrokerDestinationType destinationType, MessageBrokerAction operation, string brokerVendorName, string destinationName)
public ISegment StartMessageBrokerSegment(MethodCall methodCall, MessageBrokerDestinationType destinationType,
MessageBrokerAction operation, string brokerVendorName, string destinationName,
string messagingSystemName = null, string cloudAccountId = null,
string cloudRegion = null)
{
if (Ignored)
return Segment.NoOpSegment;
Expand All @@ -252,7 +255,7 @@ public ISegment StartMessageBrokerSegment(MethodCall methodCall, MessageBrokerDe


var segment = StartSegmentImpl(methodCall);
var messageBrokerSegmentData = CreateMessageBrokerSegmentData(destinationType, operation, brokerVendorName, destinationName);
var messageBrokerSegmentData = CreateMessageBrokerSegmentData(destinationType, operation, brokerVendorName, destinationName, messagingSystemName: messagingSystemName, cloudAccountId: cloudAccountId, cloudRegion: cloudRegion);

segment.SetSegmentData(messageBrokerSegmentData);

Expand Down Expand Up @@ -281,15 +284,15 @@ public ISegment StartMessageBrokerSerializationSegment(MethodCall methodCall, Me
return segment;
}

public AbstractSegmentData CreateMessageBrokerSegmentData(MessageBrokerDestinationType destinationType, MessageBrokerAction operation, string brokerVendorName, string destinationName)
public AbstractSegmentData CreateMessageBrokerSegmentData(MessageBrokerDestinationType destinationType, MessageBrokerAction operation, string brokerVendorName, string destinationName, string messagingSystemName = null, string cloudAccountId = null, string cloudRegion = null)
{
if (brokerVendorName == null)
throw new ArgumentNullException("brokerVendorName");

var action = AgentWrapperApiEnumToMetricNamesEnum(operation);
var destType = AgentWrapperApiEnumToMetricNamesEnum(destinationType);

return new MessageBrokerSegmentData(brokerVendorName, destinationName, destType, action);
return new MessageBrokerSegmentData(brokerVendorName, destinationName, destType, action, messagingSystemName: messagingSystemName, cloudAccountId: cloudAccountId, cloudRegion: cloudRegion);
}

public AbstractSegmentData CreateMessageBrokerSerializationSegmentData(MessageBrokerDestinationType destinationType, MessageBrokerAction operation, string brokerVendorName, string destinationName, string kind)
Expand Down Expand Up @@ -784,7 +787,7 @@ public void Hold()

public void Release()
{
End(captureResponseTime: false);
End(false);
}

private void SetTransactionName(ITransactionName transactionName, TransactionNamePriority priority)
Expand Down Expand Up @@ -1364,7 +1367,7 @@ public void SetLlmTransaction(bool isLlmTransaction)
/// <param name="value">Value for attribute.</param>
public void AddLambdaAttribute(string name, object value)
{
if(string.IsNullOrWhiteSpace(name))
if (string.IsNullOrWhiteSpace(name))
{
Log.Debug($"AddLambdaAttribute - Unable to set Lambda value on transaction because the key is null/empty");
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,15 @@ public interface ITransaction
/// <param name="operation"></param>
/// <param name="brokerVendorName">Must not be null.</param>
/// <param name="destinationName">Can be null.</param>
/// <param name="messagingSystemName"></param>
/// <param name="cloudAccountId"></param>
/// <param name="cloudRegion"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns>an opaque object that will be needed when you want to end the segment.</returns>
ISegment StartMessageBrokerSegment(MethodCall methodCall, MessageBrokerDestinationType destinationType, MessageBrokerAction operation, string brokerVendorName, string destinationName = null);
ISegment StartMessageBrokerSegment(MethodCall methodCall, MessageBrokerDestinationType destinationType,
MessageBrokerAction operation, string brokerVendorName, string destinationName = null,
string messagingSystemName = null, string cloudAccountId = null,
string cloudRegion = null);

/// <summary>
/// Creates a segment for serializing a key or value in a message brokering system..
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ public static class SqsHelper
private static ConcurrentDictionary<Type, Func<object, IDictionary>> _getMessageAttributes = new();
private static Func<object> _messageAttributeValueTypeFactory;

public const string MessagingSystemName = "aws_sqs";
public const string VendorName = "SQS";

private class SqsAttributes
{
public string QueueName { get; }
public string CloudId { get; }
public string Region { get; }
public string ServerAddress { get; }

// https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue
public SqsAttributes(string url)
Expand All @@ -51,12 +53,16 @@ public SqsAttributes(string url)

// subdomain[0] should always be "sqs"
Region = subdomain[1];

ServerAddress = new Uri(url).Host;
}
}

public static ISegment GenerateSegment(ITransaction transaction, MethodCall methodCall, string url, MessageBrokerAction action)
{
var attr = new SqsAttributes(url);
var segment = transaction.StartMessageBrokerSegment(methodCall, MessageBrokerDestinationType.Queue, action, VendorName, attr.QueueName);

var segment = transaction.StartMessageBrokerSegment(methodCall, MessageBrokerDestinationType.Queue, action, VendorName, destinationName: attr.QueueName, messagingSystemName: MessagingSystemName, cloudAccountId: attr.CloudId, cloudRegion: attr.Region);
segment.GetExperimentalApi().MakeLeaf();

return segment;
Expand All @@ -71,7 +77,7 @@ public static void InsertDistributedTraceHeaders(ITransaction transaction, objec

var setHeaders = new Action<object, string, string>((smr, key, value) =>
{
var getMessageAttributes = _getMessageAttributes.GetOrAdd(smr.GetType(), t => VisibilityBypasser.Instance.GeneratePropertyAccessor<IDictionary>(t, "MessageAttributes"));
var getMessageAttributes = _getMessageAttributes.GetOrAdd(smr.GetType(), t => VisibilityBypasser.Instance.GeneratePropertyAccessor<IDictionary>(t, "MessageAttributes"));
var messageAttributes = getMessageAttributes(smr);

// if we can't add all DT headers, don't add any
Expand Down

0 comments on commit 6eb3026

Please sign in to comment.