はじめに

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側でも意図通りに除外設定が機能するようになりました。

おわりに

「設定は正しいはずなのに動かない」という時、原因はシステムではなく「データそのもの」にあるかもしれません。
人間には同じ「空白」に見えても、コンピュータにとっては全くの別物なため、画面上の表示だけで判断せず、一度バイナリを確認してみてはいかがでしょうか。