はじめに
New Relicでログ監視(Log Detection)を設定している際、「NRQLは絶対に間違っていないはずなのに、除外したいログが検知されてしまう」という不可解な現象に遭遇しました。
画面上では正しく設定できているように見えても、実は「目に見えない文字」が原因でフィルタリングを潜り抜けていることがあります。今回は、私が解決した「ノーブレークスペース(NBSP)」によるトラブル事例をご紹介します。
起きていた問題
特定の文字列を含むログを除外するNRQLを設定していました。
NOT message RLIKE '.*ERROR \\[Auth\\] Login failed.*'
UI上のログ画面で確認する限り、除外対象のログメッセージには指定した通りの文字列が含まれています。しかし、実際にはこの条件にマッチせず、除外されるべきログが検知され続けていました。
結論
原因は、ログに含まれていた 「スペース」の正体が、標準的な半角スペース(ASCII: 0x20)ではなく、ノーブレークスペース(NBSP: U+00A0)だったこと です。
New RelicのNRQLは文字コードを厳密に区別し、WHERE message LIKE ‘% %’(0x20)というクエリでは、NBSP(0xA0)を含むログをキャッチすることはできないようです。
実際のログをバイナリ確認
なぜこれに気づけたかというと、サーバにログインして生のログファイルをバイナリモードで確認したからです。
実際にログをファイルに書き込み、それを od コマンドでバイナリ確認する手順を再現してみます。
[root@yoshimura-rhel-ec2 log]# printf "ERROR\xc2\xa0[Auth]\xc2\xa0Login failed\n" > debug_nbs.log [root@yoshimura-rhel-ec2 log]# [root@yoshimura-rhel-ec2 log]# [root@yoshimura-rhel-ec2 log]# od -t x1 -c debug_nbs.log 0000000 45 52 52 4f 52 c2 a0 5b 41 75 74 68 5d c2 a0 4c E R R O R 302 240 [ A u t h ] 302 240 L 0000020 6f 67 69 6e 20 66 61 69 6c 65 64 0a o g i n f a i l e d \n 0000034 [root@yoshimura-rhel-ec2 log]#
バイナリを確認したところ、標準的な 20 ではなく、UTF-8でノーブレークスペースを意味する c2 a0 が出力されていました。(Unicodeの U+00A0 は必ずこの2バイトセットで出力される)
この特殊なスペースを標準的なスペース(0x20)に置換してログを出力するようにアプリケーション側を修正したところ、New Relic側でも意図通りに除外設定が機能するようになりました。
おわりに
「設定は正しいはずなのに動かない」という時、原因はシステムではなく「データそのもの」にあるかもしれません。
人間には同じ「空白」に見えても、コンピュータにとっては全くの別物なため、画面上の表示だけで判断せず、一度バイナリを確認してみてはいかがでしょうか。