あらすじ
とあるAPIからのレスポンスの内容が、どうやら仕様書で共有されていたモノと中身が異なっているということで、どういうレスポンスが返ってきているのかを確認してほしいと言われました。とはいえ、本番環境では1時間に約10万回ものリクエストを送っているため、単純にログにデータを出力すると、えらいことになります。
そのため、受け取ったレスポンス(json
)を.json
形式のファイルを作成して、GoogleCloudStorage
にアップロードすることにしました。ただログを集約したいだけだったので、特に階層は作らず、バケットの直下にファイルをアップロードさせるようにしています。
ファイル名は重複がなく、いつ、どこで受け取ったレスポンスなのかが分かるように以下のように命名をしています。
uuid + timestamp + リクエストしたユーザー名 + 種別(絞り込みのための値) + .json 例: 5300f326-9fcd-d392-798b-5b7a253983ff_2021-10-08-21-45-00_ayatsuzi_student.json
ログをアップロードするところまでは良かったんですが、この後に問題に直面しました。
検索が出来ない
いざ、アップロードされたログを絞り込んで一覧を取得して、問題になっていそうなログを確認しようと思った頃に問題が発生しました。
開発はRubyOnRails
を用いて進めています。GoogleCloudStorage
のAPIを使用するために、Googleより公開されているRuby
用のライブラリを使用する必要があります。他言語でも同様の手順を踏む必要があるでしょう。
公式にサンプルがあるので、真似て書いてみました。どうやらprefix
という引数(Rubyだとdefaultがnil)を渡してあげることで、一覧表示するファイルを絞り込むことが出来るようです。コードサンプルの方にはprefix
にワイルドカードを使って、*.json
だけを絞り込むという感じのサンプルは載っていないのですが、gsutil
の方にはワイルドカードを使ったサンプルが載っていたので、「これ使ってユーザーを絞り込むか」と思い立ちます。
以下のコードを書いてみて、試してみましたが空配列が返ってきます。書き方が違うのかな?と思い正規表現を渡したり....いろいろ試してみましたが、やはり空配列が返ってきます。
# NG bucket.files prefix: 'ayatsuzi' bucket.files prefix: /ayatsuzi/ bucket.files prefix: './*_ayatsuzi'
途方に暮れていたところで、ポカしていることに気付きました。Googleのコードサンプルにこんな記述があります。
# prefix = "Filter results to files whose names begin with this prefix"
文字通り、prefix
から始まるファイルの一覧が取得出来るようです。加えて、上記には説明がありませんが、ワイルドカードを用いた絞り込みは少なくともRuby
製のライブラリには提供されていませんでした。(Python, Goでも出来ないっぽい??)
結果的に、ファイルの一覧を全件取得して、条件式を書いて絞り込みをしようかと思いましたが、どうやら取得可能なファイル数orファイルサイズに上限があるようで、全てのファイル一覧を取得することは出来ませんでした。
結果的にgsutil
を用いてファイル一覧を絞り込むという形に落ち着きました。(最初からそうしろ)
gsutil ls gs:://project-hogehoge/**_ayatsuzi
命名のススメ
prefix
が接頭辞にしか用いることが出来ないため、絞り込みを強力にすることが出来る順に命名するのが良いかと考えます。今回の場合だと、リクエストしたユーザー名
を用いることでデータ数をかなり絞り込むことが出来ます。その次は種別
、その次は...と順に情報を与えていきます。
先ほど、uuid
を重複回避のために先頭に持ってきたのは明らかな失敗でした...。
リクエストしたユーザー名 + 種別(絞り込みのための値) + timestamp + uuid + .json 例: ayatsuzi_student_2021-10-08-21-45-00_5300f326-9fcd-d392-798b-5b7a253983ff.json
副作用としては、一覧に表示されるデータの順番が意図したものではなくなる可能性がありますので、要注意です。 (とはいえ、データ数が多いとそんなに気になりませんし、普通にソートも出来ます)
階層を用いてファイルを管理する場合(例: /2020-02-08/ayatsuzi/student/***.json)にはprefix
を用いて簡単に検索することが出来ます。データを直下に集約しなければ、遭遇しない問題なので、Googleの意図としては「素直に階層作ってくれよな」というところでしょう。