Игнорировать постоянные соединения SignalR в New Relic
Где я должен позвонить NewRelic.Api.Agent.NewRelic.IgnoreApdex()
или NewRelic.Api.Agent.NewRelic.IgnoreTransaction()
в своих концентраторах SignalR, чтобы предотвратить длительные постоянные соединения от затенения журналов мониторинга приложений?
![New Relic Screenshot of SignalR dominating monitoring]()
Ответы
Ответ 1
Ооо, отличный вопрос и тот, о котором я еще не думал. Я думаю, что вам нужно будет написать собственный модуль, так как модули выполняются перед всеми обработчиками, которые обнаруживают, что обработчик SignalR AspNetHandler является тем, который запрашивается, и если да, вызовите методы NewRelic IgnoreXXX в этой точке.
Просто spitballing (например, я не тестировал это), этот модуль может выглядеть примерно так:
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()
{
}
}
Затем (очевидно?) вам нужно зарегистрировать этот модуль в config так, чтобы он...
Интегрированный режим IIS:
<configuration>
<system.webServer>
<modules>
<add name="SignalRNewRelicIgnoreHttpModule" type="WhateverNamespace.SignalRNewRelicIgnoreHttpModule, WhateverAssemblyName" />
</modules>
</system.webServer>
</configuration>
Классический режим IIS:
<configuration>
<system.web>
<httpModules>
<add name="SignalRNewRelicIgnoreHttpModule" type="WhateverNamespace.SignalRNewRelicIgnoreHttpModule, WhateverAssemblyName" />
</httpModules>
</system.web>
</configuration>
ОБНОВЛЕНИЕ: 6/25/2013
Как предупреждает @dfowler в комментариях, SignalR с тех пор изменил свой подход к хостингу и вместо этого вместо этого использует Owin. Это здорово, потому что он отделяет SignalR напрямую от ASP.NET/IIS, но это означает, что вышеупомянутый подход, очевидно, больше не будет работать. Вместо этого вам нужно будет сконфигурировать конвейер Owin с модулем, подобным приведенному ниже (доступный здесь, в частности,), чтобы отключить отслеживание для трубопровода:
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);
}
}
И затем, в вашем методе Startup:: Configuration просто убедитесь, что вы добавили этот модуль в IAppBuilder
, прежде чем отображать любые соединения/концентраторы SignalR. Это должно выглядеть примерно так:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use(typeof(NewRelicIgnoreTransactionOwinModule));
app.MapHubs();
}
}
Наконец, следует отметить, что прямо сейчас это требует очень упрощенного подхода, предполагающего, что вы не будете иметь никаких других запросов Owin в своей области приложения. Если вы смешиваете SignalR в другом веб-приложении, в котором есть другие запросы Owin, эта конкретная реализация модуля приведет к тому, что те будут игнорироваться, поэтому потребуется более продвинутый модуль, который может проверить, что входящий запрос на самом деле нацелен на URL SignalR. Пока я оставляю это до читателя, чтобы понять.
Ответ 2
Чтобы продолжить с ответа Мики, вот пользовательский файл инструментария для игнорирования всех вызовов signalr.
Создайте его в 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>
Не забудьте сделать iisreset.
Ответ 3
Можно также игнорировать транзакцию через пользовательские инструменты, используя IgnoreTransactionTracerFactory. Это особенно полезно, если вы не хотите добавлять API в свой проект или когда хотите игнорировать транзакции на основе метода Framework, который вы не можете изменить.
Ваш пользовательский файл инструментов выглядит примерно так:
<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
<instrumentation>
<tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.IgnoreTransactionTracerFactory">
<match assemblyName="System.Web.Extensions" className="System.Web.Handlers.ScriptResourceHandler">
<exactMethodMatcher methodName="Throw404" />
</match>
</tracerFactory>
</instrumentation>
</extension>
Если вы можете найти метод рамки SignalR, который всегда вызывается в потоке запроса (вы можете вызвать IgnoreTransaction только в потоке запроса, а не в потоке async), вы можете заполнить имя node/className/methodName в приведенном выше и это будет то же самое, что вызвать API-интерфейс IgnoreTransaction внутри этого метода.
Ответ 4
Вся эта проблема, по-видимому, вызвана методом "connect" на контроллере SignalR. Я создал модуль конвейерного конвейера, который игнорирует ведение журнала NewRelic, переопределяя метод OnBeforeConnect.
Где-то после того, как в вашем приложении Application_Start() (global.asax.cs) для вашего веб-приложения вызовы maphubs добавят следующее:
GlobalHost.HubPipeline.AddModule(new IgnoreNewRelicConnectionsModule());
Затем создайте этот класс:
private class IgnoreNewRelicConnectionsModule : HubPipelineModule
{
protected override bool OnBeforeConnect(IHub hub)
{
NewRelic.Api.Agent.NewRelic.IgnoreTransaction();
return base.OnBeforeConnect(hub);
}
}
Ответ 5
Для людей, использующих старую версию SignalR, здесь используется инструмент xml
<tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.IgnoreTransactionTracerFactory">
<match assemblyName="SignalR.Hosting.AspNet" className="SignalR.Hosting.AspNet.AspNetHandler">
<exactMethodMatcher methodName="ProcessRequestAsync"/>
</match>
</tracerFactory>
Ответ 6
public Task Invoke(IDictionary<string, object> environment)
{
object value = "";
//Check if the OWIN key is present
if (environment.ContainsKey("owin.RequestPath"))
{
//Get the value of the key
environment.TryGetValue("owin.RequestPath", out value);
//This will block all signalr request, but we can configure according to requirements
if (value.ToString().Contains("/signalr"))
{
// Tell NewRelic to ignore this particular transaction
NewRelic.Api.Agent.NewRelic.IgnoreTransaction();
NewRelic.Api.Agent.NewRelic.IgnoreApdex();
}
}
return _nextAppFunc(environment);
}
Ответ 7
В SignalR.Core 2.2.2 есть два метода AuthorizeRequest. Итак, новый файл инструмента Relic должен выглядеть так:
<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
<instrumentation>
<tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.IgnoreTransactionTracerFactory">
<match assemblyName="Microsoft.AspNet.SignalR.Core" className="Microsoft.AspNet.SignalR.PersistentConnection">
<exactMethodMatcher methodName="AuthorizeRequest"/>
</match>
<match assemblyName="Microsoft.AspNet.SignalR.Core" className="Microsoft.AspNet.SignalR.Hubs.HubDispatcher">
<exactMethodMatcher methodName="AuthorizeRequest"/>
</match>
</tracerFactory>
</instrumentation>
</extension>
Поместите этот файл в "C:\ProgramData\New Relic.NET Agent\Extensions".