こんにちは、グループ情報部の@mashiikeです。
この記事は Mackerel Advent Calendar 2025とdbt Advent Calendar 2025 の7日目の記事です。
はじめに
この記事は、2つのAdvent Calendarにまたがった記事となるので、それぞれについて簡単に説明します。
dbt Fusion
www.getdbt.com
dbt は、データウェアハウス上のデータを「SQL+コード」で変換・整形・モデリングするOSSのツールです。分析用テーブルの整形や集約、履歴テーブルの作成などを、SQLで記述し、依存関係を解決しながら実行してくれます。
そして dbt Fusion は、その dbt の“次世代エンジン”です。Rust 製になって高速化・開発体験の改善がされていて、「ちょっとしたSQLのチェック」や「クエリの構造確認」などを、DWHに実行する前にローカルで軽くできるようになっています。
ざっくり一言で言うと、dbt Fusionはデータパイプラインを構築するアプリケーションの一つとなります。
Mackerel
ja.mackerel.io
Mackerel は、株式会社はてなが提供する 日本製のサーバ監視サービスです。『育てる監視』という言葉がコンセプトにあり、監視系のサービスの中では凄くシンプルなのが魅力的です。
最近では、 OpenTelemetry を使った APM/トレース機能にも対応しており、アプリケーションの内部動作や分散システムでの処理経路まで可視化できるようになっています。これにより、単なるホスト監視にとどまらず、モダンなマイクロサービスやクラウド環境のトレースにも対応可能です。
ざっくり一言で言うと、MackerelはOpenTelemetryに対応した監視サービスの一つとなります。
dbt FusionをSelf-hostedで試してみたんだが、いい感じに監視したい。
さて、記事の本題に入ります。
dbt には、dbt platform(旧dbt Cloud) というサービスがあり、dbt platformにはパイプラインの実行状況を可視化するUIがついているため、dbt Cloudを使ってる分には監視で困ることはないでしょう。
しかし、様々な事情により、dbtをSelf-hostedで運用したい場合はあります。
弊社でも、現行版であるdbt CoreをSelf-hostedで運用しているケースがあり、dbt FusionがGAされた場合もSelf-hostedで運用する可能性が十分にあります。
そこで、現在Preview版として提供されているdbt FusionをSelf-hostedで試してみました。
手始めに、ローカルで dbt init をすると、dbt Fusionの場合はサンプルプロジェクトが作成されます。
サンプルプロジェクトは以下のようなパイプラインになっています。

dbtはこのような依存関係を考慮しながら、各SQLを実行していて行ってくれます。
※今回は監視が主題なので、必ずテストが失敗するモデル dummy を追加してます。
次に、以下のようなDockerfileを作成して、Google CloudのArtifact Registryにプッシュし、Cloud Run Jobsで定期実行するようにしました。
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
tzdata \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
ENV SHELL=/bin/bash
RUN curl -fsSL https://public.cdn.getdbt.com/fs/install/install.sh | bash
ENV PATH="/root/.local/bin:${PATH}"
COPY . .
ENV DBT_PROJECT_DIR=/app
RUN dbt deps
ENTRYPOINT ["dbt"]
CMD ["build"]
gcloud run jobs deploy dbt \
--image=${IMAGE_PATH} \
--region=${REGION} \
--project=${PROJECT_ID} \
--service-account=pipeline@${PROJECT_ID}.iam.gserviceaccount.com \
--memory=2Gi \
--cpu=1 \
--max-retries=0 \
--task-timeout=3600s \
--set-env-vars=DBT_PROJECT_DIR=/app

この画面をみると、いくつか失敗してますね。
Google Cloud Monitoringを使えば、Cloud Run Jobsのコンテナが異常終了した場合にアラートを飛ばすことはできます。
しかし、どのモデルが失敗したのか? はログを読みに行かないとわかりません。
何かもうちょっと、いい感じに実行監視できないか? と思ったのが今回の記事の発端です。
dbt FusionからOpenTelemetryのログが出力できるので、Mackerelに送ってみた!
どうやって、監視しようと悩んでいたとき、dbtのCLIのhelpを見ると見つけてしまいました。
--otel-file-name というオプションがあり、OpenTelemetryのログを出力できるようです。
$ dbt --help
dbt-fusion 2.0.0-preview.72: A fast and enriched dbt compiler and runner
Usage: dbt [OPTIONS] <COMMAND>
Commands:
init Initialize a new dbt project
deps Install package dependencies
parse Parse models
<中略>
--log-path <LOG_PATH>
Set 'log-path' for the current run, overriding 'DBT_LOG_PATH'
[env: DBT_LOG_PATH=]
--otel-file-name <OTEL_FILE_NAME>
Set 'otel-file-name' for the current run, overriding 'DBT_OTEL_FILE_NAME'. If set, OTEL telemetry will be written to `$log_path/otel-file-name`
[env: DBT_OTEL_FILE_NAME=]
<中略>
-V, --version
Print version
Use `dbt <COMMAND> --help` to learn more about the options for each command.
そこで、Claude Codeさんにお願いして小道具を作ってもらいました。
以前、私が作成した github.com/mashiike/jsonl-otel-forwarder のコードを参考にして、 logs/otel.jsonl に出力されたログファイルをOpenTelemetryのCollectorに出力するOSSを書いてください。
そして、できたのがこちらです。 github.com
次のように設定ファイルを書いて config.yml
exporters: otlp: type: otlp endpoint: "https://otlp-vaxila.mackerelio.com" protocol: http/protobuf headers: Accept: "*/*" "Mackerel-Api-Key": "${MACKEREL_API_KEY:?MACKEREL_API_KEY is required}" forward: default: resource: attributes: "service.name": "jaffle_shop" # APM上のサービス名 "deployment.environment": "production" # 環境ラベル traces: attributes: - action: set when: | name.contains("Node evaluated") && attributes["dbt.phase"] == "EXECUTION_PHASE_RUN" key: "url.path" value_expr: attributes["dbt.unique_id"] # モデル/テストをパスに見立てる - action: set when: | name.contains("Node evaluated") && attributes["dbt.phase"] == "EXECUTION_PHASE_RUN" key: "http.request.method" value: "POST" # 仮想HTTPリクエスト化 - action: set when: | name.contains("Node evaluated") && attributes["dbt.phase"] == "EXECUTION_PHASE_RUN" key: "http.response.status_code" value_expr: | status.code == "ERROR" ? 500 : 200 # 成否をHTTPステータスで表現 exporters: [otlp]
※ tracesのattributesセクション、http関係の属性を追加しているのは、後述するMackerelのAPM機能で見やすくするための工夫です。
この小道具をラッパーコマンドとしてdbtを実行するとMackerelにテレメトリーが送られます。
もちろん、その他のOpenTelemetryサービスをお使いの方は送る先のエンドポイントを変えれば同様にできるはずです。
$ dbt-fusion-otel-forwarder --config config.yml -- dbt build
こうすることで、Mackerel上でSlack通知を設定していれば次のように通知が飛んできます。


リンクを飛んだ先にはトレースのSpanが並んでおり、失敗したNodeの下にはQueryExecutedのSpanがぶら下がっています。

このQueryExecutedのSpanの属性には、db.statementがあり、実行されたSQL文が格納されています。

APM機能でパイプラインのボトルネックも見える化できる
Mackerelには最近APM機能も追加されており、そのAPM機能でdbt Fusionで作成したパイプラインのボトルネックが簡単に可視化できました。
モデル・テスト毎の実行時間、エラー率が見られます。
Configファイルの紹介のときにしれっと、HTTP関係の属性を足していたのは、このモデル・テスト毎のパフォーマンスを仮想のHTTPリクエストとして扱うための工夫でした。

また、実行しているSQLごとのパフォーマンスを見るタブもあって、こっちも便利です。

省略表示だと、ほとんどdbtが挿入しているヘッダーコメントばかりですが、展開すると実際のSQL文が見られます。
まとめ
dbt FusionをSelf-hostedで運用する場合に、MackerelのAPM機能を使ってパイプラインの監視を行う方法を紹介しました。
dbt FusionはまだPreview版ですが、GAされた際にはSelf-hostedで運用・監視がちゃんとできそうなことは検証できたと思います。
また、今回Mackerelのトレース機能とAPM機能を使ってdbt Fusionの監視をしてみましたが、とても良い感じでした。
お試しで使ってみている感じ、使用感がとても良いので今からGAが楽しみです。
Mackerelは、シンプルなところが魅力と言いましたが、今回のケースとかはその魅力的な一例です。
本来であればサーバーのエンドポイント毎のパフォーマンスを見る画面を、使う側のちょっとした工夫でdbt Fusionのモデルごとのパフォーマンス分析に応用できたりします。
皆様も、サーバーに限らずにMackerelにテレメトリを送ってみてはいかがでしょうか? きっといい感じに表示する方法はあると思います。