Event Tablesは、SnowflakeのUDF・ストアドプロシージャ・Streamlitアプリなどから 出力されるログ・トレース・メトリクスイベントを収集するための専用テーブルです。 従来はデバッグログの確認が困難だったSnowflakeの関数実行に対して、 構造化されたイベントデータをSQLで分析できる可観測性(Observability)基盤を提供します。
-- Event Tableの作成
CREATE OR REPLACE EVENT TABLE observability_db.events.app_events;
-- アカウントレベルでEvent Tableを有効化(ACCOUNTADMIN必須)
ALTER ACCOUNT SET EVENT_TABLE = 'observability_db.events.app_events';
-- データベースレベルでログレベルを設定
ALTER DATABASE my_app_db SET LOG_LEVEL = 'INFO';
-- スキーマレベルでログレベルを設定(より細かい制御)
ALTER SCHEMA my_app_db.analytics SET LOG_LEVEL = 'DEBUG';
-- 特定のUDF/プロシージャだけログレベルを変更
ALTER FUNCTION my_app_db.public.process_data(VARCHAR)
SET LOG_LEVEL = 'TRACE';
-- トレースレベルの設定
ALTER DATABASE my_app_db SET TRACE_LEVEL = 'ON_EVENT';| レベル | 記録されるイベント | 用途 |
|---|---|---|
| OFF | なし | ログ収集を完全に無効化 |
| FATAL | 致命的エラーのみ | クリティカルな障害の検知 |
| ERROR | FATAL + エラー | エラー監視 |
| WARN | ERROR + 警告 | 問題の早期検知 |
| INFO | WARN + 情報 | 通常運用のモニタリング(推奨デフォルト) |
| DEBUG | INFO + デバッグ | 開発・テスト環境でのデバッグ |
| TRACE | 全てのイベント | 詳細なトレース(高コスト注意) |
LOG_LEVELはアカウント → データベース → スキーマ → オブジェクト(関数/プロシージャ)の順に 上書き可能です。未設定の場合は上位レベルの設定が継承されます。
| TRACE_LEVEL | 動作 |
|---|---|
| OFF | トレースイベントを記録しない |
| ON_EVENT | SYSTEM$ADD_TRACE()呼び出し時のみ記録 |
| ALWAYS | 関数の全実行をスパンとして自動記録 |
-- Python UDFからログを出力
CREATE OR REPLACE FUNCTION process_order(order_json VARIANT)
RETURNS VARIANT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.10'
HANDLER = 'run'
AS $
import logging
logger = logging.getLogger('order_processor')
def run(order_json):
logger.info(f"Processing order: {order_json['order_id']}")
try:
total = sum(item['price'] * item['qty'] for item in order_json['items'])
logger.info(f"Order total calculated: {total}")
return {"order_id": order_json['order_id'], "total": total, "status": "success"}
except Exception as e:
logger.error(f"Failed to process order: {str(e)}")
raise
$;
-- JavaScriptプロシージャからログを出力
CREATE OR REPLACE PROCEDURE sync_inventory()
RETURNS VARCHAR
LANGUAGE JAVASCRIPT
EXECUTE AS CALLER
AS $
snowflake.log("info", "Starting inventory sync");
var rs = snowflake.execute({sqlText: "SELECT COUNT(*) FROM inventory"});
rs.next();
var count = rs.getColumnValue(1);
snowflake.log("info", "Inventory records: " + count);
return "Synced " + count + " records";
$;
-- SQLスクリプトからログを出力
CALL SYSTEM$LOG('INFO', 'Data pipeline started');
-- トレースイベントの出力
CALL SYSTEM$ADD_TRACE('pipeline_run', '{"stage": "transform", "rows": 50000}');| カラム | 型 | 説明 |
|---|---|---|
| TIMESTAMP | TIMESTAMP_NTZ | イベントが発生した時刻 |
| RESOURCE_ATTRIBUTES | VARIANT | 実行コンテキスト(データベース名、スキーマ名、関数名など) |
| RECORD_TYPE | VARCHAR | イベント種類(LOG / SPAN / SPAN_EVENT) |
| RECORD | VARIANT | イベントの詳細データ(ログメッセージ、重大度など) |
| RECORD_ATTRIBUTES | VARIANT | カスタム属性(SYSTEM$ADD_TRACEで付加したデータ) |
| SCOPE | VARIANT | スコープ情報(ロガー名、スパン名など) |
-- 直近1時間のエラーログを取得
SELECT
timestamp,
resource_attributes['snow.database.name']::VARCHAR AS db_name,
resource_attributes['snow.schema.name']::VARCHAR AS schema_name,
resource_attributes['snow.executable.name']::VARCHAR AS function_name,
record['severity_text']::VARCHAR AS severity,
record['body']['text']::VARCHAR AS message
FROM observability_db.events.app_events
WHERE record_type = 'LOG'
AND record['severity_text']::VARCHAR IN ('ERROR', 'FATAL')
AND timestamp >= DATEADD(HOUR, -1, CURRENT_TIMESTAMP())
ORDER BY timestamp DESC;
-- 関数別の実行回数とエラー率を集計
SELECT
resource_attributes['snow.executable.name']::VARCHAR AS function_name,
COUNT(*) AS total_events,
COUNT_IF(record['severity_text']::VARCHAR = 'ERROR') AS error_count,
ROUND(error_count / total_events * 100, 2) AS error_rate_pct
FROM observability_db.events.app_events
WHERE record_type = 'LOG'
AND timestamp >= DATEADD(DAY, -7, CURRENT_TIMESTAMP())
GROUP BY function_name
ORDER BY error_rate_pct DESC;
-- トレーススパンの実行時間を分析
SELECT
scope['name']::VARCHAR AS span_name,
record_attributes,
DATEDIFF('millisecond',
record['start_time']::TIMESTAMP_NTZ,
timestamp
) AS duration_ms
FROM observability_db.events.app_events
WHERE record_type = 'SPAN'
ORDER BY duration_ms DESC
LIMIT 20;Observability
問題 1
Python UDFのデバッグのために、UDF内のlogger.info()の出力をEvent Tableに記録したい。以下のうち、最低限必要な設定の組み合わせとして正しいものはどれか。
正解: A
Event Tableにログを記録するには、(1) CREATE EVENT TABLEでテーブルを作成、(2) ALTER ACCOUNT SET EVENT_TABLEでアカウントのEvent Tableを指定、(3) 対象のデータベースやオブジェクトにLOG_LEVELを設定、の3ステップが必要です。LOG_LEVELだけ設定してもEvent Tableが指定されていなければログは記録されません。TRACE_LEVELはトレーススパン用であり、ログメッセージの記録にはLOG_LEVELを使用します。
Event Tablesのデータ保持期間を変更できますか?
はい。ALTER DATABASE SET EVENT_RETENTION_TIME_IN_DAYS パラメータで保持期間を変更できます。デフォルトは1日です。長期間のログ分析が必要な場合はこの値を増やしますが、保持期間に応じてストレージコストが増加します。長期保存が必要な場合は、定期的にEvent Tableのデータを通常テーブルにCOPYまたはINSERTして永続化するパターンも検討してください。
Event Tablesに書き込めるイベントの種類は何がありますか?
Event Tablesには主に3種類のイベントが書き込まれます。(1) LOGメッセージ:UDF/ストアドプロシージャ内のsystem.log()やSYSTEM$LOG()で出力するカスタムログ、(2) TRACEイベント:SYSTEM$ADD_TRACE()で記録する関数の実行トレースやスパン情報、(3) METRICデータ:実行時間や行数などの計測データ。LOG_LEVELパラメータ(OFF/FATAL/ERROR/WARN/INFO/DEBUG/TRACE)でどのレベルのログを記録するかを制御します。
Event TableはアカウントにいくつまでENABLEにできますか?
アクティブなEvent Tableはアカウントにつき1つだけです。ALTER ACCOUNT SET EVENT_TABLE = db.schema.my_eventsで指定した1つのEvent Tableが全データベース・スキーマのイベントの書き込み先となります。テーブル自体は複数作成できますが、イベント収集先として有効化できるのは同時に1つだけです。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Snowflake資格一覧|全11試験(SnowPro)の難易度・費用
Snowflake認定資格(SnowPro)全11試験の一覧・難易度・費用・出題範囲を徹底解説。...
Snowflake試験の難易度ランキング|全11資格を徹底比較
Snowflake(SnowPro)認定全11試験の難易度をランキング形式で比較。学習時間・合格に必要なスキルから分析。...
Snowflake資格の勉強方法|効率的な学習ルートと合格のコツ
Snowflake認定資格(SnowPro)に最短で合格するための勉強方法。公式リソース・学習スケジュールを徹底ガイド。...
SnowPro Core試験完全解説|出題範囲・問題例・合格戦略
SnowPro Core Certification(COF-C03)を徹底解説。出題範囲・100問の試験形式・合格ライ...
SnowPro Platform Associate完全解説|入門試験の攻略
SnowPro Associate: Platform Certification(SOL-C01)を徹底解説。最も簡単...