Skip to content

Msmq integration#1457

Closed
anna-git wants to merge 19 commits into
masterfrom
anna/msmq
Closed

Msmq integration#1457
anna-git wants to merge 19 commits into
masterfrom
anna/msmq

Conversation

@anna-git

Copy link
Copy Markdown
Contributor

Fixes #

Changes proposed in this pull request:

  • 3 intercepted methods
  • integration test
  • sample program

@DataDog/apm-dotnet

@anna-git
anna-git requested a review from a team as a code owner May 10, 2021 13:39

@andrewlock andrewlock left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looking good! 🙂 I left a few comments mostly around whether we want to include all of the queue details as tags for performance reasons

Comment thread src/Datadog.Trace/Tagging/MsmqTags.cs Outdated
Comment on lines +30 to +44
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; }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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:

  • QueueLabel
  • QueueLastModifiedTime
  • IsTransactionalQueue
  • UniqueQueueName (i.e. either keep formatName or queueName, depending on which is more useful!)
  • TransactionType

Additionally InstrumentationName is normally created as a readonly field in the Tags, rather than specified at creation 🙂

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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 :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You'll need to create a default constructor version of this too, as there's a unit tests that checks for its existence

Comment thread test/Datadog.Trace.ClrProfiler.IntegrationTests/MsmqTests.cs Outdated

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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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; }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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

anna-git added 2 commits May 10, 2021 17:12
- constructor msmqtags
- remove some properties
- transactional messages and queue, properties make more sense
- unused params

@kevingosse kevingosse left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great stuff 👍 Only minor changes needed

Comment thread integrations.json
}
]
},
{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please remember to re-generate this file before merging, as we are in version 1.26.3 now

Comment on lines +43 to +48

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";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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)

Comment on lines +28 to +30
private const string CommandPeek = "msmq.peek";
private const string CommandConsume = "msmq.consume";
private const string IntegrationName = nameof(IntegrationIds.Msmq);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

NIT: you could move them to MsmqConstants (same for similar constants in other integration files)

AspNetMvc,
AspNetWebApi2,
GraphQL,
Msmq,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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?

@lucaspimentel lucaspimentel May 12, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 tonyredondo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you reuse the value in MsmqConstants?


var span = scope.Span;
span.Type = SpanTypes.Queue;
span.ResourceName = command;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What will the resource name look like? I tried looking in the tests and we're not asserting that there (we probably should).

@lucaspimentel lucaspimentel May 12, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Member

@anna-git, can we close this PR in favor of #1463?

@lucaspimentel lucaspimentel added area:automatic-instrumentation Automatic instrumentation managed C# code (Datadog.Trace.ClrProfiler.Managed) type:new-feature labels May 12, 2021
@anna-git

anna-git commented May 13, 2021

Copy link
Copy Markdown
Contributor Author

@anna-git, can we close this PR in favor of #1463?

@lucaspimentel yes please thanks :)

@anna-git anna-git closed this May 14, 2021
anna-git added a commit that referenced this pull request May 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:automatic-instrumentation Automatic instrumentation managed C# code (Datadog.Trace.ClrProfiler.Managed) type:new-feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants