Alerts & Reports#
Superset's Alerts & Reports feature delivers scheduled notifications with rendered chart or dashboard content (PNG screenshots, PDFs, CSV attachments, or inline data tables) via email or Slack.
- Reports run on a cron schedule and always send the content.
- Alerts run a SQL query against a database; the notification fires only when the query result meets a configured threshold (e.g.,
>,!=,not null). Alert logic lives insuperset/commands/report/alert.py.
The feature is disabled by default and must be enabled with the ALERT_REPORTS feature flag . Notification channels are Email, Slack (v1), and Slack v2 (ALERT_REPORT_SLACK_V2 feature flag) .
Architecture#
The beat schedule runs reports.scheduler every minute. scheduler() fetches all active ReportSchedule records, evaluates their cron expressions via cron_schedule_window(), and calls execute.apply_async() with the computed ETA and optional Celery time limits. Each execute task invokes AsyncExecuteReportScheduleCommand , which handles rendering and delivery.
Key files:
| File | Purpose |
|---|---|
superset/tasks/scheduler.py | Celery tasks: reports.scheduler, reports.execute, reports.prune_log |
superset/commands/report/execute.py | Core execution state machine (screenshot, CSV fetch, notification dispatch) |
superset/commands/report/alert.py | Alert SQL execution and threshold evaluation |
superset/reports/models.py | ORM models: ReportSchedule, ReportExecutionLog, ReportRecipients |
superset/reports/notifications/ | Email and Slack notification plugins |
superset/tasks/cron_util.py | cron_schedule_window() — evaluates which schedules fire in the current minute |
superset/utils/webdriver.py | Selenium/Playwright screenshot capture |
superset/utils/machine_auth.py | MachineAuthProvider — generates session cookies for headless browser and CSV fetch |
Required Components#
Alerts & Reports requires three processes running alongside the web server:
- Celery worker — executes
reports.executetasks (renders screenshots, sends notifications). - Celery beat — runs the
reports.schedulertask every minute to queue work. - Redis (or RabbitMQ) — production message broker; the default SQLite broker in
CeleryConfigis for development only.
In the Docker Compose dev environment, these are the superset-worker and superset-worker-beat services . The default CeleryConfig imports superset.tasks.scheduler (which registers all report tasks) plus superset.tasks.thumbnails and superset.tasks.cache .
The beat schedule also includes reports.prune_log (daily at midnight) to clean up old ReportExecutionLog records per each schedule's ALERT_REPORTS_DEFAULT_RETENTION policy .
Configuration Reference#
All defaults are in superset/config.py. Override via superset_config.py.
Feature Flags#
| Flag | Default | Notes |
|---|---|---|
ALERT_REPORTS | False | Master switch — must be True |
ALERT_REPORT_SLACK_V2 | False | Enables Slack v2 notification channel |
PLAYWRIGHT_REPORTS_AND_THUMBNAILS | False | Use Playwright instead of Selenium for screenshots |
Alerts & Reports Settings#
| Config Key | Default | Notes |
|---|---|---|
ALERT_REPORTS_CRON_WINDOW_SIZE | 59 (s) | Sliding cron evaluation window; sync with beat interval minus 1 s |
ALERT_REPORTS_DEFAULT_WORKING_TIMEOUT | 3600 (s) | Per-schedule execution timeout |
ALERT_REPORTS_WORKING_TIME_OUT_KILL | True | Kill tasks exceeding working timeout |
ALERT_REPORTS_EXECUTORS | [ExecutorType.OWNER] | User identity used when fetching data |
ALERT_REPORTS_NOTIFICATION_DRY_RUN | False | Log instead of send (useful for debugging) |
ALERT_REPORTS_QUERY_EXECUTION_MAX_TRIES | 1 | Retries for transient alert SQL errors |
ALERT_REPORTS_DEFAULT_RETENTION | 90 (days) | Log retention per schedule |
ALERT_MINIMUM_INTERVAL / REPORT_MINIMUM_INTERVAL | 0 | Min seconds between executions |
EMAIL_REPORTS_SUBJECT_PREFIX | "[Report] " | Email subject prefix |
SMTP Settings#
Configured at :
| Key | Default |
|---|---|
SMTP_HOST | "localhost" |
SMTP_PORT | 25 |
SMTP_USER / SMTP_PASSWORD | "superset" / "superset" |
SMTP_MAIL_FROM | "superset@superset.com" |
SMTP_STARTTLS | True |
SMTP_SSL | False |
SMTP_SSL_SERVER_AUTH | False |
SMTP_TIMEOUT | 30 s |
Slack Settings#
| Key | Default | Notes |
|---|---|---|
SLACK_API_TOKEN | None | String or callable; required for Slack delivery |
SLACK_PROXY | None | Optional HTTP proxy for Slack API |
SLACK_API_TIMEOUT | 30 s | Slack API call timeout |
Timeout Summary#
| Config Key | Default | Scope |
|---|---|---|
ALERT_REPORTS_CSV_REQUEST_TIMEOUT | 60 s | Internal HTTP call to chart data endpoint |
SMTP_TIMEOUT | 30 s | SMTP socket connection |
SLACK_API_TIMEOUT | 30 s | Slack WebClient calls |
SCREENSHOT_LOAD_WAIT | 60 s | Timeout for chart load in headless browser |
SCREENSHOT_LOCATE_WAIT | 10 s | Timeout to find main container element |
WebDriver / Screenshot Generation#
Screenshots are taken by a headless browser launched inside the Celery worker process. Implementation is in superset/utils/webdriver.py .
| Implementation | Enabled when | Notes |
|---|---|---|
WebDriverSelenium | Default | Supports firefox or chrome |
WebDriverPlaywright | PLAYWRIGHT_REPORTS_AND_THUMBNAILS = True | Chromium only; required for deck.gl |
Key webdriver config keys :
| Key | Default | Notes |
|---|---|---|
WEBDRIVER_TYPE | "firefox" | Selenium driver type |
WEBDRIVER_BASEURL | "http://0.0.0.0:8080/" | Internal URL the headless browser loads — must be reachable from the worker |
WEBDRIVER_BASEURL_USER_FRIENDLY | (same) | External HTTPS URL embedded in notification links |
WEBDRIVER_WINDOW | dashboard: (1600, 2000) | Viewport size |
SCREENSHOT_SELENIUM_HEADSTART | 3 s | Initial sleep before DOM interaction |
SCREENSHOT_SELENIUM_ANIMATION_WAIT | 5 s | Post-load wait for animations |
The dashboard is loaded in ?standalone=3 (report mode) to hide navigation chrome. Authentication is provided by MachineAuthProvider.get_auth_cookies(), which opens a Flask test_request_context, logs in the executor user, and returns session cookies. The provider class is overridable via MACHINE_AUTH_PROVIDER_CLASS .
Screenshots are stored in THUMBNAIL_CACHE_CONFIG. This must be set to a real cache backend (e.g., Redis) — the default is NullCache, which will cause screenshots to fail silently .
For CSV reports, the worker makes a server-to-server HTTP call to Superset's ChartDataRestApi (not Selenium). See Report Scheduler Internal HTTP Requests for the full call flow.
Networking and Proxy Considerations#
When Superset runs behind a TLS-terminating reverse proxy, several settings must be coordinated to keep Celery worker calls working :
| Setting | Correct value | Reason |
|---|---|---|
WEBDRIVER_BASEURL | http://... (internal) | Workers call Superset over the internal network, not through the proxy |
WEBDRIVER_BASEURL_USER_FRIENDLY | https://... (external) | User-facing links in emails should use the public HTTPS URL |
SESSION_COOKIE_SECURE | False (if workers use HTTP) | If True, cookies are silently dropped on HTTP connections, breaking screenshot and CSV generation |
Talisman force_https | False | Setting to True creates redirect loops for internal HTTP requests from Celery workers |
ENABLE_PROXY_FIX | True | Required so Flask reconstructs the correct scheme from X-Forwarded-* headers |
All web server and worker instances must share identical SECRET_KEY and SQLALCHEMY_DATABASE_URI values — mismatches cause silent session decryption failures .