New Relic Now+ New Relic’s most transformative platform update yet with 20+ product launches.
Watch the event on-demand now.
明るいターコイズの背景に黄色いリボンのアワード

アラート通知では impacted entities として障害の影響をうけたエンティティが記録されます。 しかし、同じアラートコンディションからの通知であっても 対象エンティティの記載がない場合 や (ユーザーの期待とは) 異なるエンティティが記録されてしまうということがあります。 本ブログポストでは対象エンティティの決定の仕組みに関して、検証した内容を元に記載いたします。 意図と異なる通知が発生してしまう可能性があるような場合はコンディションの設定などの見直しをご検討ください。

前提知識: 集計ウィンドウとシグナル値について

本題に入る前に少しアラートの評価システムについて、記載します。 New Relic のアラートでは、集計ウィンドウとよばれる一定時間ごとに区切られた期間を利用して、閾値の評価を行います。

この集計ウィンドウの期間は Window Duration 項目でユーザーがアラートコンディションごとに決定します。 例えば 5分と設定されている場合は

  • 12:00 - 12:05
  • 12:05 - 12:10
  • 12:10 - 12:15
  • 12:15 - 12:20

のように固定された 5分ごとの期間が各ウィンドウの期間となります (5分前などの相対的な時刻の期間ではありません)。

Window Duration を 7分 などの 24時間で割り切れない時間幅に設定した場合は、正確に算出されたい場合は UnixTime から計算する必要があります。または 6時間などの場合、UnixTime が基準であるため 日本時間では 09:00 - 15:00, 15:00 - 21:00 というウィンドウになります。

NRQL 型アラートコンディションでは、SELECT 句に average(項目) や count(*) または max(項目) や latest(項目) といったデータの集計する方法を設定します。

例えば、下記のようなアラートクエリが設定されていた場合

CPU 使用率の平均値を収集するアラートクエリ 例

SELECT average(`cpuPercent`) FROM SystemSample WHERE entityName = ‘web1’

これは web1 サーバの cpuPercent の平均値でアラートを設定するという意味となります。

もう少し具体的にみていきます。 インフラエージェントの SystemSample の収集ポーリングはデフォルトで 5秒であるため、5分間ではおよそ 12*5 = 60 個のデータを受信することになります。 (インフラエージェントのデータ送信タイミングはエージェントサービスの起動を基準にするため、起動後からおよそ 5秒ポーリングで収集し、送信する仕組みとなります。またサーバの負荷状況などにより正確に 5秒で収集されないという場合はあります。)

Window Duration が 5分である場合、12:00 - 12:05 期間のタイムスタンプを持つデータ (およそ 60個) の各 cpuPercent 値をもちいて、平均値が算出されます。 そして、その算出された値を 12:00 - 12:05 ウィンドウの シグナル値と呼びます。 average (平均値) などの SELECT 句で規定された集計関数で、その期間に受信したデータの集計を行うことを 出荷処理と呼びます。

出荷処理が行われるタイミングは Streaming method (Event flow, Event timer, Cadence) およびその関連設定でユーザーが設定します。 12:00 - 12:05 のウィンドウの出荷タイミングを 12:05:00 ちょうどに設定するような場合は、12:04:59 のタイムスタンプデータが 2秒おくれて到着した場合などは、集計処理の対象データには含まれないことになるので、データの送信遅延なども考慮が必要です。 Streaming method については本テーマからずれるため、下記ブログポストなどを参照ください。

[NRQLアラート条件に追加された新しい集計方法とどれを選ぶべきかの指針] https://newrelic.com/jp/blog/nerdlog/new-aggregation-methods-for-nrql-alert-conditions

前提知識: 閾値とインシデント

Warning/Critical 閾値は、result query > 50 for at least 10分 のように設定をしますが、ここで登場する閾値評価時間 (10分) は集計ウィンドウの数と解釈するとわかりやすいです。 また、for at least は いずれも (すべての)、result query は、各シグナル値と解釈します。

集計ウィンドウの期間 (Window Duration) が 5分である場合、10分は 集計ウィンドウ 2つ分であるため 、 この閾値の意味は (5分ごとに集計された) シグナル値が 2回連続で 50 を超過したら、違反と判定する、という意味となります。

また at least once in (いずれか) だった場合は (5分ごとに集計された) シグナル値 2つのうちいずれかが 50 を超過したら、違反と判定する、(意訳すると、最新のシグナル値が 50 を超過したら違反) という意味となります。

回復判定時の違いなどについては、下記ブログポストなどを参照ください。

[インシデント (アラート) で回復判定されないときに確認すること] https://newrelic.com/jp/blog/how-to-relic/alert-zeronull

上記のように、閾値評価のプロセスでは 複数の (または単一) の集計ウィンドウが利用されます。そうして閾値違反となった場合は、インシデントが作成されます。

前提知識:インシデントと Issue の関係性

インシデントは Issue に所属します (1つの Issue に対するインシデントの所属上限数を超える場合などを除く)。

新規のインシデント (新規の閾値違反) が発生した場合、既存の Issue に属するか、または、新規の Issue が合わせて作成され、そこに属するという動作となります。 Issue には複数 (または単一) のインシデントが所属することになります。

インシデントは監視項目 (の閾値) ごとの障害発生イベントを表し、Issue にはそれらがまとまります。(同一の根本原因と考え) Issue 単位で障害対応を行います。

インシデントがどの Issue に属するかの判定は、アラートポリシーの Issue creation preference 設定または correlation が有効な場合は decisions で決定されます。

Issue creation preference 設定はアラートポリシーの設定項目で下記の 3つの選択肢があります。 (また FACET によるシグナル分割については、次の章に記載します。)

  • One issue per policy (アラートポリシー単位でまとめる):

    • アラートポリシー配下のアラートコンディションに由来するインシデントであれば、同一 Issue に所属するようにまとめられます
  • One issue per condition (アラートコンディション単位でまとめる):

    • 同一アラートコンディションに由来するインシデントであれば、同一 Issue に所属するようにまとめられます
      • 異なるアラートコンディションであれば異なる Issue に所属するようになります。FACET 利用で分割された別シグナル由来のインシデントでも同一コンディションであれば、同一 Issue に所属することになります
  • One issue per condition and signal (シグナル単位でまとめる):

    • 同一シグナルであれば同一 Issue に所属するようにまとめられます
      • シグナルはコンディションごとに作成されるので、別コンディションであれば、別 Issue になります。また、同一コンディションでも FACET 利用で別シグナルであれば、別 Issue に所属することになります。しかし、閾値の違い (Warning 閾値と Critical 閾値、信号損失閾値) のインシデントは同一シグナルに由来したインシデントとなるため、同一 Issue となります。このため同一シグナルであれば Warning 閾値違反のインシデントと Critical 閾値違反のインシデントは同一 Issue に所属することになります。

[イシューが作成されるタイミングを決定する] https://docs.newrelic.com/jp/docs/alerts/organize-alerts/specify-when-alerts-create-incidents/

また、上記のようなコンディション・ポリシーごとのまとめルールだけでなく、対象エンティティごとなどでインシデントのまとめ方をカスタマイズしたいという場合は correlation および decisions ルールの作成を行うことで実現できます。詳細はドキュメントを確認ください。

[意思決定で相関ロジックを構成する] https://docs.newrelic.com/jp/docs/alerts/organize-alerts/change-applied-intelligence-correlation-logic-decisions/

前提知識: 1つのコンディションから複数のシグナル (FACET によるシグナル分割)

先述の「CPU 使用率の平均値を収集するアラートクエリ 例」の場合は、1つのシグナルのみが作成されます。 (※ アラートコンディションが変更されるとシグナルはリセット (既存シグナルは破棄) され、別のシグナルが作成されることになります。)

この場合は 1つのアラートコンディションで 1つのシグナルという扱いになります。

一方で、下記のようにアラートクエリに FACET (グループ化) を利用した場合、複数のシグナルが作成されます。

SELECT average(`cpuPercent`) FROM SystemSample FACET entityName
WHERE entityName IN (‘web1’, ‘web2’)

FACET 項目である entityName ごとにシグナルを分ける、という意味となり、entityName ごとにグループ化されたデータでシグナル値が算出されるようになります。

web1, web2 からデータを受信している場合、web1 用のシグナルと web2 用のシグナルが作成され、それぞれでシグナル値が算出、閾値評価が行われます。 そしてそれぞれのインシデントが作成されることになります。(別の障害 (インシデント) という扱いになります。)

アラートポリシーの設定で、correlation が無効化で One issue per condition and signal であれば、別の Issue に所属するインシデントという扱いとなります。

また、FACET はデータとして報告されている任意の項目で設定することができ、複数を指定することも可能です。

entityName と awsRegion でグループ化する場合の例

FACET entityName, awsRegion

アラートコンディション、シグナル、インシデント、Issue の関係性まとめ

シグナルはアラートコンディション × FACET 項目で作成されます。

Window Duration で定められた時間幅をもつ集計ウィンドウごとに各シグナルでシグナル値が算出されます。

シグナル値をもとに閾値で評価されます。閾値違反となるとインシデントが作成されます。

インシデントは Open な Issue に所属します。Open Issue がない場合は新規の Issue が作成されます。

1つの Issue には複数 (または単一) のインシデントが所属します。インシデントがどの Issue に所属するかは アラートポリシーの Issue creation preference 設定または correlation で決まります。

シグナルにおける対象エンティティ

前置きが長くなってしまいましたが、ようやく本題です。

アラートコンディションを作成すると気がつきますが、対象エンティティを (明示的に) 設定する箇所はありません。 NRQL 型アラートは自由度があるため、設定するようにもでき、設定しないようにもできます。 設定しない場合、データの受信状況によっては、集計ウィンドウ (区切られた時間) ごとに対象エンティティが異なってしまう場合もあります。

シグナルにおける対象エンティティの決定は、各時間で受信した対象データが 単一のエンティティに限定されていた場合、対象エンティティと認定されます。

アラートクエリ例1

SELECT average(`cpuPercent`) FROM SystemSample WHERE entityGuid =...

上記のようなアラートクエリの場合、WHERE 句で entityGuid を 1つに限定しているため、常に 1種類のエンティティデータに限定されます。 そのため、このシグナルはどの時間でも対象エンティティが決まります。

アラートクエリ例2

SELECT average(`cpuPercent`) FROM SystemSample
WHERE entityName IN (‘web1’, ‘web2’)

一方で上記のようなアラートクエリの場合は、web1 と web2 の 2つのエンティティからのデータが対象となります。 この場合、集計ウィンドウのデータは 単一のエンティティデータではなくなってしまうため、シグナル値は対象エンティティを定めず、なし、となります。

(※ web1 と web2 両方からデータを受信している場合)

アラートクエリ例3

SELECT count(*) FROM Log
WHERE message like%error%AND (hostname = ‘web1’ OR hostname =  ‘web2’)

次はログデータ用のアラートクエリ例で、WHERE 句では error を含むメッセージで、web1 か web2 からのデータを対象とするという条件となっています。 Window Duration 5分で、12:01 に web1 からの対象のログデータ (error を含むメッセージ) を受信、続いて 12:07 に web2 からの対象のログデータを受信。さらにその後 12:13 に web1 と web2 の両方から対象データを受信した場合を考えてみます。

この場合、12:00 - 12:05 の集計ウィンドウでは web1 エンティティのみのデータが対象で、12:05 - 12:10 の集計ウィンドウでは web2 エンティティのみのデータとなるため、それぞれの集計ウィンドウで対象エンティティが異なる、ということになります。 また、12:10 - 12:15 の場合は web1 と web2 の 2つのエンティティからのデータが混在しているため、この時間の集計ウィンドウでは 対象エンティティは なし となります。

アラートクエリ例4

SELECT average(`cpuPercent`) FROM SystemSample FACET entityName

最後に FACET を使用した例です。WHERE 条件はないため、SystemSample で cpuPercent を含む項目が対象データとなりますが、entityName で FACET しているため、シグナルは entityName ごとに作成されます。(同一 entityName からのデータ受信がないならば) シグナルは対象エンティティを一意に認識できるため、対象エンティティが定まります。

シグナルにおけるエンティティの決定過程は、上記のように対象の期間で受信したデータが単一エンティティのみか否かとなります。

インシデントにおける対象エンティティ

シグナルのエンティティが常に定まっている場合は、そのインシデントの対象エンティティもそのエンティティとなります。

では、先に見たように集計ウィンドウごとに変わる (各シグナル値で対象エンティティが異なる) ような場合、インシデントの対象エンティティはどのようになるのでしょうか。

Window Duration が 5分で、閾値が result query > 50 for at least 15分 だった場合で、次のように各集計ウィンドウの対象エンティティが異なる場合

ウィンドウ シグナル値 対象エンティティ 備考
11:55 - 12:00 45 web1 閾値以下
12:00 - 12:05 51 web2 閾値超過 1回目
12:05 - 12:10 53 閾値超過 2回目
12:10 - 12:15 54 web3 閾値超過 3回目
12:15 - 12:20 60 web4 閾値超過 4回目

テーブル 1. 集計ウィンドウごとに対象エンティティが異なる場合の例1

閾値の意味は シグナル値が 3回連続 50 を超過した場合、閾値違反とする、という意味ですがシグナルの対象エンティティには 5種類 (web1, web2, なし, web3, web4) が表示されています。閾値の 50 を超過している期間をみても (web2, なし, web3) の 3種類があります。

しかし、この場合は閾値違反と判定されるに至った最後の集計ウィンドウのエンティティがそのインシデントの対象ウィンドウとして設定されます。従って上記の場合は 閾値超過 3回目の web3 がこのインシデントの対象エンティティとなります。

また、次のように対象エンティティが なし に当たってしまった場合、 インシデントの対象エンティティも なし となります。

ウィンドウ シグナル値 対象エンティティ 備考
11:55 - 12:00 45 web1 閾値以下
12:00 - 12:05 51 web2 閾値超過 1回目
12:05 - 12:10 53 web3 閾値超過 2回目
12:10 - 12:15 54 閾値超過 3回目
このウィンドウでインシデントが作成
12:15 - 12:20 60 web4 閾値超過 4回目

テーブル 2. 集計ウィンドウごとに対象エンティティが異なる場合の例2

Issue における対象エンティティ

最後に Issue の対象エンティティに関して、記載します。

Issue では、複数のインシデントが所属する設計であるため、所属する各インシデントの対象エンティティの配列として認識されます。

Issue に 次のような 4つのインシデントが所属している場合

  • Issue
    • インシデント1 (対象エンティティ: web1)
    • インシデント2 (対象エンティティ:なし)
    • インシデント3 (対象エンティティ: web2)
    • インシデント4 (対象エンティティ: web1)

Issue の対象エンティティ は [web1, web2] となります。(インシデントの場合は Entity と単数表現ですが、Issue の場合は Entities と複数形で表現されます)

まとめ - 要注意なアラートクエリ-

これまで記載してきたように Issue/インシデントの対象エンティティの認識は、受信するデータが集計ウィンドウにおいて単一のエンティティであるかどうかです。 複数のエンティティが対象データとなってしまうようなアラートクエリの場合、対象エンティティなし、または受信データによっては時間帯でが変わってしまう可能性があります。

注意が必要なアラートクエリ例1

SELECT filter(uniqueCount(entityAndPid), where processDisplayName = 'プロセス名' and hostname = 'ホスト名') as 'プロセス数' FROM ProcessSample

filter 関数を利用した プロセス監視のアラートクエリ例ですが、WHERE 句や FACET 句には対象ホストの指定がありません (filter 関数内の where は対象データには利用されません。 対象エンティティが認識されない、または、別のサーバを対象エンティティと認識されてしまう可能性さえあります。

注意が必要なアラートクエリ例2

SELECT count(*) FROM Metric WHERE metricName = 'windows_service_state' AND state != 'running' FACET entity.guid

Windows サービスモニタリングでの例です。 上記は FACET entity.guid が指定されているため、シグナルでは一意のエンティティのみとなるため、対象エンティティという意味で問題ありません。

ただ、Windows サービスモニタリングでのエンティティはホストではなく ホスト × Windows サービスで作成され、entity.name には Windows サービス名が入り、対象ホスト名ではありません。

FACET hostname, service_name などで ホスト名を workflow 変数で取得できるようにしておく方がよいでしょう。