我应该在哪里调用NewRelic.Api.Agent.NewRelic.IgnoreApdex()
或NewRelic.Api.Agent.NewRelic.IgnoreTransaction()
在我的 SignalR 集线器中调用,以防止长时间运行的持久连接掩盖我的应用程序监控日志?
7 回答
要继续 Micah 的回答,这里是用于忽略所有信号器调用的自定义检测文件。
创建到 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。
哦,很好的问题,一个我自己还没有想到的问题。我认为您需要做的是编写一个自定义模块,因为模块在所有处理程序之前执行,它检测到 SignalR AspNetHandler 处理程序是被请求的处理程序,如果是,则调用 NewRelic IgnoreXXX 方法。
只是吐口水(例如我没有测试过这个)该模块可能看起来像这样:
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()
{
}
}
然后(显然?)您需要像这样在配置中注册该模块......
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>
更新:2013 年 6 月 25 日
正如@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 请求的 Web 应用程序中,则此特定模块实现也会导致这些请求被忽略,因此可能需要一个更高级的模块来检查传入请求是否实际上以 SignalR URL 为目标。现在,我把它留给读者去弄清楚。
也可以使用 IgnoreTransactionTracerFactory 通过自定义检测忽略事务。当您不想将 API 添加到项目中或想要忽略基于无法更改的框架方法的事务时,这特别有用。
您的自定义检测文件将类似于:
<?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,而不是在异步线程上)你可以在上面填写 assemblyName/className/methodName,它会是与在该方法中调用 IgnoreTransaction API 相同。
这整个问题似乎是由 SignalR 控制器上的“连接”方法引起的。我创建了一个集线器管道模块,它通过覆盖 OnBeforeConnect 方法来忽略 NewRelic 日志记录。
在 web 应用程序的 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);
}
}
对于使用旧版本 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>
在 SignalR.Core 2.2.2 中有两个 AuthorizeRequest 方法。所以 New 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”可解决问题。
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);
}