Superset配置Report & Alert实践及二次开发实践

Superset配置Report & Alert实践及二次开发实践

项目背景与概述

Apache Superset 是一个现代化的数据探索和可视化平台,提供了强大的自动报警和报表功能。通过这些功能,用户可以将仪表板或图表自动发送到指定的电子邮件收件人或Slack频道,主要包括两种类型:

  • 警报(Alert):当SQL查询满足特定条件时触发发送
  • 报表(Report):按照预设的时间计划定期发送

然而,在实际使用过程中,我发现其截屏功能存在一些限制 - 只能以固定窗口大小进行截屏,这可能导致报表中的图表内容被截断或产生多余的空白区域。为了解决这个问题,我进行了相关的二次开发。本文将详细介绍Report & Alert功能的配置方法,以及如何通过二次开发优化截屏功能。

Report & Alert配置指南

前置要求

1. 基础配置

superset_config.pysuperset_config_docker.py中需要:

  1. 启用功能标志:
python 复制代码
FEATURE_FLAGS = {
    "ALERT_REPORTS": True
}
  1. 配置Celery调度:
python 复制代码
from celery.schedules import crontab

class CeleryConfig:
    # ... 其他Celery配置 ...
    beat_schedule = {
        "reports.scheduler": {
            "task": "reports.scheduler",
            "schedule": crontab(minute="*", hour="*"),
        },
        "reports.prune_log": {
            "task": "reports.prune_log",
            "schedule": crontab(minute=0, hour=0),
        },
    }
  1. 配置通知方式(至少选择一种):
    • 邮件通知:配置SMTP_*相关设置
    • Slack通知:配置SLACK_API_TOKEN
2. 环境要求
  1. 必须安装无头浏览器(Firefox或Chrome)用于截图
  2. 如果使用Chrome,需要在配置中设置:
python 复制代码
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",
]

详细配置示例

python 复制代码
# Redis配置
REDIS_HOST = "superset_cache"
REDIS_PORT = "6379"

# 截图等待时间配置
SCREENSHOT_LOCATE_WAIT = 100
SCREENSHOT_LOAD_WAIT = 600

# Slack配置
SLACK_API_TOKEN = "xoxb-your-token"

# 邮件配置
SMTP_HOST = "smtp.sendgrid.net"
SMTP_PORT = 2525
SMTP_STARTTLS = True
SMTP_SSL_SERVER_AUTH = True
SMTP_SSL = False
SMTP_USER = "your_user"
SMTP_PASSWORD = "your_password"
SMTP_MAIL_FROM = "[email protected]"
EMAIL_REPORTS_SUBJECT_PREFIX = "[Superset] "

# WebDriver配置
WEBDRIVER_BASEURL = "http://superset:8088"
WEBDRIVER_BASEURL_USER_FRIENDLY = "https://your-domain.com:8088"

# 执行用户配置
from superset.tasks.types import ExecutorType
THUMBNAIL_SELENIUM_USER = 'admin'
ALERT_REPORTS_EXECUTE_AS = [ExecutorType.SELENIUM]

# 最小执行间隔配置
from datetime import timedelta
ALERT_MINIMUM_INTERVAL = int(timedelta(minutes=10).total_seconds())
REPORT_MINIMUM_INTERVAL = int(timedelta(minutes=5).total_seconds())

重要说明

  1. 关于Celery并发

    • 建议使用-c 4限制并发数,因为Selenium/webdriver会消耗大量资源
    • 如果发现geckodriver进程泄露,尝试使用:celery worker --pool=prefork --max-tasks-per-child=128
  2. Worker配置

    • 建议为sql_lab和email_reports任务运行独立的worker
    • 可以通过task_annotations中的queue字段配置
  3. 故障排查

    • 检查Celery worker日志
    • 验证浏览器和webdriver安装
    • 测试邮件发送功能
    • 确认worker可以访问报表URL

功能改进:自适应截屏

问题描述

原版Superset(3.1.*)在进行截屏时使用了预设的固定窗口大小:

python 复制代码
driver.set_window_size(*self._window)

这种方式无法根据实际内容自动调整窗口大小,可能导致以下问题:

  • 内容过长时被截断
  • 内容较短时产生多余空白
  • 无法完整捕获仪表板的所有内容

改进方案

我对get_screenshot()函数进行了优化,主要改动如下(完整代码可见GitHub提交记录):

python 复制代码
# 屏蔽预设的窗口配置
# driver.set_window_size(*self._window)
driver.get(url)
img: bytes | None = None
selenium_headstart = current_app.config["SCREENSHOT_SELENIUM_HEADSTART"]
logger.debug("Sleeping for %i seconds", selenium_headstart)
sleep(selenium_headstart)

# 使用JavaScript获取页面实际高度并设置窗口大小
height = driver.execute_script("return document.documentElement.scrollHeight")
driver.set_window_size(self._window[0], height)

改进后的代码可以:

  1. 通过JavaScript获取页面的实际高度
  2. 动态调整窗口大小以适应内容
  3. 确保截图包含所有内容,无多余空白

项目结构导读

在开始开发之前,了解Superset的项目结构很重要。以下是主要目录结构:

复制代码
superset/
├── superset/              # 后端Python代码
│   ├── views/            # 视图层,处理HTTP请求
│   ├── models/           # 数据模型
│   ├── utils/            # 工具类,我们的截屏功能就在这里
│   ├── extensions/       # Flask扩展
│   └── ...
├── superset-frontend/    # 前端代码
│   ├── src/             # 源代码
│   ├── packages/        # 可重用的包
│   └── ...
├── docker/              # Docker相关配置
├── tests/              # 测试用例
└── ...

关键模块说明

  1. 后端核心模块

    • superset/views/: 包含所有视图函数,处理HTTP请求
    • superset/models/: 定义数据库模型
    • superset/utils/: 包含各种工具函数,如我们修改的截屏功能
    • superset/config.py: 配置文件
  2. 前端核心模块

    • superset-frontend/src/views/: 页面组件
    • superset-frontend/src/components/: 可重用组件
    • superset-frontend/src/visualizations/: 可视化组件
  3. Docker相关

    • docker/: 包含Docker相关配置
    • Dockerfile: 主Dockerfile文件

开发环境搭建指南

1. 使用Docker Compose搭建开发环境

因为项目依赖较多,推荐使用Docker Compose来搭建开发环境。首先需要创建一个适合开发的docker-compose配置文件。

  1. 克隆项目代码:
bash 复制代码
git clone [email protected]:apache/superset.git
cd superset
  1. 创建开发环境配置文件:
bash 复制代码
cp docker-compose.yml docker-compose-local.yml
  1. 修改docker-compose-local.yml,主要改动如下:
yaml 复制代码
// ... existing code ...
x-superset-image: &superset-image apache/superset:latest-dev
// ... existing code ...
  superset:
    env_file: docker/.env
    build: 
      context: .
      dockerfile: Dockerfile
      target: dev
    image: *superset-image
// ... existing code ...
  1. 启动开发环境:
bash 复制代码
docker compose -f docker-compose-local.yml up

主要改动说明:

  1. 将远程镜像地址 apachesuperset.docker.scarf.sh/apache/superset:${TAG:-latest-dev} 改为本地镜像名称 apache/superset:latest-dev
  2. 在 superset 服务中添加了 build 配置,指定使用本地的 Dockerfile 进行构建
  3. 使用 target: dev 指定构建开发环境镜像
    这样修改后,当您运行 docker-compose up 时,系统会先使用本地的 Dockerfile 构建镜像,而不是从远程仓库拉取。其他依赖这个镜像的服务(如 superset-worker、superset-init 等)会自动使用这个本地构建的镜像。
    记得在运行前执行:
bash 复制代码
docker-compose -f docker-compose-local.yml build

来构建本地镜像。

2. 本地开发流程

  1. 创建并切换到新的开发分支:
bash 复制代码
git checkout -b feature/screenshot-improvement
  1. 修改代码后,需要重新构建Docker镜像:
bash 复制代码
docker compose -f docker-compose-local.yml down
docker compose -f docker-compose-local.yml build
docker compose -f docker-compose-local.yml up

3. 开发调试技巧

  1. 实时代码修改

    • 由于配置了代码目录挂载,修改Python代码后会自动重载
    • 修改前端代码需要在superset-frontend目录下运行npm run dev
  2. 查看日志

bash 复制代码
# 查看所有容器日志
docker compose -f docker-compose-local.yml logs -f

# 只查看superset容器日志
docker compose -f docker-compose-local.yml logs -f superset
  1. 数据库操作
bash 复制代码
# 进入容器
docker exec -it superset_app bash

# 执行数据库迁移
superset db upgrade

# 创建管理员用户
superset fab create-admin

4. 生产环境部署

根据不同的部署环境和需求,这里提供几种部署方案:

方案一:直接修改Python包源码(最简单)

适用场景:单机部署,快速验证

  1. 找到Superset安装目录:
bash 复制代码
# 查看superset包安装位置
pip show apache-superset | grep Location
  1. 直接修改目标文件:
bash 复制代码
# 例如修改截屏功能
cd <superset安装路径>/superset/utils/
vim webdriver.py

# 修改完成后重启Superset服务
sudo systemctl restart superset
# 或者
supervisorctl restart superset

优点:

  • 操作简单直接
  • 无需构建镜像
  • 适合快速验证修改

缺点:

  • 不适合多机部署
  • 版本管理困难
  • 系统升级时修改会被覆盖
方案二:使用Docker镜像(推荐)

适用场景:正式生产环境,多机部署

  1. 确保代码经过充分测试
  2. 创建发布分支
  3. 构建生产环境镜像:
bash 复制代码
docker build -t your-registry/superset:your-tag .
  1. 推送镜像到镜像仓库:
bash 复制代码
docker push your-registry/superset:your-tag
  1. 在生产环境更新镜像版本并重启服务:
bash 复制代码
# 拉取新镜像
docker pull your-registry/superset:your-tag

# 更新服务
docker compose -f docker-compose-prod.yml up -d

优点:

  • 环境一致性好
  • 便于版本管理
  • 适合多机部署
  • 回滚方便

缺点:

  • 需要维护Docker镜像仓库
  • 部署流程相对复杂
方案三:使用pip安装自定义包

适用场景:需要在多个项目中复用修改,或需要维护自己的版本

  1. 创建自定义包:
bash 复制代码
# 克隆原始代码
git clone https://github.com/apache/superset.git
cd superset

# 修改版本号(避免冲突)
vim setup.py  # 修改version为自定义版本,如"3.1.0-custom"
  1. 构建并上传到私有PyPI仓库:
bash 复制代码
# 构建包
python setup.py sdist bdist_wheel

# 上传到私有PyPI仓库
twine upload --repository-url https://your-pypi-repo/simple/ dist/*
  1. 在生产环境安装:
bash 复制代码
pip install -i https://your-pypi-repo/simple/ apache-superset==3.1.0-custom

优点:

  • 便于在多个项目中复用
  • 可以维护自己的版本
  • 支持通过pip管理依赖

缺点:

  • 需要维护私有PyPI仓库
  • 版本号管理需要注意
方案四:使用Helm在Kubernetes中部署

适用场景:Kubernetes环境

  1. 修改Helm配置:
yaml 复制代码
# values.yaml
image:
  repository: your-registry/superset
  tag: your-tag
  1. 部署/更新:
bash 复制代码
# 首次部署
helm install superset ./helm/superset -f values.yaml

# 更新部署
helm upgrade superset ./helm/superset -f values.yaml

优点:

  • 适合云原生环境
  • 便于扩展和管理
  • 配置灵活

缺点:

  • 需要Kubernetes环境
  • 学习成本较高

开发建议

  1. 环境隔离:始终使用Docker进行开发,确保环境一致性

  2. 代码规范

    • 遵循项目的代码风格指南
    • 添加适当的注释
    • 编写测试用例
  3. 版本控制

    • 创建功能分支进行开发
    • 提交信息要清晰明了
    • 定期与主分支同步
  4. 测试验证

    • 本地充分测试
    • 在开发环境验证
    • 考虑边界情况

结论

通过这次二次开发实践,不仅解决了Superset截屏功能的限制,也积累了宝贵的开发经验。对于想要进行Superset二次开发的开发者,建议:

  1. 充分阅读项目文档
  2. 使用Docker管理开发环境
  3. 遵循项目的开发规范
  4. 循序渐进,从小改动开始

希望这篇文章能帮助到想要进行Superset二次开发的同学们!

参考资料

  1. Superset警报和报表配置指南
  2. Superset开发环境搭建指南
相关推荐
End9281 小时前
Spark之搭建Yarn模式
大数据·分布式·spark
我爱写代码?1 小时前
Spark 集群配置、启动与监控指南
大数据·开发语言·jvm·spark·mapreduce
TDengine (老段)1 小时前
什么是物联网 IoT 平台?
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
青云交1 小时前
Java 大视界 -- 基于 Java 的大数据分布式存储在工业互联网海量设备数据长期存储中的应用优化(248)
java·大数据·工业互联网·分布式存储·冷热数据管理·hbase 优化·kudu 应用
艾醒(AiXing-w)2 小时前
探索大语言模型(LLM):国产大模型DeepSeek vs Qwen,谁才是AI模型的未来?
大数据·人工智能·语言模型
£菜鸟也有梦2 小时前
从0到1上手Kafka:开启分布式消息处理之旅
大数据·kafka·消息队列
Elastic 中国社区官方博客3 小时前
在 Elasticsearch 中删除文档中的某个字段
大数据·数据库·elasticsearch·搜索引擎
时序数据说3 小时前
时序数据库IoTDB分布式系统监控基础概述
大数据·数据库·database·时序数据库·iotdb
漂流瓶6666664 小时前
Spark处理过程-转换算子
大数据·分布式·spark
双流元宇宙产业园4 小时前
元宇宙赛道新势力:成都芯谷产业园创新业务如何重构产业格局
大数据