Skip to main content

A lightweight local task scheduler with CLI, web UI, and email reporting

Project description

TaskWatch

轻量级本地任务调度器,集 CLI 管理、Web 仪表盘和邮件报告于一体。

核心特性

  • CLI 管理:基于 Typer + Rich 的命令行工具,支持任务增删改查、手动触发、日志查看
  • Web 仪表盘:FastAPI 驱动的 Web 管理界面,实时查看任务状态与运行趋势
  • APScheduler 调度:支持 cron 表达式和 interval 间隔两种调度方式
  • SQLite 持久化:WAL 模式本地数据库,零配置、高可靠
  • SMTP 邮件通知/告警:任务失败即时告警,支持多账号轮转与冷却机制
  • 日报/周报自动生成:定时汇总任务运行情况,自动生成 HTML 报告并邮件发送

快速启动(Quick Start)

环境要求

  • Python >= 3.9
  • pip(或其他兼容的包管理器)

安装步骤

# 克隆或进入项目目录
cd taskwatch-project

# 开发模式安装(推荐)
pip install -e .

# 或直接安装
pip install .

安装完成后,系统会注册两个命令入口:twtaskwatch(功能相同)。

最小化使用示例

# 1. 初始化(创建数据库、配置文件、日志目录)
tw init

# 2. 添加一个任务:每天早上 9 点执行
tw task add --name "hello" --command "echo Hello TaskWatch" --schedule "0 9 * * *"

# 3. 启动调度器(前台运行)
tw run

# 4. 或者启动 Web 管理界面(内嵌调度器)
tw web

默认访问地址

启动 Web UI 后,默认监听地址为:

http://127.0.0.1:8899

可通过 --host--port 参数自定义:

tw web --host 0.0.0.0 --port 9000

详细使用教程

CLI 命令完整说明

tw init

初始化 TaskWatch 工作环境:创建数据目录、SQLite 数据库、默认配置文件,并可选配置 SMTP。

tw init

tw task — 任务管理

命令 说明 示例
tw task add 添加新任务 tw task add -n "backup" -c "python backup.py" -s "0 2 * * *"
tw task list 列出所有任务 tw task list --status enabled
tw task show <ID> 查看任务详情与统计 tw task show 1
tw task edit <ID> 编辑任务属性 tw task edit 1 --schedule "30 8 * * *"
tw task rm <ID> 删除任务 tw task rm 1 --force
tw task enable <ID> 启用任务 tw task enable 1
tw task disable <ID> 禁用任务 tw task disable 1
tw task run <ID> 手动触发一次运行 tw task run 1

task add 完整参数:

tw task add \
  --name "my_task" \           # 任务名称(必填)
  --command "python run.py" \  # 执行命令(必填)
  --schedule "0 9 * * *" \    # 调度表达式(必填)
  --timeout 3600 \             # 超时时间(秒),默认 3600
  --retry 3 \                  # 最大重试次数,默认 3
  --retry-interval 60 \        # 重试间隔(秒),默认 60
  --working-dir "/path" \      # 工作目录
  --env "KEY1=val1,KEY2=val2" \ # 环境变量
  --tags "daily,etl" \         # 标签(逗号分隔)
  --notify on_failure          # 通知策略:always / on_failure / never

tw run — 启动调度器

# 前台运行(Ctrl+C 停止)
tw run

# 后台守护进程模式(仅 Unix 系统)
tw run --daemon

tw log — 查看日志

# 查看任务最近运行记录及日志
tw log 1

# 查看指定运行记录的日志
tw log 1 --run-id 42

# 显示最近 50 行
tw log 1 --tail 50

# 实时跟踪日志输出
tw log 1 --follow

tw report — 生成报告

# 生成今日日报
tw report daily

# 生成指定日期的日报并发送邮件
tw report daily 2025-01-15 --send

# 生成本周周报
tw report weekly

# 生成指定周期的周报并发送
tw report weekly 2025-01-06 2025-01-12 --send

tw config — 配置管理

# 查看所有配置
tw config --list

# 查看某个配置项
tw config smtp.host

# 修改配置项
tw config smtp.host smtp.qq.com
tw config smtp.port 465
tw config alert.cooldown_minutes 30

tw mail — 邮件测试

# 发送测试邮件验证 SMTP 配置
tw mail test

tw web — Web 管理界面

# 默认启动(127.0.0.1:8899,自动打开浏览器)
tw web

# 自定义端口,不自动打开浏览器
tw web --port 9000 --no-browser

Web UI 各页面功能说明

页面 路径 功能
仪表盘 / 任务总数、今日运行数、成功率、运行中数量;近 7 天趋势图;最近运行记录
任务管理 /tasks 任务列表、搜索过滤、新建/编辑/删除任务、启用/禁用开关、手动运行
任务详情 /tasks/{id} 任务配置信息、运行统计(总次数/成功率/平均耗时)、最近运行记录
运行日志 /logs 多条件过滤(任务/状态/触发方式/时间范围)、分页浏览、日志详情弹窗
报告中心 /reports 日报/周报历史列表、手动生成报告、查看报告详情、重新发送邮件
系统设置 /settings SMTP 配置、报告时间配置、告警配置、数据库/日志路径、日志清理

配置文件说明

配置文件为 config.toml(TOML 格式),位于工作目录下。首次运行 tw init 时自动创建。

[core]
database_path = "./taskwatch.db"    # 数据库文件路径
log_dir = "./logs"                  # 日志目录
pid_file = "./taskwatch.pid"        # PID 文件路径

[smtp]
enabled = false                     # 是否启用 SMTP
host = "smtp.gmail.com"            # SMTP 服务器
port = 587                          # 端口
use_tls = true                      # 是否使用 TLS
username = ""                       # 用户名
password = ""                       # 密码(也可通过环境变量 TASKWATCH_SMTP_PASSWORD 设置)
from_addr = ""                      # 发件人地址
to_addrs = []                       # 收件人列表

[retry]
default_retry = 3                   # 默认重试次数
default_retry_interval = 60         # 默认重试间隔(秒)

[timeout]
default_timeout = 3600              # 默认任务超时(秒)

[logging]
max_log_files = 100                 # 最大日志文件数
max_log_age_days = 30               # 日志保留天数

[web]
host = "127.0.0.1"                 # Web 监听地址
port = 8899                         # Web 监听端口
auto_open_browser = true            # 启动时自动打开浏览器

[report]
daily_time = "10:00"                # 日报发送时间
daily_enabled = true                # 是否启用日报
weekly_day = "monday"               # 周报发送星期
weekly_time = "11:00"               # 周报发送时间
weekly_enabled = true               # 是否启用周报

[alert]
enabled = true                      # 是否启用失败告警
cooldown_minutes = 10               # 告警冷却时间(分钟)

任务调度类型说明

TaskWatch 支持两种调度方式,系统会根据表达式格式自动识别:

类型 格式 示例 说明
cron 标准 5 位 cron 表达式 0 9 * * * 每天 9:00 执行
cron 带秒的 6 位表达式 30 0 9 * * * 每天 9:00:30 执行
interval 数字 + 单位 30m2h1d 每 30 分钟 / 2 小时 / 1 天执行一次

cron 表达式字段说明:

┌──────── 分钟 (0-59)
│ ┌────── 小时 (0-23)
│ │ ┌──── 日 (1-31)
│ │ │ ┌── 月 (1-12)
│ │ │ │ ┌ 星期 (0-6, 0=周日)
│ │ │ │ │
* * * * *

interval 格式说明:

  • 30s — 每 30 秒
  • 5m — 每 5 分钟
  • 2h — 每 2 小时
  • 1d — 每 1 天

邮件通知与告警机制

通知策略

每个任务可独立设置通知策略(--notify 参数):

策略 说明
on_failure 仅在任务失败时发送告警邮件(默认)
always 每次运行完成后都发送通知
never 不发送任何通知

多账号轮转

在配置文件中可配置多个 SMTP 账号(smtp.accounts 列表),系统发送邮件时会自动轮转使用,避免单账号发送频率限制。

失败告警冷却

为防止同一任务频繁失败导致邮件轰炸,系统设有告警冷却机制:

  • 默认冷却时间:10 分钟
  • 同一任务在冷却期内不会重复发送告警
  • 可通过 alert.cooldown_minutes 配置调整

项目架构

目录结构

taskwatch/
├── __init__.py                     # 包入口,版本定义
├── cli/                            # CLI 命令行层
│   ├── __init__.py
│   ├── main.py                     # Typer 主应用,注册所有子命令
│   ├── task.py                     # 任务管理命令 (add/list/show/edit/rm/enable/disable/run)
│   ├── run.py                      # 调度器启动命令
│   ├── log.py                      # 日志查看命令
│   └── report.py                   # 报告生成命令 (daily/weekly)
├── core/                           # 核心业务逻辑层
│   ├── __init__.py
│   ├── models.py                   # SQLite 数据层(tasks/runs/reports 表 CRUD)
│   ├── executor.py                 # 子进程任务执行器(超时控制、日志捕获)
│   ├── scheduler.py                # APScheduler 调度引擎(cron/interval 触发器)
│   ├── notifier.py                 # SMTP 邮件通知(多账号轮转、告警冷却)
│   └── reporter.py                 # 日报/周报生成引擎(HTML 报告)
├── utils/                          # 工具层
│   ├── __init__.py
│   ├── config.py                   # TOML 配置管理(全局单例)
│   └── logger.py                   # 日志工具
└── web/                            # Web 展示层
    ├── __init__.py
    ├── app.py                      # FastAPI 应用工厂 (create_app)
    ├── api/                        # REST API 路由
    │   ├── __init__.py
    │   ├── stats.py                # 统计数据接口
    │   ├── tasks.py                # 任务 CRUD 接口
    │   ├── runs.py                 # 运行记录接口
    │   ├── reports.py              # 报告生成/查看/重发接口
    │   └── settings.py             # 配置读写/测试邮件/日志清理接口
    ├── routes/                     # 页面路由(服务端渲染)
    │   ├── __init__.py
    │   ├── dashboard.py            # 仪表盘页面
    │   ├── tasks.py                # 任务管理 + 任务详情页面
    │   ├── logs.py                 # 运行日志页面
    │   ├── reports.py              # 报告中心页面
    │   └── settings.py             # 系统设置页面
    ├── static/
    │   └── css/
    │       └── style.css           # 自定义样式(滚动条、过渡动画)
    └── templates/                  # Jinja2 HTML 模板
        ├── base.html               # 基础布局(导航栏、Toast、API 工具函数)
        ├── dashboard.html          # 仪表盘(统计卡片 + Chart.js 趋势图)
        ├── tasks.html              # 任务列表(搜索/过滤/新建/编辑弹窗)
        ├── task_detail.html        # 任务详情(配置/统计/运行记录)
        ├── logs.html               # 日志(多条件过滤/分页/详情弹窗)
        ├── reports.html            # 报告中心(日报/周报/生成/重发)
        └── settings.html           # 设置(SMTP/报告/告警/数据库配置)

各模块职责说明

模块 职责
cli/ 基于 Typer 的命令行入口,提供任务管理、调度器控制、日志查看、报告生成等命令
core/models.py SQLite 数据持久化层,管理 tasks、runs、reports 三张表的 CRUD 操作
core/executor.py 子进程任务执行器,负责命令执行、超时控制、stdout/stderr 捕获、日志文件写入
core/scheduler.py 基于 APScheduler BackgroundScheduler 的调度引擎,管理任务的注册/注销/触发
core/notifier.py SMTP 邮件发送模块,支持多账号轮转、失败告警冷却、测试邮件
core/reporter.py 报告生成引擎,汇总任务运行数据生成 HTML 格式日报/周报
utils/config.py TOML 配置文件管理,全局单例模式,支持深层嵌套读写
utils/logger.py 日志工具,提供统一的日志记录接口
web/app.py FastAPI 应用工厂,组装静态文件、模板、API 路由和页面路由
web/api/ RESTful API 接口,供前端 AJAX 调用
web/routes/ 服务端渲染页面路由,返回 Jinja2 模板响应
web/templates/ HTML 模板,使用 Tailwind CSS + HTMX + Chart.js

技术栈

技术 用途
Typer CLI 框架
Rich 终端美化输出(表格、颜色)
FastAPI Web 框架
Uvicorn ASGI 服务器
APScheduler 任务调度引擎
SQLite (WAL) 数据持久化
Jinja2 HTML 模板引擎
Tailwind CSS 前端样式(CDN)
HTMX 前端交互增强(CDN)
Chart.js 数据可视化图表(CDN)
tomli / tomli_w TOML 配置读写
smtplib 邮件发送(标准库)

设计思路

分层架构设计

┌─────────────────────────────────────────────┐
│              CLI 层 (cli/)                    │  用户交互入口
├─────────────────────────────────────────────┤
│              Web 展示层 (web/)                │  可视化管理界面
├─────────────────────────────────────────────┤
│              Core 业务层 (core/)              │  核心逻辑:调度、执行、通知、报告
├─────────────────────────────────────────────┤
│              Utils 工具层 (utils/)            │  基础设施:配置、日志
└─────────────────────────────────────────────┘
  • CLI 层Web 层作为两个独立的用户交互入口,共享底层 Core 业务逻辑
  • Core 层不依赖任何 UI 框架,可被 CLI 和 Web 共同调用
  • Utils 层提供配置管理和日志等基础能力,被所有上层模块引用

数据持久化方案

  • 采用 SQLite WAL(Write-Ahead Logging)模式,支持并发读写,无需额外数据库服务
  • 数据库文件默认位于工作目录下的 taskwatch.db
  • 三张核心表:tasks(任务定义)、runs(运行记录)、reports(报告历史)
  • 通过 row_factory = sqlite3.Row 实现字典式行访问

调度引擎选型

选用 APScheduler BackgroundScheduler

  • 纯 Python 实现,无外部依赖(无需 Redis/RabbitMQ)
  • 原生支持 cron 和 interval 两种触发器
  • 后台线程运行,不阻塞主进程
  • 支持动态添加/移除/暂停任务
  • 适合本地轻量调度场景

Web 工厂模式

def create_app() -> FastAPI:
    """应用工厂函数"""
    app = FastAPI(lifespan=lifespan)
    # 挂载静态文件、注册模板、注册 API 路由、注册页面路由
    return app
  • 通过 create_app() 工厂函数创建应用实例,便于测试和 Uvicorn 加载
  • API 路由(/api/*)与页面路由(//tasks/logs 等)模块化分离
  • 使用 lifespan 上下文管理器在应用启动时自动启动内嵌调度器

前端轻量方案

  • 无需构建步骤:所有前端依赖通过 CDN 引入(Tailwind CSS、HTMX、Chart.js)
  • 服务端渲染:Jinja2 模板直出 HTML,首屏加载快
  • 渐进增强:HTMX 处理动态交互,原生 JavaScript 处理复杂逻辑(分页、轮询)
  • 零前端工程化:无需 Node.js、npm、webpack 等工具链

免责声明

  • 本项目为本地轻量工具,设计用于个人或小团队的本地任务调度场景,不适用于生产环境高可用、高并发场景
  • 任务执行依赖本地系统环境(Shell、Python 解释器等),项目不对用户命令的执行结果负责
  • 邮件发送功能依赖用户自行配置的 SMTP 服务,项目不保证邮件一定能成功送达
  • 数据存储为本地 SQLite 文件,用户需自行做好数据备份,项目不对数据丢失承担责任。
  • 本项目按 "原样"(AS IS) 提供,不附带任何明示或暗示的保证,包括但不限于适销性、特定用途适用性和非侵权性的保证。

许可证

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

taskwatch-0.1.0.tar.gz (58.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

taskwatch-0.1.0-py3-none-any.whl (67.0 kB view details)

Uploaded Python 3

File details

Details for the file taskwatch-0.1.0.tar.gz.

File metadata

  • Download URL: taskwatch-0.1.0.tar.gz
  • Upload date:
  • Size: 58.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.3

File hashes

Hashes for taskwatch-0.1.0.tar.gz
Algorithm Hash digest
SHA256 33f0ea9b09bd75156baf82f6cad2e491584575f38e44c50bd0ec881d5fb83348
MD5 30bc09e1d862a8300ff2d3a4da8653fd
BLAKE2b-256 90919abc967d240030d78490025f9976c0bdb20bc7297372de83a9418a97bb31

See more details on using hashes here.

File details

Details for the file taskwatch-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: taskwatch-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 67.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.3

File hashes

Hashes for taskwatch-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e3df33f524a83cd75c51a1e2578fe8cededeef5acc8ea690e99bce2d71c1ba52
MD5 31e0de990c416cf2813c1629da90756f
BLAKE2b-256 fb7560ccc03005d0e6ab7e73f46fb95e0f061136370836b135ef1b04f5d4011e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page