繁体   English   中英

忽略 New Relic 中的持久 SignalR 连接

[英]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?

SignalR主导监控的New Relic截图

要继续使用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方法。

只是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()
    {

    }
}

然后(显然?)你需要在配置中注册该模块,就像这样......

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管道( 此处也可以在gist中使用)来禁用对管道的跟踪:

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方法中,确保在映射任何SignalR连接/集线器之前将此模块添加到IAppBuilder 这应该是这样的:

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

最后,应该注意的是,现在这采用了一种非常简单的方法,假设您在应用程序范围内不会有任何其他Owin请求。 如果您将SignalR混合到另一个具有其他Owin请求的Web应用程序中,则此特定模块实现也会导致这些请求被忽略,因此可能需要一个更高级的模块来检查传入请求是否实际上是针对SignalR URL。 现在,我把它留给读者去弄清楚。

也可以使用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,而不是在异步线程上调用),你可以在上面填写assemblyName / className / methodName,它将是与在该方法中调用IgnoreTransaction API相同。

整个问题似乎是由SignalR控制器上的“连接”方法引起的。 我创建了一个集线器管道模块,它通过覆盖OnBeforeConnect方法忽略NewRelic日志记录。

在maphub为您的Web应用程序调用Application_Start()方法(global.asax.cs)之后的某处,添加以下内容:

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

我无法忽略带有 NewRelic 扩展 XML 文件的 ASP.NET 核心 SignalR 请求。 因此,受@Pali 回答的启发,这个中间件适用于 ASP.NET 核心 SignalR:

public class IgnoreSignalrNewRelicMiddleware
{
    private readonly RequestDelegate _next;

    public IgnoreSignalrNewRelicMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        //This will block all signalr request, but we can configure according to requirements
        if (httpContext.Request.Path.Value?.Contains("/signalr") ?? false)
        {
            // Tell NewRelic to ignore this particular transaction
            NewRelic.Api.Agent.NewRelic.IgnoreTransaction();
            NewRelic.Api.Agent.NewRelic.IgnoreApdex();
        }

        // Call the pipeline ...
        await _next(httpContext);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM