または Cloud Functions で httpRequest ログを書く方法。
Cloud Logging (もう Stackdriver ブランドなくなりましたね)の好きな機能に、リクエスト内のログをまとめて表示する機能がある。アプリケーション内での一連のログをまとめて追えてとても便利。
という先達のエントリで GAE 環境について書かれているように、Cloud Functions でもリクエスト内でのログを Cloud Logging 上でまとめて表示したい!!
先のエントリでも書かれているように、ログを紐付けるための条件は
- parent, child で同一 GCP プロジェクトであること
- parent, child で
logName
が別々であること - parent が
httpRequest
であること trace
が同一であること
である。
経験上 Monitored Resource は region が異なっていてもログが紐付けられるし、GAE Standard のように httpRequest.requestUrl
がなくて protoPayload
に同等の構造が入っていても httpRequest
と見なされて parent として扱われるみたい。
しかし Cloud Functions は、httpRequest
ログを書かないので、紐付ける parent が存在しない... のだけど、Logging のクライアントライブラリを使って httpRequest
相当の構造を書くことで、parent になるログを作ることができる。
httpRequest
の構造自体は Logging の LogEntry の構造を参考にく立てればよい。他にも規定のフィールドについて書いてあるので、グループ化に興味なくとも一度みておくとへーってなると思う。
そしてリクエストヘッダの X-Cloud-Trace-Context
に ${traceId}/${spanId}
がやってくるので、traceId
を取り出してアプリケーションログといっしょに書けば晴れてログをまとめることができる。
とはいえ都度作るのは割と面倒だし、個人的にもよく使いたいので、httpRequest
を書く Express ミドルウェアを npm package として作っておいた。
実装はほぼ @google-cloud/logging-winston の提供するミドルウェアと同じである。Cloud Functions では明に書かないように作られていたし、Apache V2 の範囲で改変してよかろうと、ちょこちょこいじって package 化した。
これ単体では httpRequest
を書くだけなので、@google-cloud/logging-winston や @google-cloud/logging-bunyan などの trace
をいい感じにハンドルしてくれるロガーを使うか、trace
を自前で書く必要がある。
自前で trace
をハンドルするならこういう感じ
const { Logging } = require("@google-cloud/logging"); const projectId = "<YOUR_PROJECT_ID>"; const logging = new Logging({ projectId }); const log = logging.log("application_log"); exports.app = async (req, res) => { const [traceId] = req.header("X-Cloud-Trace-Context").split("/"); const trace = `projects/${projectId}/traces/${traceId}`; // log.entry(metadata, data) const entry = log.entry( { trace }, { message: "this is a message", obj: { key: "value" } } ); await log.write(entry); };
という感じで、ログを紐付けて幸せに暮らしています。
新しいプレビュー版のログビューワーは念願の child のログも展開することができる!!
その他
Cloud Functions は Default Credential 問題が起きやすいので、ログを書くならサービスアカウントキーも常に指定しておくのがよいと思う。
とはいえ、未だに nodejs10 runtime が Beta とか言ってるのは厳しいものがある。Storage や Firestore イベントで起動する必要もなくて、ちゃんと trace したり調査したいような規模ならもう GAE でいいんじゃないかな...と思う。
4/20 から Cloud Function のデプロイに Cloud Build API が必要という予告もあったし、デプロイサイクルや Default Credential 問題なんかが大きく改善しないかな〜楽しみですね。
COVID-19 でオンライン開催に変わった Google Cloud Next ’20 はその後音沙汰無い!!!