ロギングをどうするかで困っていた。AWS Lambdaでは、プリント出力したものがCloudWatchに保存されてとても便利なのだが、考えもなしにとりあえずポンポン入れていたところ、確かに情報はあるので追えないことはないんだが、地道に時間にあたりをつけて検索するなど、非常に泥臭い作業が要求され、なにかとつらかった。
APIのコール回数など集計したいという要件も出てきて、重い腰をあげてロギングについて頑張って考えました、という話。
AWS Lambdaで、何も考えずにとにかく必要そうなのをログ出力しているが、フォーマットも何も整っていないため、ほしい情報を探し当てるのも一苦労だ。
ログをjson形式に構造化させてやると、CloudWatch Insightsでクエリを投げて検索・集計することができる。ということで、ユースケースに対応できるように、ログ出力について考えたい。
ユースケースとして以下を考慮。
前提条件として、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で草稿を作りました。よかったら見ていってね(宣伝)。
その他、参考にさせていただいた記事です。ありがとうございました。
IoT関係で技術者としてお仕事しています。 趣味のブログは9年目に突入しました。 16性格診断はINFP-T。どんな心理テストでも高い内向性を叩き出せます。 友人とWebサービス開発してます。https://qnqtree.com
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント