Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore persistent SignalR connections in New Relic

Where should I call NewRelic.Api.Agent.NewRelic.IgnoreApdex() or NewRelic.Api.Agent.NewRelic.IgnoreTransaction() in my SignalR hubs to prevent long-running persistent connections from overshadowing my application monitoring logs?

New Relic Screenshot of SignalR dominating monitoring

like image 763
Petrus Theron Avatar asked Nov 21 '12 09:11

Petrus Theron


2 Answers

To continue with Micah's answer, here is the custom instrumentation file for ignoring all signalr calls.

Create it to C:\ProgramData\New Relic.NET Agent\Extensions\IgnoreSignalR.xml

<?xml version="1.0" encoding="utf-8"?> <extension xmlns="urn:newrelic-extension">     <instrumentation>          <!-- Optional for basic traces. -->         <tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.IgnoreTransactionTracerFactory">             <match assemblyName="Microsoft.AspNet.SignalR.Core" className="Microsoft.AspNet.SignalR.PersistentConnection">                 <exactMethodMatcher methodName="ProcessRequest"/>             </match>         </tracerFactory>     </instrumentation> </extension> 

Remember to do iisreset.

like image 109
Juho Rutila Avatar answered Sep 26 '22 03:09

Juho Rutila


Oooh, great question and one I hadn't thought about yet myself. I think what you would have to do is write a custom module, since modules execute before all handlers, that detect that the SignalR AspNetHandler handler is the one being requested and, if so, call the NewRelic IgnoreXXX methods at that point.

Just spitballing (e.g. I haven't tested this) that module might look something like this:

public class SignalRNewRelicIgnoreHttpModule : IHttpModule {     public void Init(HttpApplication context)     {         context.PostMapRequestHandler += (s, a) =>             {                 if(HttpContext.Current.Handler is SignalR.Hosting.AspNet.AspNetHandler)                 {                     NewRelic.Api.Agent.NewRelic.IgnoreTransaction();                 }             };     }      public void Dispose()     {      } } 

Then (obviously?) you need to register that module in config like so...

IIS Integrated mode:

<configuration>   <system.webServer>     <modules>         <add name="SignalRNewRelicIgnoreHttpModule" type="WhateverNamespace.SignalRNewRelicIgnoreHttpModule, WhateverAssemblyName" />     </modules>    </system.webServer> </configuration> 

IIS Classic mode:

<configuration>     <system.web>         <httpModules>             <add name="SignalRNewRelicIgnoreHttpModule" type="WhateverNamespace.SignalRNewRelicIgnoreHttpModule, WhateverAssemblyName" />         </httpModules>     </system.web> </configuration> 

UPDATE: 6/25/2013

As warned by @dfowler in the comments, SignalR has since changed its approach to hosting and instead now relies on Owin based hosting instead. This is great because it decouples SignalR directly from ASP.NET/IIS, but that means the above approach obviously won't work anymore. Instead what you would need to do is to make sure to configure the Owin pipeline with a module like the sample one below (available here in a gist as well) to disable tracing for the pipeline:

public class NewRelicIgnoreTransactionOwinModule {     private AppFunc _nextAppFunc;      public NewRelicIgnoreTransactionOwinModule(AppFunc nextAppFunc)     {         _nextAppFunc = nextAppFunc;     }      public Task Invoke(IDictionary<string, object> environment)     {         // Tell NewRelic to ignore this particular transaction         NewRelic.Api.Agent.NewRelic.IgnoreTransaction();          return _nextAppFunc(environment);     } } 

And then, in your Startup::Configuration method just make sure you add this module to the IAppBuilder before you map any SignalR connections/hubs. That should look something like this:

public class Startup {     public void Configuration(IAppBuilder app)     {         app.Use(typeof(NewRelicIgnoreTransactionOwinModule));         app.MapHubs();     } } 

Finally, it should be noted that, right now this takes a very simplistic approach that assumes you're not going to have any other Owin requests in your application scope. If you're mixing SignalR into another web app that has other Owin requests this particular module implementation would cause those to be ignored as well, so a more advanced module that maybe checks that the incoming request is actually targeting a SignalR URL would be required. For now, I leave that up to the reader to figure out.

like image 28
Drew Marsh Avatar answered Sep 23 '22 03:09

Drew Marsh