clickhouse-logs-queries について
clickhouse-logs-queries は Supabase ログのクエリと移行を支援するスキルで、Logs Explorer や ClickHouse のログクエリを扱う開発者向けです。統合ログテーブル、source による絞り込み、属性の参照、BigQuery から ClickHouse への変換方法を説明します。
主な機能
- 01統合 ClickHouse logs テーブルのクエリ
- 02サービス source によるログの絞り込み
- 03log_attributes からフィールドを取得
- 04BigQuery クエリを ClickHouse 用に変換
- 05クエリ例と実践上の指針
活用シーン
- 01Supabase ログクエリの作成やレビュー
- 02サービスやフィールドでログを絞り込む
- 03既存の BigQuery クエリを ClickHouse に移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ supabase/ supabase --skill clickhouse-logs-queriesインストール後、Claude Code で/clickhouse-logs-queriesを入力して読み込まれたか確認します。
同梱ファイルreferences/codebase-integration.mdreferences/bigquery-migration.md
詳細
Supabase ログのクエリ(ClickHouse)
Supabase のログは単一の ClickHouse logs テーブルに保存され、logs.all.otel 分析エンドポイントから提供されます。スタック内のあらゆる箇所から出力された各ログ行がこのテーブルの1行となり、source 列でタグ付けされています。これは、サービスごとに独自のテーブルがあり、cross join unnest(metadata) を通じてフィールドにアクセスしていた従来の BigQuery モデルに代わるものです。
このスキルを使う作業は2種類あり、どちらも同じ SQL モデルを共有します。
- ログクエリの作成またはレビュー(Logs Explorer 内、または ClickHouse の生ログクエリが必要な任意の場所)。まずこのファイルを参照してください。
- Studio のコードベースでログクエリを接続(ブランド化された分析 SQL、エンドポイントピッカー、OTEL クエリビルダー)。references/codebase-integration.md を参照してください。
既存の BigQuery ログクエリを変換する場合は、完全な変換表が記載された references/bigquery-migration.md を参照してください。
logs テーブル
各行には、実際の列が少数あります。サービス固有の情報はすべて log_attributes に格納されます。
| 列 | 型 | 備考 |
|---|---|---|
id | String | 一意のログ識別子です。 |
timestamp | DateTime64 (UTC) | ログが生成された時刻です。直接並べ替えや比較を行います。 |
event_message | String | 生のログ行です。 |
severity_text | String | ソースが設定している場合のログレベルです。 |
source | String | ログの発生元サービスです。必ずこれでフィルターしてください。 |
log_attributes | Map(String, String) | ソースごとの構造化フィールドです。ドット区切りのパスをキーにします。 |
timestamp は 2026-06-22T09:34:06.215000 の形式です(ISO 8601、マイクロ秒精度、末尾に Z は付きません)。Logs Explorer では選択した時間範囲が自動で適用されるため、手動で timestamp フィルターを書く必要はほとんどありません。
最小限の、適切な形式のクエリです。クエリ名を示すコメントから始め、source でフィルターし、必ず limit を指定してください。
-- recent edge requests
select timestamp, event_message
from logs
where source = 'edge_logs'
order by timestamp desc
limit 100;
ソース
source でサービスを選択します。主なものは次のとおりです。
edge_logs— API ゲートウェイのリクエストとレスポンスpostgres_logs— データベースのステートメントとエラー(pg_cron のログもここに含まれます)auth_logs— 認証および認可のアクティビティfunction_edge_logs— エッジ関数のリクエストとレスポンスfunction_logs— エッジ関数内からのconsole出力storage_logs— オブジェクトのアップロードおよび取得のアクティビティrealtime_logs— Realtime クライアントの接続postgrest_logs、supavisor_logs、pgbouncer_logs— 主にid、timestamp、event_message
Logs Explorer の Field Reference ドロワーには、すべてのソースと、各ソースで実際に設定されるフィールドが一覧表示されます。キーが分からない場合は、推測するのではなく実際のデータから確認してください(下記を参照)。
log_attributes からフィールドを読み取る
log_attributes は文字列キーを文字列値にマッピングします。ブラケットアクセスでフィールドを読み取ります。ネスト解除のための結合はありません。
select
log_attributes['request.method'] as method,
log_attributes['request.path'] as path,
log_attributes['response.status_code'] as status
from logs
where source = 'edge_logs'
キーには、BigQuery がネストされた構造体で表現していたドット区切りのパスが保持されますが、metadata のルートは省略されます。BigQuery の metadata.request.method は log_attributes['request.method'] になります。プレフィックス全体を保持してください。request.cf.country は log_attributes['request.cf.country'] であり、log_attributes['cf.country'] ではありません。
ソースごとの一般的なキー:
edge_logs:request.method、request.path、request.search、response.status_code、identifierpostgres_logs:parsed.error_severity、parsed.detail、parsed.hint、parsed.query、identifierauth_logs:level、status、path、msg、errorfunction_edge_logs:response.status_code、request.method、request.pathname、function_id、execution_id、execution_time_msfunction_logs:event_type、function_id、execution_id、level
数値フィールドは文字列です
マップの値は常に文字列です。数値フィールドを比較または集計するには、toInt32OrZero で囲みます。欠損値や数値以外の値には 0 を返すため、不完全なデータでもエラーになりません。
select count() as server_errors
from logs
where source = 'edge_logs'
and toInt32OrZero(log_attributes['response.status_code']) between 500 and 599
ソースが設定するキーを確認する
キー名を推測するのではなく、最近の行から mapKeys を読み取ります。
select arrayJoin(mapKeys(log_attributes)) as key, count() as n
from logs
where source = 'postgres_logs'
group by key
order by n desc
limit 100;
arrayJoin(mapKeys(...)) はマップのキーをフラット化してキーごとに1行にするため、出現頻度で順位付けできます。(Studio のコードベースでは、Field Reference ドロワーの表示と、AI による書き換えに実際のキーを渡すために、この方法を使用しています。)
ClickHouse と BigQuery の関数
特につまずきやすい置き換えは次のとおりです。
| 必要な処理 | BigQuery | ClickHouse |
|---|---|---|
| 行数を数える | count(*) | count() |
| 正規表現に一致するか確認する | regexp_contains(x, 'p') | match(x, 'p') |
| 部分文字列に一致するか確認する | x like '%p%' | x ilike '%p%'(大文字と小文字を区別しない)または like |
| 数値に変換する | cast(x as int64) | toInt32OrZero(x) |
| タイムスタンプを読み取る | cast(timestamp as datetime) | timestamp(列を直接使用) |
| マップのキー | 該当なし(unnest を使用) | mapKeys(log_attributes) |
logs.all.otel 分析エンドポイント(およびその上に構築された Logs Explorer)では、count(*) と select * は拒否されます。count() を使い、必要な列を列挙してください。(生の ClickHouse ではどちらも使用できますが、これはログクエリのインターフェースにおける制約です。)
ベストプラクティス
以下を守ると、クエリの正確性を保ちながらコストを抑えられます。ログテーブルは大きいため、範囲を限定しないスキャンでは必要以上のデータを読み取ってしまいます。
- すべてのクエリの先頭に識別用のコメントを付けてください(例:
-- errors since last deploy)。クエリにラベルを付けてログやレビューで識別できるようにし、ファイル内に複数のクエリがある場合も、それぞれを簡単に見分けられます。 - 必ず
LIMITを含めてください。 集計クエリでも、作業中は指定してください。 - 必ず
from logs where source = '...'でクエリしてください。 サービスごとのテーブル(edge_logs、postgres_logsなど)はありません。logsテーブルが1つあり、sourceでサービスを絞り込みます。sourceによるフィルタリングは必須であり、単なる最適化ではありません。 - 時間範囲を狭くしてください。 範囲が小さいほど、結果をより速く取得できます。
log_attributesにアクセスする前に、実際の列(source、timestamp)でフィルタリングしてください。- 最も新しいログを先に確認できるよう、
order by timestamp descを指定してください。 count()を使い、count(*)やselect *は使わないでください。
実例
ステータスコード別のリクエスト:
select
toInt32OrZero(log_attributes['response.status_code']) as status,
count() as count
from logs
where source = 'edge_logs'
group by status
order by count desc
limit 50
Auth のエラー:
select timestamp, event_message, log_attributes['msg'] as message
from logs
where source = 'auth_logs'
and log_attributes['level'] in ('error', 'fatal')
order by timestamp desc
limit 100
生のメッセージを検索する:
select timestamp, event_message
from logs
where source = 'postgres_logs'
and event_message ilike '%deadlock%'
order by timestamp desc
limit 100
重大度別にグループ化した Postgres のエラー(unnest をマップに変換する標準的な例):
select log_attributes['parsed.error_severity'] as severity, count() as count
from logs
where source = 'postgres_logs'
and log_attributes['parsed.error_severity'] in ('ERROR', 'FATAL', 'PANIC')
group by severity
order by count desc
limit 100
ユーザーが BigQuery のクエリを貼り付けたとき
そのまま実行するのではなく、変換してください。機械的な手順(from logs where source = ... のサービスごとのテーブルを削除し、すべての cross join unnest(...) を削除し、unnest のエイリアス列を log_attributes['...'] の参照に書き換え、上記の関数を置き換える方法)は、references/bigquery-migration.md に完全な変換前後の例とともに記載されています。Logs Explorer には、AI を使って変換する組み込みの Rewrite to ClickHouse アクションもあります。ダッシュボードでの単発の変換には、こちらを案内してください。