ブラウザのログをCloud RunのREST APIで受けBigQueryに流す
最近はすべてのログはBigQueryに流すという運用をしています。iOS/AndroidのアプリログはFirebase AnalyticsでログをとってFirebaseの設定からBigQueryにエクスポートできます。
ブラウザの場合は自分は定まった方法をもっていなくて、Google Analyticsのカスタムイベントを送るとかがあるかなと思いますが今回はCloud RunのREST APIを使ってさくっと構築できる方法があったので構築方法を紹介します。
構築方法
構成は以下のようになります。
Cloud RunにREST APIを作ってGoのプログラムを実行し標準出力にJSON形式でログを出力します。そのログをLoggingのフィルタ機能を使ってフィルタし、エクスポート機能でBigQueryに出力します。
Cloud RunはUsing Cloud Pub/Sub with Cloud Run tutorialを参考するといいと思います。たとえば以下のようなコードでJSONをうけとってそのまま標準出力に出します。
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
)
func main() {
http.HandleFunc("/", LoggingHandler)
port := os.Getenv("PORT")
if port == "" {
port = "8080"
fmt.Printf("Defaulting to port %s\n", port)
}
fmt.Printf("Listening on port %s\n", port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
type JSONMessage struct {
Message interface{} `json:"message"`
}
func LoggingHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Max-Age", "86400")
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
w.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-Access-Token, X-CSRF-Token, Authorization")
w.Header().Set("Access-Control-Expose-Headers", "Content-Length")
w.Header().Set("Access-Control-Allow-Credentials", "true")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
var m JSONMessage
if err := json.NewDecoder(r.Body).Decode(&m); err != nil {
fmt.Printf("json.NewDecoder: %v\n", err)
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
if m.Message == nil {
http.Error(w, "Bad Request", http.StatusBadRequest)
}
j, _ := json.Marshal(m)
fmt.Println(string(j))
}
Cloud Runにデプロイしたら実際に動くか確かめてみます。https://aaa.run.app
はプロジェクトに合わせて変更して、以下のようにAPIをたたきます。
curl https://aaa.run.app -X POST -H "Content-Type: application/json" -d '{"message": { "name":"John", "age":30, "car":null }}'
次に、LoggingからBigQueryへのエクスポートを設定します。デプロイしたCloud Runのサービス名がlogger
だとすると以下のようにLoggingのフィルタを設定するとmessage
キーをもったJSONのログだけをフィルタすることができます。
resource.type = "cloud_run_revision"
resource.labels.service_name = "logger"
jsonPayload.message:*
うまくフィルタされたことを確認して、CREATE EXPORT
からBigQueryへのエクスポートを作成します。
これで完了です。先程実行したcurl
コマンドを実行してしばらく待ってからBigQueryで確認してみると以下のようにログが取り込まれています。
まとめ
Cloud Runを使ってブラウザのログをBigQueryへと取り込む方法を紹介しました。Cloud Runはまだベータで日本リージョンにないのでレスポンスタイムが気になりますがいずれ日本にくるはずなので待っています。どうしても日本リージョンで動かしたい場合はCloud Run on GKEを使うといいと思います。
今回認証も何もつけていませんが必要に応じてFirebase Authenticationを使ってセキュリティを高めてください。