【问题标题】:Ignore persistent SignalR connections in New Relic忽略 New Relic 中的持久 SignalR 连接
【发布时间】:2012-11-09 12:57:00
【问题描述】:

我应该在 SignalR 集线器的哪里调用 NewRelic.Api.Agent.NewRelic.IgnoreApdex()NewRelic.Api.Agent.NewRelic.IgnoreTransaction() 以防止长时间运行的持久连接掩盖我的应用程序监控日志?

【问题讨论】:

    标签: c# asp.net-mvc signalr newrelic


    【解决方案1】:

    要继续 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。

    【讨论】:

    • 已确认。谢谢Juho!
    • 为了完整起见,这个文件的名称应该是什么?
    • @ArthurStankevich 您可以随意命名。只要确保它以 .xml 结尾。见New Relic Documentation
    • 关于如何在 Azure 网站上进行这项工作的任何想法,因为我们无权访问文件系统
    • @CamLangsford 这很容易。从打开 Azure 门户并转到 Web 应用程序。现在寻找App Service Editor,它将打开你的整个代码库,准备好进行编辑。现在浏览到newrelic\extension 并在那里添加 IgnoreSignalR.xml。如果您没有找到该门户,则表示您尚未在此 Web 应用程序中设置 New Relic。我发现最简单的解决方案是安装 New Relic Azure Site Extension siteextensions.net/packages/NewRelic.Azure.WebSites
    【解决方案2】:

    哦,很好的问题,我自己还没有想过。我认为你需要做的是编写一个自定义模块,因为模块在所有处理程序之前执行,它检测到 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 在 cmets 中所警告的那样,SignalR 已经改变了托管方式,现在改为依赖基于 Owin 的托管。这很棒,因为它将 SignalR 直接与 ASP.NET/IIS 分离,但这意味着上述方法显然不再适用。相反,您需要做的是确保使用如下示例模块(也可用here in a gist)配置 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 方法中,只需确保在映射任何 SignalR 连接/集线器之前将此模块添加到 IAppBuilder。应该是这样的:

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

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

    【讨论】:

    • 调用 IgnoreTransaction 还应该从 Apdex 计算中删除事务(有效调用 IgnoreApdex)。
    • 是的,我今天早上正在考虑,我将从示例中删除 IgnoreApdex 调用。
    • 这在下一个版本中将无法正常工作,因为处理程序会发生变化。一般来说,依靠内部细节是不好的:)
    • 那么考虑到这一点,在这个级别上会有一个可扩展点吗?我应该在 GitHub 上提交问题吗?
    • 看起来@pexxxy 发布的链接有一个 GitHub 不喜欢的斜杠。正确链接:darrenkopp.com/posts/2014/05/07/Ignoring-SignalR-in-NewRelic
    【解决方案3】:

    也可以通过自定义检测忽略事务,也可以使用 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 相同。

    【讨论】:

    • 这样更好,不用重新部署
    【解决方案4】:

    这整个问题似乎是由 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);
        }
    
    }
    

    【讨论】:

    • 嗯,不,我会阻止所有信号器流量
    【解决方案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>
    

    【讨论】:

    • 如何在我的 Web 应用程序中检查 SignalR 版本?
    【解决方案6】:

    在 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”解决问题。

    【讨论】:

      【解决方案7】:
          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);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多