AWS Lambdaは関数が呼び出されると自動でCloudWatch Logsにログを吐く。このログの監視についてベストプラクティスを考えてみた。
これまでやってきた検証では、Lambdaとは無関係のロググループにエラー出力させて、そのログのサブスクリプションフィルタのターゲットにログ監視用Lambda関数を指定している。一方、Lambda自体のログを監視するには若干捻りが必要そうである。
以下記事のように、適当なLambda関数のログにサブスクリプションフィルタを設定してエラー検知 & SNS連携でメッセージ通知させること自体は問題ない。
CloudWatch Logsの特定文字を検知してログ内容を通知するLambda Function
一応、実際に試してみた。
- Lambda① 適当な処理を実行
- Lambda② ログ監視用関数。SNSと連携してメール送信
Lambda①のログにサブスクを設定。ターゲットはLambda②とする。これだけなら動作は想定内で、Lambda①でエラーログを1回発生させたら、Lambda②により通知メールが1回送信された。
しかしLambda①も監視用の関数の場合は注意が必要である。例えばその関数がアラーム監視に紐付いている場合の挙動を想定すると:
->Lambda①にエラー要因がなければ、アラームトリガー発生時は設定したSNSに連携され、ログにはエラーが出ない。(ログ監視通知は飛ばない)
ここまではいいとして、気をつけたいのはLambda①にエラー要因がある状態でトリガー発生した場合:
-> Lambdaログにエラーが吐き出され、サブスクが検知 -> ログ監視通知のLambdaが起動し、通知を送信する。
アラーム監視自体で大量にトリガーが発生した場合、Lambdaのログエラーもそれに準じて高騰することになり、2倍に大量通知が飛ぶことになる。やってはいけないレベルではないかもしれないが、ソリューションは検討しておく必要がある。
そして、Lambda①がログ監視用関数の場合はそれ自体にLambdaをターゲットとするサブスクを設定してはいけない。
無限の呼び出しループが作成されるため、ログ配布関数のロググループにサブスクライブすることは避けてください。
つまり、Lambda②のログはLambdaと連携させての監視はできない。他のターゲットなら可能かは不明。どちらにしろ、logsのサブスクは直接SNSに連携できないし、これだけのためにKinesis他のソリューションを採用するのも大袈裟だ。いや、どうしてもっていうなら他の仕組みを実装するしかないけど、自動通知が必須でなければ運用回避でもいいわけで。そんな中以下の記事を目にして、一瞬ハッとした。
エラー出力をする前に、なんのために必要なのか考えないといけない
よく自分も陥りがちなのは、「色々な例外がありそうだからとりあえずERROR出力をする」といったパターンです。とりあえず設定したログレベルは、一度リリースされると改修による不具合発生のリスクや、リソースの都合でななかな変更できない事が多いと思います。
本当に検知や対処が必要なものであればERROR出力は必要です。しかし、ERROR通知を受けた後何もしないのであれば、通知する必要はないのかもしれません。実装の時点で、検知したエラーを元に何をしたいのかを考慮した上で適切なログレベルをつける事が大切です。
Serverless時代のシステム監視、ノイズ通知だらけな日々を経験しての反省点
発想の転換。自分も「とにかくエラーは通知しなければいけない」と思い込んでいたふしがある。ちょっとクールダウンして再検討しよう。