本記事では New Relic テクニカルサポートにお寄せ頂くことが多いお問い合わせ内容をもとに下記のアラートに関連するいくつかのトピックについて解説します。
- シグナル
- インシデント
製品ドキュメント の補足として、意図通りのアラート設定を行うまたはトラブルシューティングのヒントとして頂ければ幸いです。
プレビューチャート と Signal History の違い
アラートコンディション編集時に表示されるプレビューチャート と 編集後に表示される Signal History チャートは、それぞれ異なるデータを描画したものです。アラートコンディションの編集時に表示されるプレビューチャートは、受信済みのデータを元にしたチャートで編集している設定内容 (Window Duration, NRQL) を過去に受信したデータに対してシミュレートして表示した図となります。
例えば、アラート用 NRQL が FROM SystemSample であれば、SystemSample のデータを利用してプロットしたものとなります。
( UI でも注意書きとして記載されていますが)
そのため受信した時刻データ (タイムスタンプではなく) 情報がないため、信号損失やギャップ埋め または Event timer などで 実際の値 (アラートの評価値(シグナル値) ) までは再現されません。
一方で、Signal History は、アラートコンディションが有効化されたあとで、受信したデータに対して、そのコンディションの設定に基づいて評価された値 (Signal Value) が表示されます。
アラート用の評価値は NRQL に記載したデータソース (SystemSample や Metric ) ではなく、NrAiSignal というイベントソースに別途記録されます。
NrAiSignal の内容は、ストリーミングデータを元に算出した値 (リアルタイムで受信したデータに対して集計処理したデータ) であるため
アラートコンディションが有効化されたあとに受信した対象データのみが表示されることになります。
filter 関数を使っているがシグナル 0 にならない
他のブログポストなどで filter 関数の利用方法をご紹介しておりますが、仕組みを誤認される場合があるようです。 filter 関数を利用しても、対象データの受信がない場合は シグナルは生成されません (データなし)。
filter 関数とアラートパイプラインでの処理につきまして、少し例を踏まえて解説させていただきます。 また、本回答では、WHERE が複数回登場しますので、誤解を避けるために filter 関数内の 条件に関しては (小文字の) where , filter 関数外の外側の条件に関しては (大文字) WHERE と記載します。
例:
SELECT filter(count(*), where result = 'FAILED') FROM SyntheticCheck WHERE monitorName = 'My Favorite Monitor'
filter 関数の基本的な考え方は フィルタリング (抽出) をイメージしていただければと思います。 上記の SyntheticCheck の例を元にすると
- SyntheticCheck イベントで受信したデータの中で WHERE モニター名が 'My Favorite Monitor' のものをこのシグナルの対象データとなります その対象データを受信した場合、出荷のタイミングで SELECT 集計関数 が実行されます。 また、対象データの受信がない場合は、SELECT は実行されません。
- 集計関数である filter では、対象データの中で where result が 'FAILED' のものを抽出します。 抽出したデータに関して count(*) (任意のカラムをもつデータ数のカウント) を行います。 このとき抽出条件 (where) に該当するデータがない場合は、0 が返ります。
ここでのポイントは、 filter 関数を利用する場合でも、外側の WHERE 条件に合致する対象データの受信がない場合は、SELECT が行われないという点です。
ログ監視でアラートが発報されない (不定期データのシグナルが作成されない)
いくつかの原因が考えられますが、まずは、Streaming Method が Event timer (または Cadence) になっているかを確認してください。
ログ監視に関わらず、不定期なイベントを検出されたい場合、Event flow は適切ではありません。
Event flow では、後続のデータを受信したタイミングで集計処理が行われます、受信しなかった場合は集計処理がされません。
この意味で、インフラストラクチャなどの定期的に対象データを受信し続ける対象向けの方法となります。
例えば、WD 3分、遅延 5分の場合は、13:00 - 13:03 期間に受信したデータは、13:08 以降のデータを受信した際に集計されます。
より具体的なケースとして、次のような時刻 (HH:mm:ss) の対象データを受信した場合を考えてみます。
13:00:15, 13:01:20, 13:06:40 (5分後) そして 13:30:50 (およそ 30分後)
この場合、13:00-13:03 のウィンドウに所属するデータは 最初の 2つ (13:00:15, 13:01:20) が該当します。
そしてこのウィンドウが集計されるのは 13:08 以降のタイムスタンプデータを受信したタイミングとなるので、13:30:50 のデータを受信したタイミングとなります。
つまり 13:00-13:03 のウィンドウ データが集計処理 (シグナルが作成される) のは 13:31 付近 (13:30:50) となります。
また、後続データが 65分以上受信がない場合は未集計データは破棄されます。
一方で、Event timer では対象データを受信したあとで、設定したタイマーのカウントダウンが 0 になったタイミングでデータの集計処理が行われます。
後続のデータ受信なしで、集計処理が行われます。
また、Cadence の場合は、Delay 時間経過後に出荷処理が行われるため、後続データなしでシグナルが出荷されます。
Event flow/timer との差はデータ受信をトリガーとしない点です。そのためデータ受信の遅延が大きい場合は、先に締め切られてしまうという場合がございます。
Streaming Method の動作の違いにつきましては下記のブログポストなどをご参照ください。
[NRQLアラート条件に追加された新しい集計方法とどれを選ぶべきかの指針 > Event Timer]
https://newrelic.com/jp/blog/nerdlog/new-aggregation-methods-for-nrql-alert-conditions
ログや 4xx, 5xx エラーアクセスに関する発生を検知するためのアラート設定において
アラートコンディション作成後に対象データは受信しているが、Signal History または NrAiSignal にて「シグナルが発生していない」という場合は
Streaming Method が Event flow になっていないことをご確認ください。
閾値設定のケアレスミス (above 1)
単純ですが、閾値設定で "above 1" (1 より大きい) を 1 以上 と誤認されてしまっているということがございます。
1 以上の場合は、"above or equal to 1" または "above 0" (0 より大きい) と設定ください。
(Event flow 利用で) 通知タイミングが遅い
Synthetic モニターなどで、エラー発生から 15~30分遅れてアラート通知された、という場合、Event flow の仕様上の問題である可能性が考えられます。
Synthetic モニターなどの定期的に発生するデータが対象の場合であっても、データの受信周期が長い場合 (15分など) は Event flow は適しません。
Event flow では後続のデータを受信したタイミングで集計処理が行われるため、データ受信周期が長いとその分集計処理は後ろ倒しされます。
例えば、Window Duration (WD) 15分、遅延 1分の場合は、Synthetic モニターが 15分周期での実行だった場合で Synthetic モニターが下記のように 12:15 に Failed となった場合を考えます。
12:00:15 Success
12:15:15 Failed
12:30:15 Failed
12:45:15 Failed
12:15:15 のデータを含むアラートのウィンドウは 12:15 - 12:30 となりますが
Event flow (遅延1分) の場合は、12:31 以降のタイムスタンプデータが処理されるタイミングで 12:15 - 12:30 のデータは集計処理されます。
従って、12:45:15 の Synthetic モニターのデータが処理されると 12:15 - 12:30 のデータが出荷され、インシデント/Issue が作成され、アラート発報となります。
結果として、12:15 に Failed となったのに、通知は 12:47 だった、ということが発生してしまいます。
(上記のような場合、
Event flow 利用で WD が 1分であれば、12:30:15 のデータ受信で 12:15 - 12:16 のシグナルが出荷されることになりますが、それでも 15分以上経過してします。)
基本的な回避方法としては、Event timer (または Cadence) に変えてしまうことです。
閾値設定が 1度でも検知したら違反という場合は、Event timer (タイマー5秒)、WD 1分などの設定で、閾値超過データ受信後、速やかに出荷処理させてインシデント作成させて、通知するように設定します。
閾値設定の解釈間違い (10分間に N回以上)
これも単純な解釈ミスですが、10分間に N回以上出力された場合を違反とされたいという場合に下記のような閾値をされてしまい、意図通り動作しないという場合がございます。
- Window Duration: 1分
- result >= N for at least 10分
上記の設定は
(WD) 1分ごとの集計値 が N を超過する状態が 10分間継続した場合、違反とする
という意味となりますので、10分間で N回以上発生とはなりません。
より実用的な表現としては、閾値 10分 は WD (1分) の10個分であるため、シグナル値が 10回連続 N 以上だった場合は閾値違反、という解釈となります。
10分間で N回以上発生した場合、閾値違反とされたい場合は、Window Duration を 10分に変更いただければ意図通りとなるかと思います。
- Window Duration: 10分
- result >= N for at least 10分
この場合は、閾値 10分 は WD (10分) の 1個分であるため、シグナル値が 1回 N 以上だった場合は閾値違反、という動作となります。
インシデントが閾値未満になってもクローズされない
Window Duration と閾値期間が合致していない場合の閾値による回復判定では、下記の仕様のため注意が必要です。
閾値による回復判定は、at least once in でも for at least でも同じで閾値期間のすべての集計値が閾値未満の値となると、回復と判定されます。
また、Slide by を利用していない場合は、連続した期間である必要があり、シグナル値が存在しない時間帯が存在すると回復と判定されません。
具体例をあげると
Window Duration (WD) が 1分で、閾値が result >= 96 at least once in 5分、と設定された場合。
違反判定では、at least once in であるため、1度でも 96 以上のデータが出荷されれば、違反となりますが
回復判定では、5回連続で 96未満のデータが出荷されなければ回復とは判定されません。
違反を判定する期間と回復と判定する期間を同じにされたいのであれば、WD と閾値期間を同じとするように変更ください。
- 1分間のデータで判定する場合
閾値期間を 5分 -> 1分に変更
WD 1分 (変更なし) で、閾値を result >= 96 at least once in 1分 - 5分間のデータで判定する場合
WD を 1分 -> 5分に変更
WD 5分 で、閾値 result >= 96 at least once in 5分 (変更なし)
参考: インシデント (アラート) で回復判定されないときに確認すること > 静的閾値設定における違反・回復の条件
信号損失閾値が極端に短い場合
信号損失と判定させるまでの期間が短い場合、シグナルの出荷よりも前に信号損失イベントが発生してしまいます。
信号損失が発生すると未出荷のデータは破棄されます。
- Event timer でタイマーが 1分、信号損失閾値 30秒の場合
Event timer 方式の場合、データ受信後にタイマーのカウントダウンが開始され、0 になったら、シグナルの出荷処理となるため
タイマーの時間より 信号損失までに時間が短い場合、先に信号損失が発生してしまいます
信号損失のクローズアクションにて、作成されたインシデントをクローズさせたいという場合、インシデントが作成される前に信号損失が発生してしまうということが起こります。
- Event timer でタイマーが 5秒、信号損失閾値 30秒 (クローズアクション) の場合
Event timer 方式に限りませんが、どの方式でもシグナルの出荷処理からインシデント作成までには30秒~1分程度かかります。
継続したデータ受信がない場合、インシデントが作成される前に信号損失が発生 (クローズアクションの対象インシデントは存在しない)、
その後、インシデントが作成されるという場合があります。
信号損失のクローズアクションは、後から作成されたインシデントには適用されませんので、インシデントがクローズされないということが起こりえます。
信号損失閾値が 30秒でもインフラエージェントからのデータのようにより短い時間間隔でデータ受信をしている場合は問題ありません。
データ受信間隔よりも信号損失までの時間を短く設定されている場合は注意が必要です。
基本的には、信号損失閾値の時間は余裕を持たせた時刻を設定いただくのがよいと思います。
Event flow 利用では データ受信間隔または WD の 2~3倍以上。Eevnt timer 利用では タイマー+2-3分以上で設定いただくのがよいかと思います。
シグナルロスト (信号損失) アラートが発生したが、問題なさそうだった
信号損失は、対象データを一定期間受信できなかった場合に発生します。これは timestamp (タイムスタンプ) 値ではなく、インジェスト時刻で判定されます。
アラート発生後にタイムスタンプデータを確認しても特に問題はなかったという場合は、データの収集遅延が発生している場合などが問題の場合があります。
エージェント経由での収集で、発生した場合は、サーバ〜システムのネットワーク環境などのユーザの環境の場合やインターネットの経路上の問題、または New Relic 側に問題があった場合などが考えられます。
インフラエージェントのログやあるいは、ネットワーク機器のログなどでユーザ環境で問題がなかったかなどをお問い合わせ前にご確認いただければと思います。
また、API ポーリングなどクラウド連携の場合は、ベンダー側の公開が遅延するような場合もございます。
ポーリング周期を 5分おきにしている場合などは、遅延がない場合でもインジェスト時刻とデータのタイムスタンプには、数秒~5分程度の差が存在します。
例えば、5分ポーリングの収集データにおいて、信号損失を 10分で設定されている場合は
いずれかの処理が数分遅延してしまい、1ポーリングの遅延となり 10分が経過してしまい検知するというパターンもございます。
1ポーリング分 (5分) の遅延は許容できるという場合は、信号損失を 10分ではなく、11分や 12分に微調整いただくとよろしいかと思います。
シグナルの集計処理で error となる
NrAiSignal をクエリすると下記のような error にて、シグナルの集計処理に失敗しているという場合があります。
Non numeric (string) value cannot be evaluated.
評価値が 文字列データであるので、集計評価ができないというエラーの内容となります。
例えば、下記のようなアラート用 NRQL だった場合で、SELECT の対象項目が数値データなかった場合、上記のようなエラーが発生します。
SELECT latest(processorCount) FROM SystemSample WHERE processorCount IS NOT NULL
一見、数値のように見えても文字列である場合がありますので、QueryYourData で json 型での出力させて 文字列型データ (ダブルクォートで囲われている) でないことなどをご確認ください。
文字列データが入らないような場合は、numeric 関数で数値に変換して対応ください。
SELECT latest(numeric(processorCount)) FROM SystemSample WHERE processorCount IS NOT NULL
Non numeric (null) value cannot be evaluated.
先と類似ですが、評価値が null データであるので、集計評価ができないというエラーの内容になる場合があります。
例えば、下記のようなアラート用 NRQL だった場合で、SELECT sum() の対象がディメンショナルメトリクスの場合、発生する可能性があります。
SELECT sum(`aws.applicationelb.HTTPCode_ELB_5XX_Count`) FROM Metric WHERE entity.name = '...'
aws.applicationelb.HTTPCode_ELB_5XX_Count は数値データですが、WHERE では entity.name しか指定されていないため aws.applicationelb.HTTPCode_ELB_5XX_Count を持たないデータも対象データと判定されてしまいます。 結果として、存在しない項目 (null) に対して sum() を実行することになり、エラーとなってしまっています。
WHERE 条件で metricName を限定するように追加いただくなどで回避ください。
SELECT sum(`aws.applicationelb.HTTPCode_ELB_5XX_Count`) FROM Metric
WHERE entity.name = '...' AND metricName = 'aws.applicationelb.HTTPCode_ELB_5XX_Count'
日次ジョブが実行されなかったことを監視したい
New Relic のアラート設定では、対象データの受信をきっかけに処理が行われるため 対象データの受信がない場合のアラート設定は難しいです。
しかし、信号損失設定は 48時間まで設定ができますので、前回のデータ受信から 24時間以上データ受信がない場合、シグナルロスト (信号損失)として検出することは可能です。
ジョブが実行される、または終了するとログが出力され、New Relic にログが転送されるというような場合は、該当ログに対してアラート設定、 Event timer または Cadence で、信号損失を Open アクションで 24~25時間程度で設定いただくと対象ログの出力がなかった場合に Signal lost のインシデントが作成されるという動作となります。
ただし、信号損失は最後のデータ受信からの時間経過で発生しますので、一日に複数回出力される場合や数日ぶりに出力されるような場合などには対応できません。 ログメッセージに時刻データなどがある場合は、WHERE 条件で指定することで、より対象データを狭め、精度をあげることが可能かもしれません。
参考: NRQLアラート条件を作成する > 信号損失の閾値を設定
上記のような単純化ができず、より複雑な監視要件であるという場合は、デフォルトのアラート設定では対応が難しいように思います。 そのような場合は、API を介して NRQL を実行することは可能ですので、ユーザ環境または Synthetic モニターの Scripted APIなどを用いて NerdGraph API より過去 24時間のログ数を取得するような NRQL を定期的に実行し、そのデータをイベントデータとして NewRelic に送信する、というような方法で実現できる可能性がございます。
下記のブログでは Synthetic の Scripted API を用いたオリジナルアラートの実装例を紹介しております。
参考: 定期実行ツールを利用したアラート評価 > Synthetic monitor を利用したアラート評価例
スクリプトなどを作成いただく、または定期的な実行環境を準備していただく必要がございますが、要件を満たすアラートを設定されたい場合などはお試しください。
本ブログに掲載されている見解は著者に所属するものであり、必ずしも New Relic 株式会社の公式見解であるわけではありません。また、本ブログには、外部サイトにアクセスするリンクが含まれる場合があります。それらリンク先の内容について、New Relic がいかなる保証も提供することはありません。