Trying out golang BigQuery client library
GCPのbillingをbigqueryにエクスポートしてre:dashで可視化してみました。
次はmackerelにbillingの情報を送ってメトリクスとして記録してみたいので、まずはgolangからbigqueryに対し何かしらのクエリを叩くところまでやってみます。
以下のドキュメントを見ながら試してみます。
準備
ライブラリのインストール。
go get cloud.google.com/go/bigquery
go get google.golang.org/api/iterator
cloud.google.com/go/bigquery
はbigqueryのapiを叩くライブラリ- ちなみにこのライブラリはまだβ版なので注意
google.golang.org/api/iterator
はgoogle apiが返してきた配列なりなんなりの構造に対し繰り返し処理をするためのライブラリ?- イテレータ - Wikipedia
- wikipediaにあるようにrubyでいうeach的なものを提供しているのか な?
今回はローカルでのみ動かすので、Google Cloudへの認証を済ませておきます。
gcloud beta auth application-default login
※ サーバ上で実行したい場合は明示的に作成したアカウントでアプリケーションのデフォルト認証情報を使用する必要がある(認証情報JSONの設置と、そのJSONへのpathをGOOGLE_APPLICATION_CREDENTIALS
環境変数に設定する)。
コードを書く
書くと言ってもほとんどドキュメント通り。googleのドキュメントはわかりづらっ というものも多いですがこのドキュメントはわかりやすくて良いですね。
月ごとのbillingデータを集計するクエリを実行してみます。プロジェクトID
、データセット名
、gcp_billing_exportテーブル名
だけ修正すれば動く(と思う)。
package main
import (
"fmt"
"golang.org/x/net/context"
"log"
"cloud.google.com/go/bigquery"
"google.golang.org/api/iterator"
)
func main() {
ctx := context.Background()
projectID := "プロジェクトID"
client, err := bigquery.NewClient(ctx, projectID)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
q := client.Query(`
SELECT SUM(cost) AS sum_cost, product,
LEFT (FORMAT_UTC_USEC(
UTC_USEC_TO_MONTH(TIMESTAMP_TO_USEC(start_time))), 7)
AS month
FROM
データセット名.gcp_billing_exportテーブル名
GROUP BY month, product
`)
it, err := q.Read(ctx)
if err != nil {
log.Fatalf("Failed to querying: %v", err)
}
for {
var values []bigquery.Value
err := it.Next(&values)
if err == iterator.Done {
break
}
if err != nil {
log.Fatalf("Failed to iterator: %v", err)
}
fmt.Println(values)
}
}
実行してみる
良さそう。
$ go run golang-bq.go
[0.002567 BigQuery 2017-01]
感想
思ったよりあっさりやりたいことが実現できた。ライブラリ便利だ...。
bigqueryへアクセスするための認証の手順でもっと時間がかかるかもと身構えていたが、ローカルで試す分にはgcloudコマンドがいい感じに認証の部分を吸収してくれた。
次やること
go-mackerel-plugin-helperを利用してmackerelへメトリクスを送れる形でデータ出力を行えるようにする。その際プロジェクトIDやデータセット、テーブル名は引数で渡せるようにする。