What you will be able to do
- Query event table columns and record types to find system health signals
- Use resource attributes to see which user and role ran code, and control who can read telemetry
- Build alerts on event table data that neither miss rows nor send duplicate notifications
- Follow a trace through spans, durations and metrics to find the root cause of failures and slow code
1.Reading the event table for system health
Every event table has the same predefined columns. The RECORD_TYPE column tells you how to read each row:
- RECORD holds the fixed values for that record type. For a log, this is the severity. - VALUE holds the main payload, such as the log message or the metric value. - RESOURCE_ATTRIBUTES identifies where the row came from, such as the database, schema, user or warehouse. - TRACE links rows that belong together through a trace_id and span_id.
| RECORD_TYPE | What the row holds | Health signal to look for |
|---|---|---|
| LOG | A log message. RECORD holds severity_text (TRACE, DEBUG, INFO, WARN, ERROR or FATAL) and VALUE holds the message | Counts of ERROR and FATAL rows. An unhandled exception is logged at the runtime's highest error level, which is FATAL for Python |
| METRIC | A metric data point. RECORD holds the metric name and unit, and VALUE holds the number | process.memory.usage and process.cpu.utilization, which show resource consumption |
| SPAN / SPAN_EVENT | A unit of execution, and a single trace event inside one | Span durations and span status |
| EVENT | An event tied to an operation, such as Iceberg automated refresh | The status and severity of the operation, held in RECORD |
Log events (record type EVENT) also report on Snowflake features beyond your own code. They include events from Snowpipe, tasks, dynamic tables, Snowpark Container Services compute pools, Iceberg tables and data governance tag activity. These rows appear only if LOG_EVENT_LEVEL allows them.
Many RECORD and RESOURCE_ATTRIBUTES values are key-value objects, so you read them with bracket notation. The query below lists recent log messages with the executable that emitted each one and its severity.
SELECT TIMESTAMP AS time, RESOURCE_ATTRIBUTES['snow.executable.name'] as executable, RECORD['severity_text'] AS severity, VALUE AS message FROM tutorial_log_trace_db.public.tutorial_event_table WHERE RECORD_TYPE = 'LOG' AND SCOPE['name'] = 'tutorial_logger';Checkpoint 1 of 7· Match them up
Match each event table column to what it holds
Tap a term, then the definition that fits it.
Severity lives in RECORD, the payload in VALUE, the source in RESOURCE_ATTRIBUTES and correlation IDs in TRACE.
“Attributes that identify the source of an event such as database, schema, user, warehouse, Openflow, etc.”Source: docs.snowflake.com
2.Monitoring user activity and controlling access to telemetry
Every telemetry row records who caused it. RESOURCE_ATTRIBUTES includes these keys:
- db.user is the user who ran the function or procedure. For a Streamlit app, it is the user viewing the app. - snow.session.role.primary.name is the primary role of the session. - snow.owner.name is the role that owns the executable. - snow.query.id, snow.session.id and snow.warehouse.name identify the query, session and warehouse.
Filtering or grouping on these keys shows which users and roles are running which code, and which errors they hit. The Snowsight Traces & Logs page offers the same filters: by user, severity, language and date range.
The event table can expose sensitive data, so access to it is a security control in its own right. To read logs, your role needs one of the following: ACCOUNTADMIN, the EVENTS_VIEWER or EVENTS_ADMIN application role, or SELECT on a custom event table. EVENTS_ADMIN can add a row access policy to EVENTS_VIEW so each role sees only its own rows. For custom tables, views granted per role do the same job.
A note on scope: these sources do not describe threat-detection rules or login monitoring. What they support is using event table attributes to tie activity to users and roles, and restricting who can see that data.
Checkpoint 2 of 7· Check yourself
A security reviewer wants to know which role was active when a UDF logged a suspicious error. Which value answers that?
The session's primary role is recorded in RESOURCE_ATTRIBUTES. RECORD holds severity, SCOPE holds the code namespace, and TRACE holds correlation IDs.
“Retrieved from the RESOURCE_ATTRIBUTES column snow.session.role.primary.name value.”Source: docs.snowflake.com
3.Creating alerts on event table data
Querying the event table by hand only finds problems after the fact. An alert runs a condition query and performs an action when that query returns rows. There are two kinds.
A scheduled alert runs on a SCHEDULE you set. A an alert on new data has no SCHEDULE. It fires when new rows matching its condition are inserted into the table, so it suits event tables well. The documentation's example watches SNOWFLAKE.TELEMETRY.EVENTS for dynamic table refresh errors and posts to Slack. Two limits apply to alerts on new data: you cannot run them with EXECUTE ALERT, and the CONDITION_FALSE state does not apply to them.
For scheduled alerts, bound the condition with two functions instead:
- SCHEDULED_TIME returns when the current run was scheduled. - LAST_SUCCESSFUL_SCHEDULED_TIME returns when the last successfully evaluated run was scheduled.
Together they make each run cover exactly the rows that arrived since the last successful run, so a row is not reported twice. Both functions live in SNOWFLAKE.ALERT, and calling them requires the SNOWFLAKE.ALERT_VIEWER database role.
CREATE OR REPLACE ALERT alert_new_rows
WAREHOUSE = my_warehouse
SCHEDULE = '1 MINUTE'
IF (EXISTS (
SELECT *
FROM my_table
WHERE row_timestamp BETWEEN SNOWFLAKE.ALERT.LAST_SUCCESSFUL_SCHEDULED_TIME()
AND SNOWFLAKE.ALERT.SCHEDULED_TIME()
))
THEN CALL SYSTEM$SEND_EMAIL(...);To check that an alert is working, use the ALERT_HISTORY table function or the ACCOUNT_USAGE.ALERT_HISTORY view. They report a STATE for each run:
- CONDITION_FALSE: the condition ran and returned no rows, so the action was skipped. - TRIGGERED: the condition and the action both succeeded. - CONDITION_FAILED or ACTION_FAILED: something failed. The error columns explain why.
The WAS_AUTO_SUSPENDED column shows whether the alert was suspended after reaching SUSPEND_ALERT_AFTER_NUM_FAILURES consecutive failures.
Checkpoint 3 of 7· Check yourself
An alert must notify the team as soon as new ERROR events land in the event table, without a polling schedule. How do you create it?
Leaving out SCHEDULE creates an alert on new data, which fires when matching rows are inserted. EXECUTE ALERT cannot run alerts on new data.
“Execute the CREATE ALERT command to create the alert, and omit the SCHEDULE parameter.”Source: docs.snowflake.com
Checkpoint 4 of 7· Exam question
An administrator ran CREATE EVENT TABLE monitoring.logs.app_events and set LOG_LEVEL = INFO at the account level. Python procedures call logging.info, but no rows ever appear in monitoring.logs.app_events. What is missing?
Correct answer: D — Run ALTER ACCOUNT SET EVENT_TABLE = monitoring.logs.app_events as ACCOUNTADMIN so collection is redirected away from the default table.
- A. Incorrect. Snowflake writes telemetry itself, so procedure owners never need INSERT on the event table, and granting it would not change where records are collected.
- B. Incorrect. Change tracking supports streams on the table but has no effect on which event table receives telemetry from handler code.
- C. Incorrect. EVENT_TABLE is set at the account (or database) level and is not a session parameter that individual users can set.
- D. Correct. Creating an event table does not activate it; until ALTER ACCOUNT SET EVENT_TABLE points to it, telemetry continues to land in the default SNOWFLAKE.TELEMETRY.EVENTS table.
4.Using trace data for root cause analysis and performance tuning
Logs tell you what happened. Traces show where it happened and how long it took. A span is one execution of a function or procedure:
- A stored procedure produces a single span. - A UDF can produce several spans for one call, depending on how Snowflake schedules its execution.
All spans from one query share the same trace_id. A span's duration is its TIMESTAMP minus its START_TIMESTAMP. To capture only the trace data your own code emits, set TRACE_LEVEL to ON_EVENT.
Checkpoint 5 of 7· Fill the gap
You want to capture only the trace data your handler code emits explicitly. Which TRACE_LEVEL value completes the statement?
ALTER SESSION SET TRACE_LEVEL = ? ;ON_EVENT captures only the trace data your own code emits. ALWAYS is the setting Snowsight's Traces toggle uses for full collection.
Source: docs.snowflake.comIn Snowsight, open Monitoring » Traces & logs. Each trace shows its date, duration, name, status and span count. Status is Error if any span reported an error. You can filter by status, date range and database. To work through a root cause analysis:
1. Filter to Error traces. 2. Open a trace's details. The span list shows each span's parent span ID and status code. 3. Use the Query ID to find the query that started the trace. Use User, Role and Warehouse to see the context it ran in. 4. Check the Logs tab for messages the code logged during the span.
For performance, compare span durations to find the slow step. Then open the Related Metrics tab, which charts CPU and memory for Snowpark Python procedures and UDFs. It can tell you whether the problem is heavy compute or memory pressure. You can also capture the SQL text of traced statements by enabling SQL_TRACE_QUERY_TEXT at the account level.
Checkpoint 6 of 7· Put it in order
Put these steps for finding a failing UDF call in Snowsight in order
- 1.Open Monitoring » Traces & logs in Snowsight
- 2.Select the trace row to open its Trace Details page
- 3.Filter the traces by Status to show Error
- 4.Select a span to see its status code, Query ID and Logs tab
You start from the Traces & Logs list, filter it, open a trace's details and then drill into one span. Each step depends on the page the previous step opened.
“To view more detailed information about an entry in its Trace Details page, select the entry’s row.”Source: docs.snowflake.com
Checkpoint 7 of 7· Exam question
A production procedure sales.etl.load_orders fails intermittently. The account LOG_LEVEL is ERROR to limit event table volume, and engineers need DEBUG messages from only this procedure with minimal side effects. What should the administrator do?
Correct answer: B — Run ALTER PROCEDURE sales.etl.load_orders(VARCHAR) SET LOG_LEVEL = DEBUG, then UNSET it once the failures have been diagnosed.
- A. Incorrect. An account-level DEBUG setting makes every procedure and function in the account log verbosely, which inflates event table volume and cost far beyond the one procedure.
- B. Correct. Log level can be set on an individual procedure, overriding the account value, so only that object emits DEBUG messages and the change is easy to revert.
- C. Incorrect. LOG_LEVEL is not a property of the event table; severity filtering happens at the account, database, schema or object where the code runs.
- D. Incorrect. A schema-level setting would be inherited by every object in sales.etl, producing noise from unrelated procedures and UDFs.
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.A scheduled alert should filter event rows on CURRENT_TIMESTAMP minus the schedule interval.Why is that wrong?
That window ignores the delay between when an alert is scheduled and when it runs, so it can miss rows or report them twice. Bound the condition with LAST_SUCCESSFUL_SCHEDULED_TIME() and SCHEDULED_TIME() instead.
Covered in Creating alerts on event table data
2.A UDF call always produces exactly one span, just as a stored procedure does.Why is that wrong?
Only a stored procedure is guaranteed a single span. A UDF can produce several spans for one call, all sharing the query's trace_id.
Covered in Using trace data for root cause analysis and performance tuning
Practise it for real
Send one database's telemetry to its own event table, capture warnings and errors, and query the results
1.Run CREATE EVENT TABLE my_database.my_schema.my_events; with a role that has the CREATE EVENT TABLE privilege.
Why: A custom table lets you DROP it later and control access with privileges you grant yourself.
You should see: SHOW EVENT TABLES lists my_events.
2.Run ALTER DATABASE my_database SET EVENT_TABLE = my_database.my_schema.my_events; then SHOW PARAMETERS LIKE 'event_table' IN DATABASE my_database;
Why: A database association takes precedence over the account's event table. This step requires Enterprise Edition.
You should see: The parameter value shows my_database.my_schema.my_events.
3.Run ALTER DATABASE my_database SET LOG_LEVEL = WARN; then call a procedure or UDF in that database that logs at INFO and at ERROR.
Why: The level is a threshold, so only WARN and more severe messages should be captured.
You should see: After a few seconds, the ERROR message appears in my_events and the INFO message does not.
4.Query my_events for RECORD_TYPE = 'LOG', selecting RECORD['severity_text'], VALUE and RESOURCE_ATTRIBUTES['db.user'].
Why: These columns show the severity, the message and the user who ran the code.
You should see: One row with severity ERROR and your user name.
Stuck? Get a nudge
If no rows appear, check both requirements: is my_events the active table for this database, and does the level allow the message's severity?
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“Metrics are CPU and memory data generated by Snowflake. You can use this data to analyze resource consumption.”
↩︎ Reading the event table for system health“When the log entry is for an unhandled exception, this value is the highest-severity error level for the current language runtime.”
↩︎ Reading the event table for system health“For a function or procedure, the name of the user executing the function or procedure.”
↩︎ Monitoring user activity and controlling access to telemetry“The duration of a span is the difference between the values in the start_timestamp and timestamp columns”
↩︎ Using trace data for root cause analysis and performance tuning“For user-defined functions there may be multiple spans for a single function call, depending on how Snowflake decides to schedule execution.”
↩︎ Exam trap 2“Attributes that identify the source of an event such as database, schema, user, warehouse, Openflow, etc.”
↩︎ Checkpoint - 2.
“Examples include events from Snowpipe, tasks, dynamic tables, Snowpark Container Services compute pools, Iceberg tables, and data governance tag activity.”
↩︎ Reading the event table for system health - 3.https://docs.snowflake.com/en/developer-guide/logging-tracing/logging-accessing-messagesOfficial docs
“The SELECT privilege on a custom event table, if your account uses a custom event table instead of the default.”
↩︎ Monitoring user activity and controlling access to telemetry - 4.
“An alert on new data triggers when new rows matching a condition are inserted into the event table.”
↩︎ Creating alerts on event table data - 5.https://docs.snowflake.com/en/user-guide/alertsOfficial docs
“You cannot use EXECUTE ALERT to execute an alert on new data.”
↩︎ Creating alerts on event table data“LAST_SUCCESSFUL_SCHEDULED_TIME returns the timestamp representing when the last successfully evaluated alert was scheduled.”
↩︎ Exam trap 1“does not account for latency between the time that the alert is scheduled and the time when the alert condition is actually evaluated”
↩︎ Prediction“Execute the CREATE ALERT command to create the alert, and omit the SCHEDULE parameter.”
↩︎ Checkpoint - 6.
“TRIGGERED: The condition was evaluated successfully, and the action was executed successfully.”
↩︎ Creating alerts on event table data - 7.
“Displays charts illustrating CPU and memory metrics for resource consumption by Snowpark Python stored procedures and UDFs.”
↩︎ Using trace data for root cause analysis and performance tuning“Retrieved from the RESOURCE_ATTRIBUTES column snow.session.role.primary.name value.”
↩︎ Checkpoint“To view more detailed information about an entry in its Trace Details page, select the entry’s row.”
↩︎ Checkpoint - 8.https://docs.snowflake.com/en/developer-guide/logging-tracing/tutorials/logging-tracing-getting-startedOfficial docs
“This specifies that only trace data emitted explicitly by your own code should be captured.”
↩︎ Using trace data for root cause analysis and performance tuning