警报和报告
用户可以配置自动警报和报告,将仪表板或图表发送到电子邮件收件人或 Slack 频道。
- 警报 在达到 SQL 条件时发送
- 报告 按计划发送
警报和报告默认是禁用的。要启用它们,您需要进行一些设置,具体描述如下。
要求
通用
在您的 superset_config.py
或 superset_config_docker.py
中
"ALERT_REPORTS"
功能标志 必须设置为 True。beat_schedule
在 CeleryConfig 中必须包含reports.scheduler
的计划。- 至少需要配置以下之一,具体取决于您想要使用的内容:
- 电子邮件:
SMTP_*
设置 - Slack 消息:
SLACK_API_TOKEN
- 电子邮件:
禁用试运行模式
只要 ALERT_REPORTS_NOTIFICATION_DRY_RUN = True
,截图将被拍摄但不会实际发送消息,这是 docker/pythonpath_dev/superset_config.py
中的默认值。要禁用试运行模式并开始接收电子邮件/Slack 通知,请在 superset 配置 中将 ALERT_REPORTS_NOTIFICATION_DRY_RUN
设置为 False
。
在您的 Dockerfile
中
- 您必须安装一个无头浏览器,用于截取图表和仪表板的截图。目前仅支持 Firefox 和 Chrome。
如果您选择 Chrome,还必须在
superset_config.py
中将WEBDRIVER_TYPE
的值更改为"chrome"
。
注意:如果您遵循 本地安装 Superset,所有必需的组件(无头 Firefox 浏览器、Redis、Postgres 数据库、celery worker 和 celery beat)都存在于 dev docker 镜像中。您只需添加本指南中描述的所需配置变量(参见 详细配置
)。
如果您运行的是非 dev 的 docker 镜像,例如 apache/superset:3.1.0
这样的稳定版本,该镜像不包含无头浏览器。只有 superset_worker
容器需要这个无头浏览器来浏览目标图表或仪表板。您可以安装并配置无头浏览器 - 参见下面的“自定义 Dockerfile”部分 - 或者在通过 docker compose
部署时,修改您的 docker-compose.yml
文件,使用 dev 镜像作为 worker 容器,使用稳定版本镜像作为 superset_app
容器。
注意:在此上下文中,“dev 镜像”与其对应的非 dev 镜像具有相同的应用程序软件,只是捆绑了额外的工具。因此,像 3.1.0-dev
这样的镜像在稳定性、功能和生产运行方面与 3.1.0
完全相同。实际上,Superset 的“开发中”版本 - 前沿且不稳定 - 在 Docker Hub 上没有版本号标签,并且在 Superset UI 中会显示版本 0.0.0-dev
。
Slack 集成
要将警报和报告发送到 Slack 频道,您需要在工作区中创建一个新的 Slack 应用程序。
- 连接到您的 Slack 工作区,然后前往 [https://api.slack.com/apps]。
- 创建一个新应用。
- 转到“OAuth & Permissions”部分,并为您的应用授予以下范围:
incoming-webhook
files:write
chat:write
- 在“OAuth and Permissions”部分的顶部,点击“安装到工作区”。
- 选择您的应用的默认频道并继续。 (您可以通过邀请您的 Superset 应用进入该频道来发布到任何频道)。
- 该应用现在应该已安装在您的工作区中,并且应该已创建一个“Bot User OAuth Access Token”。将该令牌复制到
superset_config.py
中的SLACK_API_TOKEN
变量。 - 重新启动服务(或运行
superset init
)以拉取新的配置。
注意:当您配置警报或报告时,Slack 频道列表使用不带前导 #
的频道名称,例如使用 alerts
而不是 #alerts
。
Kubernetes 特定
- 您必须运行一个
celery beat
pod。如果您使用 GitHub 仓库中 helm/superset 下的图表,您需要在您的值覆盖中设置supersetCeleryBeat.enabled = true
。 - 您可以查看关于 Kubernetes 安装 的专用文档以获取更多详细信息。
Docker Compose 特定
您必须在 docker-compose.yml
中包含
- 一个 Redis 消息代理
- PostgreSQL 数据库而不是 SQLlite
- 一个或多个
celery worker
- 一个单独的
celery beat
此过程也适用于 Docker swarm 环境,您只需为 Superset、Redis 和 Postgres 服务添加 Deploy:
以及您的 swarm 特定配置。
详细配置
以下配置需要添加到 superset_config.py
文件中。该文件在镜像运行时加载,其中的任何配置都将覆盖 config.py
中的默认配置。
你可以在GitHub仓库的superset/config.py下找到每个字段的文档说明。
你需要将默认值替换为你自定义的Redis、Slack和/或SMTP配置。
Superset使用Celery beat和Celery worker(s)来发送警报和报告。
- beat是调度器,它告诉worker何时执行其任务。这个调度在你创建警报或报告时定义。
- worker将处理当警报或报告触发时需要执行的任务。
在CeleryConfig
中,只有beat_schedule
与该功能相关,其余的CeleryConfig
可以根据你的需求进行更改。
from celery.schedules import crontab
FEATURE_FLAGS = {
"ALERT_REPORTS": True
}
REDIS_HOST = "superset_cache"
REDIS_PORT = "6379"
class CeleryConfig:
broker_url = f"redis://{REDIS_HOST}:{REDIS_PORT}/0"
imports = (
"superset.sql_lab",
"superset.tasks.scheduler",
)
result_backend = f"redis://{REDIS_HOST}:{REDIS_PORT}/0"
worker_prefetch_multiplier = 10
task_acks_late = True
task_annotations = {
"sql_lab.get_sql_results": {
"rate_limit": "100/s",
},
}
beat_schedule = {
"reports.scheduler": {
"task": "reports.scheduler",
"schedule": crontab(minute="*", hour="*"),
},
"reports.prune_log": {
"task": "reports.prune_log",
"schedule": crontab(minute=0, hour=0),
},
}
CELERY_CONFIG = CeleryConfig
SCREENSHOT_LOCATE_WAIT = 100
SCREENSHOT_LOAD_WAIT = 600
# Slack配置
SLACK_API_TOKEN = "xoxb-"
# 邮件配置
SMTP_HOST = "smtp.sendgrid.net" # 更改为你的主机
SMTP_PORT = 2525 # 你的端口,例如587
SMTP_STARTTLS = True
SMTP_SSL_SERVER_AUTH = True # 如果你的SMTP服务器使用有效证书
SMTP_SSL = False
SMTP_USER = "your_user" # 如果使用未经身份验证的SMTP服务器,请使用空字符串""
SMTP_PASSWORD = "your_password" # 如果使用未经身份验证的SMTP服务器,请使用空字符串""
SMTP_MAIL_FROM = "noreply@youremail.com"
EMAIL_REPORTS_SUBJECT_PREFIX = "[Superset] " # 可选 - 覆盖config.py中的默认值"[Report] "
# WebDriver配置
# 如果你使用Firefox,可以保留默认值
# 如果你使用Chrome,则添加以下WEBDRIVER_TYPE和WEBDRIVER_OPTION_ARGS
WEBDRIVER_TYPE = "chrome"
WEBDRIVER_OPTION_ARGS = [
"--force-device-scale-factor=2.0",
"--high-dpi-support=2.0",
"--headless",
"--disable-gpu",
"--disable-dev-shm-usage",
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-extensions",
]
# 这是内部使用,你可以保留http
WEBDRIVER_BASEURL = "http://superset:8088" # 使用docker compose运行时使用"http://superset_app:8088"
# 这是发送给收件人的链接。更改为你的域名,例如https://superset.mydomain.com
WEBDRIVER_BASEURL_USER_FRIENDLY = "http://localhost:8088"
你还需要指定代表哪个用户名来渲染仪表板。通常,仪表板和图表对未经授权的请求不可访问,这就是为什么worker需要接管现有用户的凭据来截取快照。
默认情况下,警报和报告作为警报/报告对象的所有者执行。要使用固定用户账户,只需按如下方式更改配置(此示例中为admin
):
from superset.tasks.types import ExecutorType
THUMBNAIL_SELENIUM_USER = 'admin'
ALERT_REPORTS_EXECUTE_AS = [ExecutorType.SELENIUM]
请参考代码库中的ExecutorType
了解其他执行器类型。
重要提示
- 注意celery的并发设置(使用
-c 4
)。Selenium/webdriver实例可能会消耗服务器上的大量CPU/内存。 - 在某些情况下,如果你注意到大量泄漏的geckodriver进程,尝试使用
celery worker --pool=prefork --max-tasks-per-child=128 ...
运行你的celery进程。 - 建议为
sql_lab
和email_reports
任务运行单独的worker。这可以通过task_annotations
中的queue
字段来实现。 - 如果celery worker无法通过默认值
http://0.0.0.0:8080/
访问Superset,请调整配置文件中的WEBDRIVER_BASEURL
。
还可以通过配置文件指定每个报告执行之间的最小间隔:
# 设置执行之间的最小间隔阈值(针对每个警报/报告)
# 值应为整数
ALERT_MINIMUM_INTERVAL = int(timedelta(minutes=10).total_seconds())
REPORT_MINIMUM_INTERVAL = int(timedelta(minutes=5).total_seconds())
或者,你可以将函数分配给ALERT_MINIMUM_INTERVAL
和/或REPORT_MINIMUM_INTERVAL
。这在需要动态获取值时很有用:
def alert_dynamic_minimal_interval(**kwargs) -> int:
"""
在此处定义逻辑以动态获取值
"""
ALERT_MINIMUM_INTERVAL = alert_dynamic_minimal_interval
自定义 Dockerfile
如果你正在运行已发布 Superset 镜像的开发版本,例如 apache/superset:3.1.0-dev
,那么按照上述步骤应该已经足够了。
但如果你正在构建自己的镜像,或者从非开发版本开始,则需要一个 WebDriver(以及无头浏览器)来捕获图表和仪表板的截图,这些截图随后会被发送给接收者。以下是如何修改你的 Dockerfile 以使用 Firefox 或 Chrome 进行截图的方法。
使用 Firefox
FROM apache/superset:3.1.0
USER root
RUN apt-get update && \
apt-get install --no-install-recommends -y firefox-esr
ENV GECKODRIVER_VERSION=0.29.0
RUN wget -q https://github.com/mozilla/geckodriver/releases/download/v${GECKODRIVER_VERSION}/geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz && \
tar -x geckodriver -zf geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz -O > /usr/bin/geckodriver && \
chmod 755 /usr/bin/geckodriver && \
rm geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz
RUN pip install --no-cache gevent psycopg2 redis
USER superset
使用 Chrome
FROM apache/superset:3.1.0
USER root
RUN apt-get update && \
apt-get install -y wget zip libaio1
RUN export CHROMEDRIVER_VERSION=$(curl --silent https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_116) && \
wget -O google-chrome-stable_current_amd64.deb -q http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROMEDRIVER_VERSION}-1_amd64.deb && \
apt-get install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb && \
rm -f google-chrome-stable_current_amd64.deb
RUN export CHROMEDRIVER_VERSION=$(curl --silent https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_116) && \
wget -q https://storage.googleapis.com/chrome-for-testing-public/${CHROMEDRIVER_VERSION}/linux64/chromedriver-linux64.zip && \
unzip -j chromedriver-linux64.zip -d /usr/bin && \
chmod 755 /usr/bin/chromedriver && \
rm -f chromedriver-linux64.zip
RUN pip install --no-cache gevent psycopg2 redis
USER superset
如果你使用 Chrome,别忘了在你的配置中设置 WEBDRIVER_TYPE
和 WEBDRIVER_OPTION_ARGS
。
故障排除
报告功能可能无法正常工作的原因有很多。尝试以下步骤来检查具体问题。
确认功能标志已启用且权限足够
如果你在 Superset UI 的设置下拉菜单的 Manage 部分中没有看到“警报与报告”,你需要启用 ALERT_REPORTS
功能标志(见上文)。启用另一个功能标志并检查其是否生效,以验证你的配置文件是否被加载。
以管理员用户身份登录,确保你有足够的权限。
检查 Celery 工作者的日志
这是了解问题的最佳信息来源。在 docker compose 部署中,你可以使用类似 docker logs superset_worker --since 1h
的命令来查看日志。
检查 Web 浏览器和 WebDriver 的安装
为了截图,工作者会使用无头浏览器访问仪表板或图表,然后进行截图。如果你能够以 CSV 或文本形式发送图表,但不能以 PNG 形式发送,问题可能出在浏览器上。
标签以 -dev
结尾的 Superset docker 镜像已经安装了 Firefox 无头浏览器和 geckodriver。你可以通过进入 Superset 工作者并运行 firefox --headless
和 geckodriver
来测试这些是否已正确安装并位于正确的路径中。这两个命令都应该启动相应的应用程序。
如果你自己处理该软件的安装,或者希望使用 Chromium 代替,请自行验证以确保无头浏览器在工作者环境中成功打开。
发送测试邮件
当报告尝试发送时,日志中出现 [Errno 110] Connection timed out
错误是与邮件服务器连接无效的一个症状。
通过测试确认你的出站邮件配置是否正确。以下是最简单的测试,适用于在端口 25 上运行的未经身份验证的 SMTP 邮件服务。如果你通过 SSL 发送邮件,例如,研究 Superset 的代码库如何发送邮件,然后使用这些命令和参数进行测试。
在你的工作者环境中启动 Python,替换所有示例值并运行:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from_email = 'superset_emails@example.com'
to_email = 'your_email@example.com'
msg = MIMEMultipart()
msg['From'] = from_email
msg['To'] = to_email
msg['Subject'] = 'Superset SMTP config test'
message = 'It worked'
msg.attach(MIMEText(message))
mailserver = smtplib.SMTP('smtpmail.example.com', 25)
mailserver.sendmail(from_email, to_email, msg.as_string())
mailserver.quit()
这应该会发送一封邮件。
可能的修复方法:
- 一些云主机禁用未经验证的SMTP邮件发送以防止垃圾邮件。例如,Azure默认在某些机器上阻止25端口。请启用该端口或使用其他发送方法。
- 使用另一组你确认在此设置中有效的SMTP凭证。
从工作节点浏览到你的报告
工作节点可能无法访问报告。它将使用WEBDRIVER_BASEURL
的值来浏览 到报告。如果该路由无效,或者呈现了工作节点无法通过的身份验证挑战,报告截图将失败。
通过尝试curl
你在工作节点错误日志中看到的报告URL来检查这一点。例如,从工作节点环境运行curl http://superset_app:8088/superset/dashboard/1/
。根据仪表板是否存在,你可能会得到不同的响应——例如,你可能需要更改该URL中的1
。如果日志中有来自失败报告截图的URL,那是一个很好的起点。目标是确定WEBDRIVER_BASEURL
的有效值,并确定是否存在HTTPS或身份验证等问题导致工作节点被重定向。
在启用了HTTPS和单点登录等身份验证措施的部署中,让工作节点直接导航到在同一位置运行的Superset应用程序可能是有意义的,从而避免登录的需要。例如,你可以为docker compose部署使用WEBDRIVER_BASEURL="http://superset_app:8088"
,并在TALISMAN_CONFIG
中设置"force_https": False,
。
将查询作为报告调度
你可以选择允许用户直接在SQL Lab中调度查询。这是通过向保存的查询添加额外元数据来实现的,这些元数据随后会被外部调度器(如Apache Airflow)获取。
要允许调度查询,请将以下内容添加到配置文件中的SCHEDULED_QUERIES
:
SCHEDULED_QUERIES = {
# 当用户点击“调度查询”时,此信息会被收集,
# 并保存到保存查询的`extra`字段中。
# 参见:https://github.com/mozilla-services/react-jsonschema-form
'JSONSCHEMA': {
'title': 'Schedule',
'description': (
'为了调度查询,你需要指定查询应何时开始运行、何时停止运行以及运行的频率。'
'你还可以选择指定在执行查询之前应满足的依赖关系。'
'请阅读文档以了解最佳实践以及如何指定依赖关系的更多信息。'
),
'type': 'object',
'properties': {
'output_table': {
'type': 'string',
'title': '输出表名',
},
'start_date': {
'type': 'string',
'title': '开始日期',
# 日期时间使用chrono库解析,参见
# https://www.npmjs.com/package/chrono-node#usage
'format': 'date-time',
'default': '明天上午9点',
},
'end_date': {
'type': 'string',
'title': '结束日期',
# 日期时间使用chrono库解析,参见
# https://www.npmjs.com/package/chrono-node#usage
'format': 'date-time',
'default': '30天后的上午9点',
},
'schedule_interval': {
'type': 'string',
'title': '调度间隔',
},
'dependencies': {
'type': 'array',
'title': '依赖关系',
'items': {
'type': 'string',
},
},
},
},
'UISCHEMA': {
'schedule_interval': {
'ui:placeholder': '@daily, @weekly, 等。',
},
'dependencies': {
'ui:help': (
'定义依赖关系时,请检查文档以获取正确的格式。'
),
},
},
'VALIDATION': [
# 确保start_date <= end_date
{
'name': 'less_equal',
'arguments': ['start_date', 'end_date'],
'message': '结束日期不能早于开始日期',
# 这是错误消息显示的位置
'container': 'end_date',
},
],
# 链接到调度器;此示例链接到使用查询ID和输出表作为名称的Airflow管道
'linkback': (
'https://airflow.example.com/admin/airflow/tree?'
'dag_id=query_${id}_${extra_json.schedule_info.output_table}'
),
}
此配置基于react-jsonschema-form,并将添加一个 在SQL Lab中添加一个名为“Schedule”的菜单项。当点击该菜单项时,将弹出一个模态框,用户可以在其中添加调度查询所需的元数据。
然后可以从/api/v1/saved_query/
端点检索这些信息,并用于调度在其JSON元数据中包含schedule_info
的查询。对于非Airflow的调度器,可以轻松地在上述配置文件中添加额外的字段。