Cloud Logging のログをエクスポートして BigQuery テーブルに手動インポートする方法


GCP の Cloud Logging から BigQuery へのログエクスポートがうまくいかないときに確認すること という記事を書いた。こういうケースでうまく取り込みができてなかったログを手動でインポートしたいとき、やや手順が多いので何をすればいいかまとめる。

Cloud Loggingからログをエクスポートする

まずは該当のログをエクスポートするところから。

Cloud Console からも簡単に書き出せるが、ログの件数が最大 300 件(現時点でプレビュー版の新しいログビューアでは 1 万件)という制限がある。また書き出した内容を少し加工した方がインポート時に都合がいいので(理由は後述)、 google-cloud-sdk を用いてコマンドラインから書き出すのがおすすめ。

Cloud Console のログビューワ。ベータ版の UI だと最大1万件まで書き出し可能

gcloud コマンドでログを書き出す方法はこのようになる。

gcloud logging read --project=PROJECT_NAME --freshness=7d --format=json '(
resource.type="k8s_container"
resource.labels.cluster_name="MY_CLUSTER_NAME"
resource.labels.namespace_name="default"
resource.labels.container_name="MY_CONTAINER_NAME"
receiveTimestamp>="2020-12-11T15:00:00"
receiveTimestamp<="2020-12-13T08:30:00"
)' | jq -c '.[]' > log_export.ndjson

ポイントは

  • 古いログを読み込む場合は忘れず —freshness を指定する。デフォルトは 1d になっていて、2 日以上前のログは読み込まれないので注意
  • 後述する BigQuery へのインポート時に ndjson 形式だと便利なので、 jq で加工する(これがコマンドラインをオススメする理由)

BigQueryへのログファイルのインポート

ログファイルから BigQuery へのインポートは bq コマンドを使う。
データをローカル データソースから読み込む  |  BigQuery  |  Google Cloud

インポート前にあらかじめテーブルのスキーマを書き出す。これも bq コマンドで行える。

bq show --project_id=project-name --schema --format=prettyjson dataset_name.table_name > schema.json

BigQuery テーブルのカラム名には英数字とアンダースコアしか使えないが、 Kubernetes container のログをエクスポートすると json キーに k8s-pod/app といったような文字列が含まれていたりする。これをそのままインポートすると以下のようにエラーが出るので、地道に k8s_pod_app といったように文字列置換をする。 Sink を使った BigQuery へのログエクスポートだとこれを暗黙的にやってるみたい。

Error in query string: Error processing job 'project-name:bqjob_...': Invalid field name "k8s-pod/job-name". 
Fields must contain only letters, numbers, and underscores, start with a letter or underscore, and be at most 128 characters long. Table:
stdout_8c81f8db_f768_4e20_bb30_6045b86e9cca_source

ログファイル内のキー名を修正したら、以下のコマンドでインポート。

bq load --source_format=NEWLINE_DELIMITED_JSON project_name:dataset_name.table_name ./log_export.ndjson ./schema.json

以上が手動インポートの流れ。地味に手順が多かったのでメモまでに。