.NET エージェントによるエラーレポート

問題

.NET エージェントは、標準エラーであるかのようにエラーをレポートします。これは、Azureのワーカーのロール、コンソールアプリ、非同期の作業、同様の操作でよく起こる問題です。

対策

これらの誤ったエラーレポートを受け取らないためには、直接または間接的に例外ハンドラを含むメソッド計測します。以下の例では、GetResponse() はエラーをスローします。

エラーをスローする GetResponse()
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.IO;

namespace ErrorTester
{
    class Program
    {
        static void Main(string[] args)
        {
            var i = 0;
            while (true)
            {
                Foo(++i);
            }
        }
        static void Foo(int i)
        {
                try
                {
                    GetNotFound();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Got it " + i + "!");
                    Thread.Sleep(1000);
                }

        }
        static string GetNotFound()
        {
            string uri = "http://localhost/Test/this/is/not/a/real/page";
            var request = (HttpWebRequest)WebRequest.Create(uri);
            var response = request.GetResponse();
            var data = new StreamReader(response.GetResponseStream()).ReadToEnd();
            response.Close();
            return data;
        }
    }
}

この例では、Foo() メソッドが計測されない限りGetResponse() からのエラーを報告します。Foo が計測されているかぎり、Foo がコールされたら、トランザクションを開始し、Foo が終了したら、トランザクションを終了します。Foo が終了する前にエラーが処理されるため、New Relic はエラーをレポートしません。GetReponse は Foo トランザクションに含まれることに注意してください。

カスタム計測ファイルを定義したり、カスタムトランザクションでメソッドをラップすることにより、以下のように対象とするメソッドを計測します。

カスタム計測ファイルを定義する

カスタム計測を利用して Foo を計測するには、 カスタム計測ファイルを定義します。この場合、CustomInstrumentation.xml は以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2008-2014 New Relic, Inc. All rights reserved. -->
<!--
    When you edit this file, please use an XML aware editor (such as Visual Studio),
    and pair with the companion file extension.xsd to minimize the
    chance of introducing typos that may confuse the agent when it is run.
-->
<extension xmlns="urn:newrelic-extension">
  <instrumentation>
    <tracerFactory >
      <match assemblyName="ErrorTester" className="ErrorTester.Program">
        <exactMethodMatcher methodName="Foo" /> 
      </match>
    </tracerFactory>
  </instrumentation>
</extension>

New Relic の extensions フォルダに CustomInstrumenation.xml を置いてください。そこには、CoreInstrumentation.xml もあります。そして、アプリケーションを再起動します。

さらに詳しい情報は、カスタム計測をご覧ください。

カスタムトランザクションでメソッドをラップする

カスタムトランザクションを利用して、Foo を計測するには、以下のように Foo をカスタムトランザクションで「ラップ」します。

<extension xmlns="urn:newrelic-extension">
  <instrumentation>
     <tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="Background/Task">
       <match assemblyName="ErrorTester" className="ErrorTester.Program">
         <exactMethodMatcher methodName="Foo" />
       </match>
    </tracerFactory>
  </instrumentation>
</extension>

さらに詳しい情報は、カスタムトランザクションをご覧ください。

原因

.NET 用 New Relic がレポートする唯一のエラーは、トランザクションを終了させる未処理のエラーです。トランザクションが終了する前にアプリケーションが例外ハンドラーを呼び出す場合、New Relic はエラーを報告しません。
しかし、エラーが Web トランザクション、WCF トランザクション、 カスタムトランザクションの外側で発生した場合は、例外ハンドラーを常に検出する訳ではありません。なぜなら、エージェントが、トランザクションに関連付けられていない計測対象のメソッドについては、「ミニトランザクション」を生成するためです。計測対象のメソッドが終了すると、ミニトランザクションも終了します。ミニトランザクションがエラーをスローし、計測対象のメソッドがそれを処理しない場合は、New Relic はエラーを報告します。

GetResponse() を呼び出すコンソールアプリケーションでこれを確認できます。上記の例に見られるように、GetResponse がエラーをスローすると、GetResponse が try/catch ブロック内で呼び出されていたとしても、New Relic はエラーを報告します。なぜなら、GetResponse の「ミニトランザクション」が終わっているため、エージェントはエラーを報告します。エージェントから見ると、エラーはトランザクション終了時にまだ未処理だったからです。

さらに詳しい情報

追加のドキュメントリソースは次のとおりです。