こんにちは。自称 Looker エバンジェリストの id:masutaka26 です。
今日は Spectacles というツールを導入して、Looker インスタンスの健全性を高められた話を紹介します。
Spectacles とは
Spectacles は Looker のサードパーティ CI ツールです。継続的に各種テストを実行し、Looker インスタンスを健全に保つことが出来ます。
クラウド版と OSS 版があり、それぞれ過去にクラスメソッドや、Zenn の記事で紹介されたことがあります。
今回は OSS 版を使いました。
4 種類のテスト
2022 年 9 月時点で 4 種類のテストが実装されています。
- SQL validation
- Assert validation
- LookML IDE 上でも実行できる LookML data tests を実行する
- Content validation
- 開発メニューの Content Validator 相当の検証を行い、エラーのある Dashboard や Look を特定する
- LookML validation
- LookML IDE 上でも実行できる LookML validation を実行する
基本的な振る舞い
Spectacles は Looker API を使用し、指定した Looker インスタンス上で、LookML data tests や validation などを実行します。
Spectacles -(Looker API)-> Your Looker Instance
いわゆるユニットテストでは、テスト環境でソースコードを checkout し、そこでテストを実行しますが、Spectacles はその点は全く違います。
つまり GitHub Actions 等の CI で動かす場合、LookML コードの checkout は不要ということです。
どのテストを採用し、どのような課題を解決したのか
SQL validation
いきなりですが、こちらは今回採用出来ませんでした。
我々の環境で全ての Explore をテスト対象にすると、かなりの数のテストが失敗します。hidden: yes
な Dimension がおそらく全てです。想定内です。
$ spectacles sql --project my_project_name --profile -v
それならばと、--ignore-hidden
オプションを付けると、今度はこんなエラーが発生します。どうやら 1 つも Dimension が表示されない Explore があるようです。こちらも想定内です。
Explore object is missing dimensions, meaning this query won't have fields and will error. Often this happens because you didn't include dimensions when you built the project.
--explore
オプションでエラーが発生しない Explore を指定すればよいのですが、Explore が 150 個以上ある関係で、切り分けができていません。
sql パラメーターは壊れていても、実際に Explore で当該 Dimension が使われないとエラーにならないのと、そのエラーが報告されるとも限らないので、いずれは再挑戦したいです。
Assert validation
我々の Looker インスタンスでは、BigQuery の外部テーブルに Google スプレッドシートを指定したテーブルを数多く参照しています。つまり人間が編集するデータです。このようなデータはオペミスにより壊れることがあり、primary_key も芋づる式に壊れることがあります。
primary_key はほぼ全てテストを書いています2が、約 250 個と数が多いです。一方で LookML IDE 上での data tests は同時実行数が 1 に制限されているようで、テストに 10 分以上かかります。commit 前のテストを必須にできない状態でした。そのため、時々テストを手動実行しないと、壊れたことに気づけない課題がありました。
以上の課題を解決するために、定期的に LookML data tests を実行し、手動実行せずに気付けるようになりました。
Content validation
今までは私の注意力で Dashboard 約 140 個と Look 約 30 個のエラー数ゼロを継続できていましたが、まさに属人的でした。
これも定期的に実行し、Content Validator を手動実行することなく気付けるようになりました。
LookML validation
時々 LookML IDE を介さず、ローカル環境で git commit してデプロイすることがあります。そのケースで大きな変更をすることはないものの、validation が通らない LookML がデプロイされる確率はゼロではありません。
こちらは git push のタイミングで実行することで、健全性を高めることが出来ました。
どのような GitHub Actions にしたのか
git push のタイミングで実行する CI workflow と、定期的に実行する Schedule workflow を作りました。
CI workflow
git push のたびに、当該 commit のブランチに対して、LookML validation のテストをしています3。
name: CI on: push: branches-ignore: # ① - 'dev-**' # LookML IDE の個人用開発ブランチ - 'tmp_spectacles_**' # spectacles の --commit-ref オプションが作るブランチ jobs: validate_lookml: name: Validate LookML files runs-on: ubuntu-latest timeout-minutes: 5 # デフォルトは 360 分。料金のスパイクを防ぐ concurrency: # ② spectacles が複数同時に実行しないようにする spectacles_should_be_run_in_series steps: - uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install Spectacles run: pip install spectacles - name: Run LookML Validator env: LOOKER_BASE_URL: "https://my_instance_name.looker.com" LOOKER_CLIENT_ID: ${{ secrets.SPECTACLES_LOOKER_CLIENT_ID }} # ③ LOOKER_CLIENT_SECRET: ${{ secrets.SPECTACLES_LOOKER_CLIENT_SECRET }} # ③ run: spectacles lookml --project my_project_name --commit-ref "$GITHUB_SHA" -v
①で特定のブランチを除外しています。特に今回のケースでは、tmp_spectacles_**
を設定しないと validate_lookml
ジョブが無限に起動し続けるため、絶対に必要です。
②も結構重要で、CI workflow と次に示す Schedule workflow から起動される spectacles プロセスの同時実行数を 1 に制限しています。
Spectacles は③と紐づく Looker ユーザーが実際に開発モードで tmp_spectacles_**
というブランチを作り、切り替えます。Looker では 1 人のユーザーが同時に利用できるブランチは 1 つだけです。Spectacles の複数起動は問題が発生するため、今回の制限を設定しました。公式ドキュメントでも言及されています。
Schedule workflow
早朝と夕方に master(デフォルト)ブランチ上で、Content validation と LookML data tests を実行しています。
name: Schedule on: schedule: - cron: "00 21 * * 0-4" # 平日の 6:00 JST - cron: "30 7 * * 1-5" # 平日の 16:30 JST jobs: schedule: name: Scheduled job runs-on: ubuntu-latest timeout-minutes: 30 # デフォルトは 360 分。料金のスパイクを防ぐ concurrency: # ① spectacles が複数同時に実行しないようにする spectacles_should_be_run_in_series env: LOOKER_BASE_URL: "https://my_instance_name.looker.com" LOOKER_CLIENT_ID: ${{ secrets.SPECTACLES_LOOKER_CLIENT_ID }} LOOKER_CLIENT_SECRET: ${{ secrets.SPECTACLES_LOOKER_CLIENT_SECRET }} steps: - uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install Spectacles run: pip install spectacles - name: Run Content Validator run: spectacles content --project my_project_name -v - name: Run LookML data tests run: spectacles assert --project my_project_name -v
ブランチの時や、master ブランチへのマージ直後ではまだ Dashboard や Look がエラーになることがあるため、Content validation はこのタイミングにしています。
LookML data tests も 10 分以上かかることと、git push の粒度でやらないと不安というわけではないため、このタイミングにしています。BigQuery の料金もかかりますからね。
落ち穂拾い
作業ブランチのゴミが残ることがある
Spectacles が途中で異常終了すると、LookML IDE と GitHub に tmp_spectacles_b016c8a4dd
といった、Spectacles が作る作業ブランチが残ることがあります。気づいたら削除してあげましょう。
正常終了の場合は残りません。
マシンユーザーを作るか作らないか
Looker はユーザー課金モデルであるため、Spectacles のためにユーザーを作ることに躊躇するかもしれません。私もそうでした。おまけに Developer 相当の権限が必要なため、そこそこの料金です。
Create a Looker API Key | Spectacles Docs
We strongly recommend creating a dedicated Spectacles user in Looker to ensure a human user doesn't accidentally change the Git branch or turn off development mode in the middle of a validation.
ですが、公式ドキュメントで強く奨励されているとおり、Spectacles 専用のユーザーを作って下さい。
人間のユーザーは権限が大きすぎますし、前述のとおり Spectacles は実際に開発モードでブランチを作って切り替えるため、人間の作業とコンフリクトします。
まとめ
Spectacles というツールを導入して、Looker インスタンスの健全性を高められた話をしました。
導入したのは先月ですが、導入の翌日にタイミング良く Schedule workflow のテストが落ち、primary_key が壊れたことに気づけたことにはニッコリしました。
私のようなボッチ LookML 開発者は、いかに作業を機械に任せるかが重要だと思います。心の平穏も大事です。また、あとから CI を導入するのは結構大変なので、始めから開発計画に組み込むことをオススメします。
それでは良い Looker ライフを!(^^)/
-
Looker で Join 先の view の primary_key をいい感じにテストする方法をようやく見つけた - Feedforce Developer Blog↩
-
実際には他のジョブや、失敗時の Slack 通知ジョブもありますが、分かりやすくするために省略しています。↩