(追記)AWS Lambda PowertoolsのLogger使え
ロギングをどうするかで困っていた。AWS Lambdaでは、プリント出力したものがCloudWatchに保存されてとても便利なのだが、考えもなしにとりあえずポンポン入れていたところ、確かに情報はあるので追えないことはないんだが、地道に時間にあたりをつけて検索するなど、非常に泥臭い作業が要求され、なにかとつらかった。
APIのコール回数など集計したいという要件も出てきて、重い腰をあげてロギングについて頑張って考えました、という話。
ユースケースを考える
AWS Lambdaで、何も考えずにとにかく必要そうなのをログ出力しているが、フォーマットも何も整っていないため、ほしい情報を探し当てるのも一苦労だ。
ログをjson形式に構造化させてやると、CloudWatch Insightsでクエリを投げて検索・集計することができる。ということで、ユースケースに対応できるように、ログ出力について考えたい。
ユースケースとして以下を考慮。
- ERRORだけ抜き出す
- ユーザー別に叩いたAPIについて集計する
- 詳細な検索ができるように、ハンドラに渡された情報は全部取っておく
前提条件として、node.jsを使っていたりPythonを使っていたりする。そのため、特定の言語のライブラリに依存した解決はあまり好ましくない。
結果
以上の条件を考えて色々調査し、必要なことを考えた結果、以下のような感じになった。
{
"msg": string // フィルタリングできるような固有のメッセージ
"funcName": string // 実行関数
"dateTime": string // ログ出力した時刻 RFC3339 に則る(jsならDateオブジェクトをconsole出力すればよい)
"level": INFO | WARN | ERROR,
"event": object // Lambda関数のeventパラメータをそのまま
"input": object // 必要なやつ
}
levelでログレベルを設定。inputとmsgでフィルタリング、集計を容易に。困ったらeventとfuncNameで頑張って追えるようにしておいた。また、独自フォーマットなので言語やライブラリに依存しない。
このフォーマットはほとんど「AWS Lambda Logging: An Intro How-To and Best Practices | Scalyr」を参考にしています。
以下のような使い方を想定(node.js)。
function logging(msg, funcName, event, level, inputValues) {
const logMsg = {
msg: msg,
funcName: funcName,
dateTime: new Date(),
level: level,
event: event,
input: inputValues
}
if (level === "INFO") {
console.info(JSON.stringify(logMsg))
} else if (level === "WARN") {
console.warn(JSON.stringify(logMsg))
} else if (level === "ERROR") {
console.error(JSON.stringify(logMsg))
} else {
console.log(JSON.stringify(logMsg))
}
}
exports.handler = async (event, context, callback) => {
logging("CallApi", "functions/users/app.handler", event, "INFO", {userId: "testUser"});
}
で、CloudWatch Insightsを使うとたとえば以下のようなクエリを投げて集計できるわけだ。
filter msg like /CallApi/
| stats count(input.userId) by input.userId
運用を通じてブラッシュアップしていきたい。
参考リンク
この記事は、開発中のWebサービスQnQで草稿を作りました。よかったら見ていってね(宣伝)。
その他、参考にさせていただいた記事です。ありがとうございました。
- AWS Lambda Logging: An Intro How-To and Best Practices | Scalyr
- 一番参考にした記事
- Lambdaの本番業務利用を考える① – ログ出力とエラーハンドリング – ナレコムAWSレシピ
- Node.js の AWS Lambda 関数ログ作成 - AWS Lambda
- AWS Lambda/PythonでJSON形式でログを出すベストプラクティス - Qiita
- Node.js の Lambda ログのフォーマットについて - tasuwo's notes
- node-bunyanを使ったAWS Lambdaでのロギング処理 | by Atsushi Nakajo | Medium
- CloudWatch Logs Insightsでログを調査する前に読む記事 | Developers.IO
コメント