先に申し上げると・・
本記事の対処方法と同様の回避方法がNew Relic社のブログで紹介されています。
(「2. ログパーシングの利用」部)
多くのケースではParsingRuleの利用で回避するのが管理上もシンプルで良いと考えます。
一方、正規表現では表現しづらい場合や条件分岐を伴うAttributeの付与が必要な場合は、本記事でご紹介するLuaスクリプトの活用も有用かと思いますので、参考になれば幸いです。
NRQLの複雑化
New Relicでログ監視をしている且つブラックリスト方式の場合、検知したくない除外文字列がどんどん増えていくケースはないでしょうか?
除外条件を追加した当初は数が少ないため、「WHERE句の条件追加が1つ追加されただけですね~はいよ~」という感じかと思いますが、これがどんどん増えていくと最悪、視認性が悪く地獄のようなNRQLが出来上がってしまいます。
-
除外条件が1つのパターン
レベルがERRORかつNOT LIKEで指定した文字列以外のmessageだったら条件に一致。
このぐらいなら全然いいですね~

-
除外条件が5つのパターン
サンプルの文字列がシンプルなのでまだいいですが、長いなどの難解な文字列だと少し苦しくなるかも・・

-
めちゃくちゃある
もう見てられない。サンプルなので同じ条件をつらつらと書いてただけですが、これでもだいぶつらい。実際のケースでは全部違う条件になると思いますので・・つらすぎる

最後の例はだいぶ極端ですが、NOT LIKE句が増えまくって見づらくなることは確定ですし、NRQLの文字数にも上限があるので、除外条件を増やしていくやり方はどこかで破綻すると思います。
今回はこのようなNRQLにならないようLuaスクリプトを使って回避する方法をご紹介させていただきます。
どうやって回避するか
New Relicにログが送られた時点で、除外対象か否かを判定できるAttributeをLuaスクリプトを使って付与します。
そして、AlertConditionは前述の例にあるようなNOT LIKE句でmessageに対して「除外文字列が含まれているか?」を見るのではなく、「除外対象のAttributeの有り/無し」で判断するようにします。
このようにすることで、見やすくスリムなNRQLでログ監視が可能になります。
- ざっくり流れ
最終的な実装内容
-
除外対象のログの場合
-
最終結果(AlertCondition)
そもそもLuaスクリプトとは
Luaは組み込み用途のプログラミング言語で、拡張用としてアプリケーション側に組み込んで利用することが多いそうです。
New Relicにおいてはログ転送の時に今回のようにログを加工したいよといった要件をかなえるためにInfrastractureAgentに標準で内包されているもののようです。
※解釈ミスってたらご指摘ください・・。
検証環境
Luaスクリプトの設定
必要なファイルは以下の3つになります。(ファイル名は任意です。)
- ext-lua-logging.yml
- ext-lua.conf
- ExcludeMessage.lua
これらを以下のフォルダに作成すると動作します。
C:\Program Files\New Relic\newrelic-infra\logging.d
1. ext-lua-logging.yml
ここでは純粋にFluentbitのConfファイルを定義するだけです。
logs:
- name: external-Lua-config
fluentbit:
config_file: C:\Program Files\New Relic\newrelic-infra\logging.d\ext-lua.conf
2.ext-lua.conf
InfrastractureAgentに内包されるFluentbitに対してどのファイルが対象かなど具体的な定義を入れていきます。
[INPUT]部には対象のログのパスやFILTER条件で使用するタグの情報を定義しています。
[FILTER]部はマッチしたタグ(Exclude)の場合、記載のLuaスクリプトを実行するという定義になります。
[INPUT]
Name tail
Path C:\temp\Alert.log
Path_Key filePath
Tag Exclude
Read_From_Head Off
Skip_Long_Lines On
DB C:\Program Files\New Relic\newrelic-infra\logging.d\Alert.db
Key message
[FILTER]
Name lua
Match Exclude
script C:\Program Files\New Relic\newrelic-infra\logging.d\ExcludeMessage.lua
call enrich
3. ExcludeMessage.lua
これがスクリプトファイルになります。
「ext-lua.conf」で条件にマッチしたログの中身(message)を見て、IF文で除外パターンに合致しているか?を判定しています。合致した場合は除外対象ですねということで除外対象用のAttribute([ext.IssueExclude]と[ext.IssueExcludeMessage])を追加で付与します。
条件に当てはまらないログの場合は個別のAttributeは付与せずに、そのまま処理を終えます。(そのままNew Relicへ送るイメージ)
function enrich(tag, ts, record)
local m = record["message"] or record["log"]
if m == nil then
return 1, ts, record
end
-- messageの中に除外文字列「New Relicに送ったよ_A」が含まれていたら正
if string.find(m, "New Relicに送ったよ_A") then
record["ext.IssueExclude"] = "On"
record["ext.IssueExcludeMessage"] = "New Relicに送ったよ_A"
-- messageの中に除外文字列「New Relicに送ったよ_B」が含まれていたら正
elseif string.find(m, "New Relicに送ったよ_B") then
record["ext.IssueExclude"] = "On"
record["ext.IssueExcludeMessage"] = "New Relicに送ったよ_B"
else
end
record["log"] = nil
return 1, ts, record
end
確認結果
準備が出来たところで、ログに以下3種類のmessageを書き込んでみました。
想定通り、除外対象のmessageに対してAttributeが付与されることが確認できました。
- 除外文字列(「ExcludeMessage.lua」のIF文で指定した文字列)
- New Relicに送ったよ_A
- New Relicに送ったよ_B
| messageパターン | 除外対象 | 結果 |
|---|---|---|
| ERROR-MESSAGE New Relicに送ったよ_A | 〇 | 想定通り。Attributeが付与 |
| ERROR-MESSAGE New Relicに送ったよ_B | 〇 | 〃 |
| ERROR-MESSAGE New Relicに送ったよ_C | × | 想定通り。除外対象ではないのでAttributeはされない |
繰り返しになりますが、上記より除外対象のログには除外対象用のAttributeが付与されることが確認できましたので、ログ監視用のAlertConditionのNRQLも以下のように簡素でわかりやすく表現が可能になります。
その他の活用
- 上記のLuaスクリプトではもう1つのAttribute[ext.IssueExcludeMessage] を付与するように設定しています。
これは除外文字列自体を別のAttributeとして定義しています。
⇒このAttributeを使ってDashboardのウィジェットに出しておくと、いつでも除外条件の確認が出来るようになるのでドキュメントを見る手間も省けるかと思いますので、参考にしていただければと思います。
仕様上、以下2点を満たすケースのみしか表示されないので、ご注意ください。
- 過去にログとして出力されている。 ※Luaスクリプトで除外設定を入れたが、一度もログが出力されない場合は表示されません。
- 指定した期間に対象ログが出力されている前提です ※例だと指定した期間が直近30日間ですので、その間に出力したログしか表示されません。
除外対象のログが頻繁に出力されている場合は問題ないですが、たまにしか出ない場合はウィジェットに表示されません。
もれなく表示させたい場合は、別途Flexで定期的に除外文字列を飛ばすか、LockupTableを使うなど本対応とは別で設定が必要になります。。
https://docs.newrelic.com/jp/docs/nrql/using-nrql/lookups/
FROM Log SELECT latest(timestamp) AS '最後に出力したタイミング' WHERE ext.IssueExclude = 'On' FACET filePath AS '対象ログファイル', ext.IssueExcludeMessage AS '除外文字列' SINCE 30 days ago LIMIT MAX
まとめ
- ParsingRuleでだいたい同じことが出来るけど、Luaスクリプトでもいけまっせ
- ParsingRuleで対応できない複雑な要件ならLuaスクリプトの活用で解決できる(かも)
ご参考になれば幸いです。





