NServiceBus + Elastic APM

Hi,

I just wondered if anyone has got Elastic APM working on an NServiceBus endpoint?

I have NSB running on Azure web apps and I’ve installed the Elastic APM agent. It’s supposed to log all dependencies such as Azure SQL and Redis. It logs the receipt of the incoming message but nothing else.It works fine on my APIs just not on the messaging apps.

The only thing I can think of is that it’s something to do with the dependency injection, which I use autofac for.

Thanks

Rob

Hi @robgardner

I am not familiar with Elastic APM. I know NewRelic logs a ton of stuff without doing anything, but you specifically mention dependency injection. Do you mean that it doesn’t log anything after NServiceBus picks it up? What is “it logs the receipt of the incoming message”? With the information you’re providing us, it’s hard to figure out what is going on and if this is an issue with us or Elastic APM. Perhaps you can create a reproduction of the issue or if that requires too much Elastic APM infrastructure, provide more information.

We have several samples on how one can do logging/tracing with other libraries, maybe those can be of help: Logging and Metrics Samples • NServiceBus • Particular Docs

Hi Dennis,

I got the response below from Elastic. It looks like it’s just down to the way that NServiceBus works.

Also for completeness: we got another reproducer with NServiceBus over Azure ServiceBus where the current transaction was null within an IHandleMessages implementation. I think this is from @gardnerr, but maybe I’m wrong - I’ll also reach out through other channels. I debugged through this and this is an NServiceBus related issue: the underlaying Azure ServiceBus library sends a .Stop event before the IHandleMessages implementation is called and this causes the agent to end the transaction before the IHandleMessages implementation runs. So this is kind of an unfortunate combination. We don’t support NServiceBus directly, we support the underlaying Azure ServiceBus library and the way NServiceBus runs its message handlers (specifically the IHandleMessages implementations) is that those run after the reading from Azure ServiceBus is alrerady closed. I think for this to work out of the box, we’d need specific support for NServiceBus.

Rob:

Out of the box, NServiceBus isn’t compatible with Elastic APM.

The good news is, from what I can tell, we have the extensibility points available to make it so.

First NServiceBus needs to publish System.Diagnostics events. Fortunately one of our Champs @jbogard has created a package called NServiceBus.Extensions.Diagnostics that does just that.

The package raises events around the different stages of the NServiceBus pipeline. Unfortunately, the exact events are not documented, but looking at the source the one associated with the invoke handlers stage is NServiceBus.Extensions.Diagnostics.InvokedHandler.Processed.

The second part is harder. You would need Elastic APM listeners to listen to those specific events and capture them.

To do that you would have to create those listeners using the Elastic APM public API for .NET. You could use the listeners included in the Elastic APM .NET agent as examples to get you going. You would even see the ServiceBus listener in that source.

Undocumented?? That doesn’t sound like me at all!!

1 Like

Another option is to plug in to OpenTelemetry - Elastic has a provider (and so does NSB with my package) so those should work together just fine. That way you’re not writing Elastic extensions, just working with plain System.Diagnostics ones.

1 Like

Thanks Jimmy / Bob,

I’ve implemented this as a couple of pipeline behaviours which plug into a class based on Elastic’s MicrosoftAzureServiceBusDiagnosticListener. It ended up being hardly any code at all. I will look into the other options suggested though - no matter what you do, there’s always a cleaner way of doing things :grinning: