Conversation
needs some more checks
needs some more checks
andrewlock
left a comment
There was a problem hiding this comment.
Looking good! 🙂 I left a few comments mostly around whether we want to include all of the queue details as tags for performance reasons
| public override string SpanKind { get; } | ||
|
|
||
| public string Queue { get; set; } | ||
|
|
||
| public string QueueLabel { get; set; } | ||
|
|
||
| public string QueueLastModifiedTime { get; set; } | ||
|
|
||
| public string UniqueQueueName { get; set; } | ||
|
|
||
| public string TransactionType { get; set; } | ||
|
|
||
| public string IsTransactionalQueue { get; set; } | ||
|
|
||
| public string InstrumentationName { get; set; } |
There was a problem hiding this comment.
This is a lot of tags, do we definitely want them all? I've learnt (the hard way!) that each tag has a significant performance impact! IMO, we could probably lose:
QueueLabelQueueLastModifiedTimeIsTransactionalQueueUniqueQueueName(i.e. either keepformatNameorqueueName, depending on which is more useful!)TransactionType
Additionally InstrumentationName is normally created as a readonly field in the Tags, rather than specified at creation 🙂
There was a problem hiding this comment.
Tacking onto this, as a user of MSMQ, I would find these types of things useful:
- Queue name
- Path
- Address
As they would allow me to identify the queue, and any other information can be uncovered by knowing the unique queue.
There was a problem hiding this comment.
Oh ok good to know! will remove those and keep format which gives the host info.
In msmq, if we send a message within a transaction to a non transactional queue, or the opposite, sending a message outside of a transaction context to a transactional queue, the message is never sent but the methods are called and nothing crashes, which is kind of an odd behavior I got stuck on. So I thought it might be useful to a customer to see, in the operation msmq.send, for example:
is_transactional_queue > False
transaction_type> Single (there is Auto, None, Single)
but it's just a remark, I'm not sure of their requirements here :)
There was a problem hiding this comment.
Tacking onto this, as a user of MSMQ, I would find these types of things useful:
- Queue name
- Path
- Address
As they would allow me to identify the queue, and any other information can be uncovered by knowing the unique queue.
@colin-higgins I dont see any Address property, you mean MulticastAddress property only available from from Msmq 3.0 ?
Otherwise queue and path might be enough?
for ex
Path: .\Private$\private-nontransactional-queue
Unique name : DIRECT=OS:desktop-duevvft\Private$\private-nontransactional-queue
There was a problem hiding this comment.
If unique name includes Path (as it seems to from that example), then that will probably be sufficient IMO. (Spoken as someone that has never used MSMQ!)
| /// Initializes a new instance of the <see cref="MsmqTags"/> class. | ||
| /// </summary> | ||
| /// <param name="spanKind">kind of span</param> | ||
| public MsmqTags(string spanKind) => SpanKind = spanKind; |
There was a problem hiding this comment.
You'll need to create a default constructor version of this too, as there's a unit tests that checks for its existence
|
|
||
| private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(MsmqCommon)); | ||
|
|
||
| internal static Scope CreateScope(Tracer tracer, string command, string spanKind, string queueName, string formatName, string queueLabel, DateTime queueLastModifiedTime, bool withinTransaction, string transactionType, bool transactionalQueue, out MsmqTags tags) |
There was a problem hiding this comment.
This is a matter of preference, but could we pass an IMessageQueue in here instead of the strings? Also I don't think the out parameter is used anywhere?
| /// Returns: | ||
| /// true to create and use a connection cache; otherwise, false. | ||
| /// </summary> | ||
| bool EnableConnectionCache { get; } |
There was a problem hiding this comment.
I don't think all of these properties are used in the integration? We have to generate code for each extra property, so AFAIK it's best to only specify the properties you actually need
kevingosse
left a comment
There was a problem hiding this comment.
Great stuff 👍 Only minor changes needed
| } | ||
| ] | ||
| }, | ||
| { |
There was a problem hiding this comment.
Please remember to re-generate this file before merging, as we are in version 1.26.3 now
|
|
||
| public const string MsmqCursorHandle = "System.Messaging.Interop.CursorHandle"; | ||
| public const string MsmqMessageQueueTransaction = "System.Messaging.MessageQueueTransaction"; | ||
| public const string MsmqMessageQueueTransactionType = "System.Messaging.MessageQueueTransactionType"; | ||
| public const string MsmqMessagePropertyFilter = "System.Messaging.MessagePropertyFilter"; | ||
| public const string MsmqMessage = "System.Messaging.Message"; |
There was a problem hiding this comment.
As much as possible, we should put in ClrNames only base types that may be useful for other integrations. For the MSMQ ones, you should declare them in the same folder as the integration (for instance in MsmqConstants)
| private const string CommandPeek = "msmq.peek"; | ||
| private const string CommandConsume = "msmq.consume"; | ||
| private const string IntegrationName = nameof(IntegrationIds.Msmq); |
There was a problem hiding this comment.
NIT: you could move them to MsmqConstants (same for similar constants in other integration files)
| AspNetMvc, | ||
| AspNetWebApi2, | ||
| GraphQL, | ||
| Msmq, |
There was a problem hiding this comment.
I don't think it would cause any version conflict, but I'd feel safer if you declared it last, so that the numerical id of the existing integrations don't change
|
|
||
| public string InstrumentationName => "msmq"; | ||
|
|
||
| public string IsTransactionalQueue { get; set; } |
There was a problem hiding this comment.
I wonder if metrics would be a better storage than string for boolean value... I don't know if we have booleans elsewhere. @lucaspimentel thoughts?
There was a problem hiding this comment.
What's the purpose of this value? If we want to display it in the UI, it needs to be a span tag. We don't display span "metrics" in the UI.
| { | ||
| public class Program | ||
| { | ||
| const string PrivateTransactionalQueuePath = ".\\Private$\\private-transactional-queue"; |
There was a problem hiding this comment.
I'm curious to see if that will work in the CI agent. That would be a pleasant surprise if the MSMQ service is activated.
tonyredondo
left a comment
There was a problem hiding this comment.
Looking good so far!, I've just left a couple of comments performance related.
|
|
||
| private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(MsmqCommon)); | ||
|
|
||
| internal static Scope CreateScope(Tracer tracer, string command, string spanKind, IMessageQueue messageQueue, bool? messagePartofTransaction = null) |
There was a problem hiding this comment.
If we use IMessageQueue as parameter then the proxy struct will be boxed. You can use the generic constraint as in the integration.
| { | ||
| internal class MsmqCommon | ||
| { | ||
| internal const string IntegrationName = nameof(IntegrationIds.Msmq); |
There was a problem hiding this comment.
Can you reuse the value in MsmqConstants?
| public class MessageQueue_Purge_Integration | ||
| { | ||
| private const string Command = "msmq.purge"; | ||
| private const string IntegrationName = nameof(IntegrationIds.Msmq); |
There was a problem hiding this comment.
Can you reuse the value in MsmqConstants.IntegrationName? Consider also moving "msmq.purge" there.
| IntegrationName = IntegrationName)] | ||
| public class MessageQueue_SendInternal_Integration | ||
| { | ||
| private const string IntegrationName = nameof(IntegrationIds.Msmq); |
There was a problem hiding this comment.
Can you reuse the value in MsmqConstants?
|
|
||
| var span = scope.Span; | ||
| span.Type = SpanTypes.Queue; | ||
| span.ResourceName = command; |
There was a problem hiding this comment.
What will the resource name look like? I tried looking in the tests and we're not asserting that there (we probably should).
There was a problem hiding this comment.
If users are sending messages to different queues, we want those grouped by queue name in the UI. Should we append the Path to the current resource name?. Something like {command} {path}. Similar to http requests which use {verb} {path} (e.g. GET /users/edit/{id}).
|
@lucaspimentel yes please thanks :) |
) * msmq integration Co-authored-by: anna-git <anna,[email protected]>
Fixes #
Changes proposed in this pull request:
@DataDog/apm-dotnet