Overview
Snowflake Tasks are the backbone of many automated data pipelines. But when they fail, you often find out too late — after data is stale or downstream processes have broken. In this article, we walk through building a fully automated monitoring system using Snowpark for Python that detects failures, generates an HTML report, and sends an email alert.
Architecture
The system has three main components:
- Snowpark Stored Procedure — queries
SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORYand aggregates failures - HTML Report Generator — builds a rich, colour-coded email body
- Mailer — sends the email via SMTP using Python's
smtplib
Querying Task History
Snowflake exposes task execution history through a system view. We use a configurable lookback window (default: 24 hours) to capture recent failures:
SELECT
NAME,
DATABASE_NAME,
SCHEMA_NAME,
STATE,
ERROR_MESSAGE,
SCHEDULED_TIME,
COMPLETED_TIME
FROM SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORY
WHERE STATE = 'FAILED'
AND SCHEDULED_TIME >= DATEADD('hour', -24, CURRENT_TIMESTAMP())
ORDER BY SCHEDULED_TIME DESC;
Snowpark Stored Procedure
We wrap the query in a Snowpark stored procedure so the entire system runs inside Snowflake — no external infrastructure required:
def task_failure_report(session: Session, lookback_hours: int) -> str:
df = session.sql(f"""
SELECT NAME, STATE, ERROR_MESSAGE, SCHEDULED_TIME
FROM SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORY
WHERE STATE = 'FAILED'
AND SCHEDULED_TIME >= DATEADD('hour', -{lookback_hours}, CURRENT_TIMESTAMP())
""")
return df.to_pandas().to_json(orient="records")
Email Notification
The HTML email uses a colour-coded table to make it easy to scan failures at a glance. Each row shows the task name, database, schema, error message, and scheduled time.
You can extend this pattern to post alerts to Slack or Teams webhooks using the same Snowpark stored procedure — just swap the email step for an HTTP request.
Scheduling with Tasks
Finally, we schedule the monitoring procedure itself using a Snowflake Task on a cron schedule so it runs automatically every day:
CREATE OR REPLACE TASK MONITOR_TASK_FAILURES
WAREHOUSE = COMPUTE_WH
SCHEDULE = 'USING CRON 0 8 * * * UTC'
AS
CALL SP_TASK_FAILURE_REPORT(24);
Conclusion
With fewer than 200 lines of Python and SQL, you now have a self-contained monitoring system that lives entirely inside Snowflake. No external servers, no cron jobs on EC2 — just Tasks and Snowpark.