New Relic Workflowのエンリッチメントでログを取得する
このページについて
本記事は New Relic Advent Calendar 2022 の16日目です。
New RelicにはWorkflowという機能があります。
さらにWorkflowのエンリッチメントを使うと、ログの中身を取得できるのでご紹介します。
Workflowとは
ワークフローでは、課題に関する通知をいつ、どこで受け取るかをコントロールし、適切な情報を関連する担当者やチームにトンネリングし、課題の通知をNew Relicの追加データで充実させることができます。
https://docs.newrelic.com/jp/docs/alerts-applied-intelligence/applied-intelligence/incident-workflows/incident-workflows/
つまり、アラート条件に合致した問題をどのように通知させるか設定できるということです。
例えば、WarningレベルのアラートならばSlack通知のみにしたい場合など、細かくアラート制御したいケースで活用できます。
New Relicコンソールでは、「Alerts & AI」→「ENRICH & NOTIFY」セクションに「Workflows」があります。

NotificationからWorkflowへ
ちなみに、少し脱線しますが、今まで通知機能として使っていたNotification Channelは廃止され、Workflow/Destinationで設定していく必要があります。
エンリッチメントとは
エンリッチメントは、アラート通知にNRQLクエリの結果を追加することで、アラート通知に追加のコンテキストを与えることができます。
https://docs.newrelic.com/jp/docs/alerts-applied-intelligence/applied-intelligence/incident-workflows/incident-workflows/#add-workflow
Workflowにはエンリッチメントという設定があります。
例えばログ監視でのイメージはこんな感じで、通知する前にクエリ処理を入れることができます。

そもそも設定するきっかけ
「FROM Log …FACET message」を使用したNRQL条件はブロックされ、無効になります
破壊的な変更を含む重要なお知らせ (;゚ Д゚)ゴクリ・・・
2022年6月8日に「FROM Log ... FACET message」を含むクエリを使用したNRQLアラート条件は使用できなくなります。いますぐのアラート条件の見直しをお願いします。
ログを取得するには、「エンリッチメント」をサポートする新しいワークフロー機能を使用します
通知を送信する前に実行されるNRQLクエリをワークフローに追加することができます。そのクエリを使用して、特定のパターンに一致するログ行を取得することができます。
上記の通り、Workflowのエンリッチメントを使うことが代替機能として挙げられていました。
できなくなることの影響
以下のように、FACETに message を指定してNRQLを作成することができません。
「FACET message」とすることで、ログメッセージ(message)を一意にして、それぞれでアラートをあげることができていましたが、それができなくなりました。
SELECT count(*) FROM Log FACET aws.accountId, aws.awsRegion, label.Name, aws.ec2InstanceId, message WHERE aws.accountId ='123456789012' AND filePath = '/path/to/error.log' AND message RLIKE '.*ERROR.*'
Workflowでやってみる
「FROM Log ... FACET message」でやっていたことを、Workflowのエンリッチメントを使って設定してみます。
設定の流れ
- Workflowと紐付けるCondition設定
 - Workflowの設定
 - エンリッチメント設定
 - 通知先設定
 
1. Workflowと紐付けるCondition設定
「FACET message」はもう使えないので、それを除外して設定します。
SELECT count(*) FROM Log FACET timestamp, messageId, aws.accountId, aws.awsRegion, label.Name, aws.ec2InstanceId WHERE aws.accountId ='123456789012' AND filePath = '/path/to/error.log' AND message RLIKE '.*ERROR.*'
FACETについて
元々はFACETに message を含めていましたが使用できないため、 messageId を含めることで一意にできるため入れておきます。(timestampも念のため入れました)
2. Workflowの設定
Filter dataでは、どのようなissueを通知したいかをattributeを使ってフィルターしていきます。
今回はテスト用のPolicyのissueに対して通知するように設定します。

3. エンリッチメント設定
Additional settings を選択して開きます。

Enrich your data を有効にします。

以下のエンリッチクエリを設定します。
アラート対象に対して「SELECT message」をして、ログメッセージ(message)を抽出していきます。
SELECT message FROM Log WHERE aws.accountId = '123456789012' AND messageId = {{accumulations.tag.messageId}}

 ポイントは messageId = {{accumulations.tag.messageId}}
NRQLで「FACET messageId」とした場合、この accumulations.tag.messageId という変数に値が格納されます。(サポート確認済み)
基本的にはこのドキュメントを参照すれば、使用可能な変数がわかるのですが、これは書いていませんでした。
 messageId = {{accumulations.tag.messageId}} がない場合どうなるか
NRQLで同じタイムスタンプのログが複数件入ってきた時に、エンリッチクエリでその複数ログメッセージを拾ってしまいます。(1アラートに対して、複数ログメッセージが添付される。)

元々「FROM Log ... FACET message」の時は、「FACET message」が効いているため、ログメッセージ(message)は一意に絞られて通知できていましたが、複数件まとめられると困ります。
それに対し、エンリッチクエリで messageId = {{accumulations.tag.messageId}} を使うと、たとえ同じタイムスタンプのログでもmessageIdは一意となっているため、ログを一意に抽出できるようになります。(1アラートに対して、1つのログメッセージが添付される。)
4. 通知先設定
SlackとEmailのケースを例にして確認します。
Slack
Slackに通知させる場合は、Notify設定で単純にSlackと連携させるだけで良いです。
通知内容に以下のように Enriched data が追加されます。
(ただ、画像ファイルとなっているので、ここはテキストにしてほしいです。。)

メール通知させる場合は、Emailを選択した後に以下の設定を入れます。
ここでは通知先メールアドレスの他に、メールサブジェクトや本文中に入れることのできるCustom Detailsを設定できます。
デフォルトではEmail subjectには、{{ issueTitle }} のみ入っています。
エンリッチクエリ設定時につけた名前 {{[Log lines that match a pattern]}} がここで使えます。

ただし、今回のエンリッチクエリでは accumulations.tag.messageId を使用しているため、少し工夫が必要になります。
{{[Log lines that match a pattern]}} に入ってくるのが以下の設定の差で変わってきます。
- エンリッチクエリに 
accumulations.tag.messageIdを使用しない場合 
[{"timestamp":1670918933370,"message":"TEST newrelic workflow"}]
- エンリッチクエリに 
accumulations.tag.messageIdを使用した場合 
{accumulations={"tag":{"messageId":"('210f734e-3c1d-4156-9c69-e61e97a1b707')"}}, result=[{"timestamp":1670918933370,"message":"TEST newrelic workflow"}]}
抽出メッセージが少し長くなってしまいます。
accumulations.tag.messageId という変数を使ったことで、抽出結果に accumulations.tag.messageId を指定していないのに、その値が明確にわかるよう含まれてしまう仕様のようです。
そこで、 {{[enrich name].result}} のように指定することで、当初の抽出メッセージと同様の形となります。
- 
{{[Log lines that match a pattern].result}}の場合 
[{"timestamp":1670917974713,"message":"TEST newrelic workflow"}]
Email設定例
- Email subject
 
{{state}} {{accumulations.conditionName}} {{[Log lines that match a pattern].result}}
- Custom Details
 
- Log lines that match a pattern
{{[Log lines that match a pattern].result}}
メール確認
Email subjectで設定していたログメッセージが入っていることを確認できます。

メールの途中には、Enriched data やCustom Detailsで設定していたログメッセージが入っていることを確認できます。

まとめ
色々詰め込んで書いてしまいましたが、Workflowのエンリッチメントを使ってログを取得することができました。
エンリッチクエリを工夫することでログ監視の幅が広がると思います!
Discussion