mcpField
C
clickhouse-logs-queries

clickhouse-logs-queries

github.com/supabaseデータ・データベース114.3k90 回インストール今日更新
リポジトリ

clickhouse-logs-queries について

clickhouse-logs-queries は Supabase ログのクエリと移行を支援するスキルで、Logs Explorer や ClickHouse のログクエリを扱う開発者向けです。統合ログテーブル、source による絞り込み、属性の参照、BigQuery から ClickHouse への変換方法を説明します。

主な機能

  1. 01統合 ClickHouse logs テーブルのクエリ
  2. 02サービス source によるログの絞り込み
  3. 03log_attributes からフィールドを取得
  4. 04BigQuery クエリを ClickHouse 用に変換
  5. 05クエリ例と実践上の指針

活用シーン

  1. 01Supabase ログクエリの作成やレビュー
  2. 02サービスやフィールドでログを絞り込む
  3. 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 モデルを共有します。

  1. ログクエリの作成またはレビュー(Logs Explorer 内、または ClickHouse の生ログクエリが必要な任意の場所)。まずこのファイルを参照してください。
  2. Studio のコードベースでログクエリを接続(ブランド化された分析 SQL、エンドポイントピッカー、OTEL クエリビルダー)。references/codebase-integration.md を参照してください。

既存の BigQuery ログクエリを変換する場合は、完全な変換表が記載された references/bigquery-migration.md を参照してください。

logs テーブル

各行には、実際の列が少数あります。サービス固有の情報はすべて log_attributes に格納されます。

列型備考
idString一意のログ識別子です。
timestampDateTime64 (UTC)ログが生成された時刻です。直接並べ替えや比較を行います。
event_messageString生のログ行です。
severity_textStringソースが設定している場合のログレベルです。
sourceStringログの発生元サービスです。必ずこれでフィルターしてください。
log_attributesMap(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、identifier
  • postgres_logs:parsed.error_severity、parsed.detail、parsed.hint、parsed.query、identifier
  • auth_logs:level、status、path、msg、error
  • function_edge_logs:response.status_code、request.method、request.pathname、function_id、execution_id、execution_time_ms
  • function_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 の関数

特につまずきやすい置き換えは次のとおりです。

必要な処理BigQueryClickHouse
行数を数える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 アクションもあります。ダッシュボードでの単発の変換には、こちらを案内してください。

コメント