New Relicアプリケーションパフォーマンス監視(APM)サービスとOpenTelemetry APMサービスでは、エラーを定義、取得、表示する方法が異なります。顧客がOpenTelemetryに移行し、APMとOpenTelemetryの概要ページを比較すると、同じサービスに対してエラー率グラフが異なる値を表示していることに気づくでしょう。このブログ記事では、その理由について詳しく説明します。

エラーとは何か?

これは単純な質問のように思えるかもしれません。典型的な説明は未処理の例外があるトランザクションはすべてエラーであるというものです。

エラー率は、特定の時間枠内でエラーが発生したトランザクションの割合です。たとえば、特定の期間中にアプリケーションが1,000件のトランザクションを処理し、そのうち50件に未処理の例外がある場合、エラー率は50/1000、つまり5%になります。ただし、エラーの定義と解釈はOpenTelemetryによって異なるため、エラー率も異なります。基本的に、OpenTelemetryにはトランザクションという概念がなく、エージェントがエラーの取得およびカウントに使用する追加のロジックもないためです。

まず、New RelicがAPMエージェントのエラーをどのように処理するかを確認し、それをOpenTelemetryと比較してみましょう。

New Relic APMエージェント

New Relicでは、トランザクションはソフトウェアアプリケーションにおける1つの動作の論理的な単位として定義されます。具体的には、その作業単位を構成する関数呼び出しとメソッド呼び出しを指します。APMの場合、ウェブトランザクションを指すことが多く、アプリケーションがウェブリクエストを受信してから応答が送信されるまでのアクティビティを表します。

トランザクションタイプとサブタイプについて詳しくは、こちらをご覧ください。

トランザクションのエラーロジック

トランザクションごとに1つのエラーのみを記録します。作業単位内に複数のエラーがある場合でも、エラー率を考慮して、トランザクションごとに1つのエラーとしてカウントします。これは、次の種類のエラーの優先順位に従って生成されます。

  • NoticeError API
  • インストゥルメンテーションによって観察された例外
  • ステータスコード >= 400のウェブトランザクション

エラーが定義されると、TransactionErrorイベントは例外タイプやスタックトレースなどの詳細をキャプチャします。New Relic APMは、エージェント設定を介して「無視される」エラーと「予期される」エラーの概念もサポートしています。

参考として例外のない Go 言語がどのようにしてエラーを報告しているかを Github で説明していますので添付します。
https://github.com/newrelic/go-agent/blob/master/GUIDE.md#error-reporting

New Relicの例

このトランザクションには、4つのインストゥルメントされたメソッドがあります。メソッドBとDの両方にエラーがあります。ただし、このインスタンスは、優先順位に基づいて最初のエラーと詳細のみを記録します。

予期しないエラーが記録されると、エラーカウントが増分され、New Relic APMエージェント(apm.service.error.count)によりメトリクスとして記録されます。以下のスクリーンショットに示すように、APM概要ページのエラー率は、このメトリクスを使用して計算されます。TransactionErrorイベントはサンプリングされた、限られたデータセットであるため、エラー率の計算と視覚化ではTransactionErrorイベントは考慮されません

サンプルのNRQLクエリ

SELECT sum(apm.service.error.count['count'])/ count(apm.service.transaction.duration)AS 'Web errors' FROM Metric WHERE (entity.guid = 'foo') AND (transactionType = 'Web') LIMIT MAX SINCE 30 MINUTES AGO TIMESERIES

New Relicエージェントのエラー管理の詳細については、ドキュメントを参照してください。

OpenTelemetry

OpenTelemetryデータからUIのさまざまな部分を駆動するためにエラーを定義する方法は2つあります。

  1. OpenTelemetryメトリクス。OpenTelemetry APM概要ページのエラー率チャートに使用します。
  2. スパンから定義されたトランザクション。Errors Inboxに使用します。

メトリクスからのエラー(OpenTelemetry APMの概要)

New Relic OpenTelemetryの概要ページには、メトリクスまたはスパンを切り替えるオプションがあります。

メトリクス:APMとOpenTelemetryの主な違いは、OpenTelemetry httpメトリクス仕様にはエラーカウントメトリクスがないことです。New RelicのOpenTelemetry APMエクスペリエンスの場合、エラー率チャートは期間メトリクス(http.server.request.durationまたはrpc.server.duration)を参照し、ステータスコード >=500のインスタンスをエラー率として分類します。つまり、メトリクスからのエラー率はHTTP呼び出しに限定されています。

サンプルのNRQLクエリ

SELECT filter(count(http.server.request.duration),WHERE numeric(http.status_code)>= 500 OR numeric(http.response.status_code) >= 500)/count(http.server.request.duration)  as 'Error rate for all errors' FROM Metric WHERE (entity.guid = 'foo') AND (http.server.request.duration IS NOT NULL OR http.server.request.duration IS NOT NULL) SINCE 30 minutes ago TIMESERIES

スパン:スパンからエラー率チャートが生成される場合、サーバーまたはコンシューマーのタイプと、ERRORのステータスコードを含むすべてのOpenTelemetryスパンがエラーとみなされます。つまり、スパンからのエラー率はプロトコルに依存しません。

サンプルのNRQLクエリ

SELECT filter(count(*), WHERE otel.status_code = 'ERROR')/count(*)  as 'Error rate for all errors' FROM Span WHERE (entity.guid = 'foo') AND ((span.kind LIKE 'server' OR span.kind LIKE 'consumer' OR kind LIKE 'server' OR kind LIKE 'consumer')) SINCE 30 minutes ago TIMESERIES

スパンからのエラー(Errors Inbox)

OpenTelemetryにはトランザクションの概念はなく、スパンがあり、スパンはトランザクション内の操作を表します。New Relicは、トレースデータをトランザクションの概念にマッピングするためにSpanKindに依存しています。サーバーまたはコンシューマーのSpanKindを使用して、プロセスのエントリポイントを特定します。言い換えれば、これらはリモートプロセスのルートスパンまたは子スパンのいずれかのスパンになります。

トランザクションの定義がないことに加えて、OpenTelemetryには明示的なエラー率メトリクスが含まれていません。

New RelicとOpenTelemetryの間のギャップを埋めるために、トランザクションはkindサーバーのスパンによって定義され、子スパンがトランザクションのサブオペレーションを構成します。

このトランザクションの定義では、kindサーバーのルートスパンのstatus.codeがERRORである場合にのみ、トランザクションはエラーとみなされます。他の子スパンのステータスコードがERRORであっても、問題となるのはルートスパンのステータスコードがERRORである場合のみです。ルートスパンのステータスコードがERRORでない場合、トランザクションはエラー率にカウントされません。

OpenTelemetryの例

この例では、サービスは円(スパン)を含むボックスとして表されます。サービスAはサービスBを呼び出しており、サービス BはサービスCを呼び出しています。

サービスB内には複数のインストゥルメントされたメソッドがあり、その結果、複数のスパンがキャプチャされます。メソッドAはkindサーバー、つまりこのサービスのエントリポイントであり、APM UIに入力するトランザクションの概念を定義するために使用されます。この抽象化内には、ステータスコードERRORを持つ複数のスパンが存在します。

ルートスパンにエラーがあるため、トランザクションはエラーとみなされ、Errors Inboxに表示されます。

まとめ

New Relic APMとOpenTelemetryはモデルが根本的に異なるため、エラー率を直接比較することはできません。インストゥルメンテーション方法間での移行時には、サービスのエラーベースラインを再確立し、それをアラート条件、サービスレベル目標、ダッシュボードに活用することが重要です。