jettask 0.2.23__py3-none-any.whl → 0.2.24__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jettask/__init__.py +2 -0
- jettask/cli.py +12 -8
- jettask/config/lua_scripts.py +37 -0
- jettask/config/nacos_config.py +1 -1
- jettask/core/app.py +313 -340
- jettask/core/container.py +4 -4
- jettask/{persistence → core}/namespace.py +93 -27
- jettask/core/task.py +16 -9
- jettask/core/unified_manager_base.py +136 -26
- jettask/db/__init__.py +67 -0
- jettask/db/base.py +137 -0
- jettask/{utils/db_connector.py → db/connector.py} +130 -26
- jettask/db/models/__init__.py +16 -0
- jettask/db/models/scheduled_task.py +196 -0
- jettask/db/models/task.py +77 -0
- jettask/db/models/task_run.py +85 -0
- jettask/executor/__init__.py +0 -15
- jettask/executor/core.py +76 -31
- jettask/executor/process_entry.py +29 -114
- jettask/executor/task_executor.py +4 -0
- jettask/messaging/event_pool.py +928 -685
- jettask/messaging/scanner.py +30 -0
- jettask/persistence/__init__.py +28 -103
- jettask/persistence/buffer.py +170 -0
- jettask/persistence/consumer.py +330 -249
- jettask/persistence/manager.py +304 -0
- jettask/persistence/persistence.py +391 -0
- jettask/scheduler/__init__.py +15 -3
- jettask/scheduler/{task_crud.py → database.py} +61 -57
- jettask/scheduler/loader.py +2 -2
- jettask/scheduler/{scheduler_coordinator.py → manager.py} +23 -6
- jettask/scheduler/models.py +14 -10
- jettask/scheduler/schedule.py +166 -0
- jettask/scheduler/scheduler.py +12 -11
- jettask/schemas/__init__.py +50 -1
- jettask/schemas/backlog.py +43 -6
- jettask/schemas/namespace.py +70 -19
- jettask/schemas/queue.py +19 -3
- jettask/schemas/responses.py +493 -0
- jettask/task/__init__.py +0 -2
- jettask/task/router.py +3 -0
- jettask/test_connection_monitor.py +1 -1
- jettask/utils/__init__.py +7 -5
- jettask/utils/db_init.py +8 -4
- jettask/utils/namespace_dep.py +167 -0
- jettask/utils/queue_matcher.py +186 -0
- jettask/utils/rate_limit/concurrency_limiter.py +7 -1
- jettask/utils/stream_backlog.py +1 -1
- jettask/webui/__init__.py +0 -1
- jettask/webui/api/__init__.py +4 -4
- jettask/webui/api/alerts.py +806 -71
- jettask/webui/api/example_refactored.py +400 -0
- jettask/webui/api/namespaces.py +390 -45
- jettask/webui/api/overview.py +300 -54
- jettask/webui/api/queues.py +971 -267
- jettask/webui/api/scheduled.py +1249 -56
- jettask/webui/api/settings.py +129 -7
- jettask/webui/api/workers.py +442 -0
- jettask/webui/app.py +46 -2329
- jettask/webui/middleware/__init__.py +6 -0
- jettask/webui/middleware/namespace_middleware.py +135 -0
- jettask/webui/services/__init__.py +146 -0
- jettask/webui/services/heartbeat_service.py +251 -0
- jettask/webui/services/overview_service.py +60 -51
- jettask/webui/services/queue_monitor_service.py +426 -0
- jettask/webui/services/redis_monitor_service.py +87 -0
- jettask/webui/services/settings_service.py +174 -111
- jettask/webui/services/task_monitor_service.py +222 -0
- jettask/webui/services/timeline_pg_service.py +452 -0
- jettask/webui/services/timeline_service.py +189 -0
- jettask/webui/services/worker_monitor_service.py +467 -0
- jettask/webui/utils/__init__.py +11 -0
- jettask/webui/utils/time_utils.py +122 -0
- jettask/worker/lifecycle.py +8 -2
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/METADATA +1 -1
- jettask-0.2.24.dist-info/RECORD +142 -0
- jettask/executor/executor.py +0 -338
- jettask/persistence/backlog_monitor.py +0 -567
- jettask/persistence/base.py +0 -2334
- jettask/persistence/db_manager.py +0 -516
- jettask/persistence/maintenance.py +0 -81
- jettask/persistence/message_consumer.py +0 -259
- jettask/persistence/models.py +0 -49
- jettask/persistence/offline_recovery.py +0 -196
- jettask/persistence/queue_discovery.py +0 -215
- jettask/persistence/task_persistence.py +0 -218
- jettask/persistence/task_updater.py +0 -583
- jettask/scheduler/add_execution_count.sql +0 -11
- jettask/scheduler/add_priority_field.sql +0 -26
- jettask/scheduler/add_scheduler_id.sql +0 -25
- jettask/scheduler/add_scheduler_id_index.sql +0 -10
- jettask/scheduler/make_scheduler_id_required.sql +0 -28
- jettask/scheduler/migrate_interval_seconds.sql +0 -9
- jettask/scheduler/performance_optimization.sql +0 -45
- jettask/scheduler/run_scheduler.py +0 -186
- jettask/scheduler/schema.sql +0 -84
- jettask/task/task_executor.py +0 -318
- jettask/webui/api/analytics.py +0 -323
- jettask/webui/config.py +0 -90
- jettask/webui/models/__init__.py +0 -3
- jettask/webui/models/namespace.py +0 -63
- jettask/webui/namespace_manager/__init__.py +0 -10
- jettask/webui/namespace_manager/multi.py +0 -593
- jettask/webui/namespace_manager/unified.py +0 -193
- jettask/webui/run.py +0 -46
- jettask-0.2.23.dist-info/RECORD +0 -145
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/WHEEL +0 -0
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/entry_points.txt +0 -0
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/licenses/LICENSE +0 -0
- {jettask-0.2.23.dist-info → jettask-0.2.24.dist-info}/top_level.txt +0 -0
jettask/webui/api/overview.py
CHANGED
@@ -2,12 +2,18 @@
|
|
2
2
|
概览模块 - 系统总览、健康检查和仪表板统计
|
3
3
|
提供轻量级的路由入口,业务逻辑在 OverviewService 中实现
|
4
4
|
"""
|
5
|
-
from fastapi import APIRouter, HTTPException, Query
|
6
|
-
from typing import Optional
|
5
|
+
from fastapi import APIRouter, HTTPException, Query, Path
|
6
|
+
from typing import Optional, Dict, Any
|
7
7
|
import logging
|
8
8
|
import traceback
|
9
9
|
|
10
|
-
from jettask.schemas import
|
10
|
+
from jettask.schemas import (
|
11
|
+
TimeRangeQuery,
|
12
|
+
SystemStatsResponse,
|
13
|
+
DashboardStatsResponse,
|
14
|
+
TopQueuesResponse,
|
15
|
+
DataResponse
|
16
|
+
)
|
11
17
|
from jettask.webui.services.overview_service import OverviewService
|
12
18
|
|
13
19
|
logger = logging.getLogger(__name__)
|
@@ -18,27 +24,89 @@ router = APIRouter(prefix="/overview", tags=["overview"])
|
|
18
24
|
|
19
25
|
# ============ 健康检查和根路径 ============
|
20
26
|
|
21
|
-
@router.get(
|
22
|
-
|
23
|
-
"
|
24
|
-
|
27
|
+
@router.get(
|
28
|
+
"/",
|
29
|
+
summary="API 根路径",
|
30
|
+
description="获取 API 基本信息和健康状态",
|
31
|
+
response_model=DataResponse,
|
32
|
+
responses={
|
33
|
+
200: {
|
34
|
+
"description": "成功返回 API 信息",
|
35
|
+
"content": {
|
36
|
+
"application/json": {
|
37
|
+
"example": {
|
38
|
+
"success": True,
|
39
|
+
"data": {
|
40
|
+
"service": "JetTask WebUI API",
|
41
|
+
"version": "v1",
|
42
|
+
"status": "running"
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
)
|
50
|
+
async def root() -> Dict[str, Any]:
|
51
|
+
"""
|
52
|
+
## API 根路径
|
25
53
|
|
54
|
+
返回 API 的基本信息,包括服务名称、版本和运行状态。
|
26
55
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
56
|
+
**用途**:
|
57
|
+
- 健康检查
|
58
|
+
- 验证 API 是否可用
|
59
|
+
- 获取 API 版本信息
|
60
|
+
"""
|
61
|
+
return OverviewService.get_root_info()
|
31
62
|
|
32
63
|
|
33
64
|
# ============ 系统统计 ============
|
34
65
|
|
35
|
-
@router.get(
|
36
|
-
|
66
|
+
@router.get(
|
67
|
+
"/system-stats/{namespace}",
|
68
|
+
summary="获取系统统计信息",
|
69
|
+
description="获取指定命名空间的系统级统计数据,包括队列、任务、Worker 等关键指标",
|
70
|
+
response_model=SystemStatsResponse,
|
71
|
+
responses={
|
72
|
+
200: {
|
73
|
+
"description": "成功返回系统统计数据"
|
74
|
+
},
|
75
|
+
500: {
|
76
|
+
"description": "服务器内部错误",
|
77
|
+
"content": {
|
78
|
+
"application/json": {
|
79
|
+
"example": {
|
80
|
+
"detail": "获取系统统计信息失败: Database connection error"
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
)
|
87
|
+
async def get_system_stats(
|
88
|
+
namespace: str = Path(..., description="命名空间名称,用于隔离不同环境或项目的数据", example="default")
|
89
|
+
) -> Dict[str, Any]:
|
37
90
|
"""
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
91
|
+
## 获取系统统计信息
|
92
|
+
|
93
|
+
返回指定命名空间的关键系统指标,用于系统概览页面展示。
|
94
|
+
|
95
|
+
**统计指标包括**:
|
96
|
+
- 队列总数
|
97
|
+
- 任务总数
|
98
|
+
- 活跃 Worker 数量
|
99
|
+
- 各状态任务数量(待处理、处理中、已完成、失败)
|
100
|
+
|
101
|
+
**使用场景**:
|
102
|
+
- 系统概览页面
|
103
|
+
- 监控大屏展示
|
104
|
+
- 系统健康度检查
|
105
|
+
|
106
|
+
**示例请求**:
|
107
|
+
```bash
|
108
|
+
curl -X GET "http://localhost:8001/api/v1/overview/system-stats/default"
|
109
|
+
```
|
42
110
|
"""
|
43
111
|
try:
|
44
112
|
return await OverviewService.get_system_stats(namespace)
|
@@ -50,19 +118,68 @@ async def get_system_stats(namespace: str):
|
|
50
118
|
|
51
119
|
# ============ 仪表板统计 ============
|
52
120
|
|
53
|
-
@router.get(
|
121
|
+
@router.get(
|
122
|
+
"/dashboard-stats/{namespace}",
|
123
|
+
summary="获取仪表板统计数据",
|
124
|
+
description="获取仪表板展示所需的关键业务指标,支持按时间范围和队列过滤",
|
125
|
+
response_model=DashboardStatsResponse,
|
126
|
+
responses={
|
127
|
+
200: {
|
128
|
+
"description": "成功返回仪表板统计数据"
|
129
|
+
},
|
130
|
+
500: {
|
131
|
+
"description": "服务器内部错误"
|
132
|
+
}
|
133
|
+
}
|
134
|
+
)
|
54
135
|
async def get_dashboard_stats(
|
55
|
-
namespace: str,
|
56
|
-
time_range: str =
|
57
|
-
|
58
|
-
|
136
|
+
namespace: str = Path(..., description="命名空间名称", example="default"),
|
137
|
+
time_range: str = Query(
|
138
|
+
default="24h",
|
139
|
+
description="时间范围,支持: 15m, 1h, 6h, 24h, 7d, 30d",
|
140
|
+
example="24h",
|
141
|
+
regex="^(15m|1h|6h|24h|7d|30d)$"
|
142
|
+
),
|
143
|
+
queues: Optional[str] = Query(
|
144
|
+
None,
|
145
|
+
description="逗号分隔的队列名称列表,为空则统计所有队列",
|
146
|
+
example="email_queue,sms_queue"
|
147
|
+
)
|
148
|
+
) -> Dict[str, Any]:
|
59
149
|
"""
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
150
|
+
## 获取仪表板统计数据
|
151
|
+
|
152
|
+
提供仪表板展示所需的核心业务指标,包括任务处理情况、成功率、吞吐量等。
|
153
|
+
|
154
|
+
**统计指标包括**:
|
155
|
+
- 任务总数
|
156
|
+
- 成功任务数
|
157
|
+
- 失败任务数
|
158
|
+
- 成功率 (%)
|
159
|
+
- 吞吐量 (任务/秒)
|
160
|
+
- 平均处理时间 (秒)
|
161
|
+
|
162
|
+
**时间范围说明**:
|
163
|
+
- `15m`: 最近 15 分钟
|
164
|
+
- `1h`: 最近 1 小时
|
165
|
+
- `6h`: 最近 6 小时
|
166
|
+
- `24h`: 最近 24 小时 (默认)
|
167
|
+
- `7d`: 最近 7 天
|
168
|
+
- `30d`: 最近 30 天
|
169
|
+
|
170
|
+
**使用场景**:
|
171
|
+
- 仪表板首页
|
172
|
+
- 业务报表
|
173
|
+
- 性能监控
|
174
|
+
|
175
|
+
**示例请求**:
|
176
|
+
```bash
|
177
|
+
# 获取默认命名空间最近24小时的统计
|
178
|
+
curl -X GET "http://localhost:8001/api/v1/overview/dashboard-stats/default"
|
179
|
+
|
180
|
+
# 获取指定队列最近1小时的统计
|
181
|
+
curl -X GET "http://localhost:8001/api/v1/overview/dashboard-stats/default?time_range=1h&queues=email_queue,sms_queue"
|
182
|
+
```
|
66
183
|
"""
|
67
184
|
try:
|
68
185
|
return await OverviewService.get_dashboard_stats(namespace, time_range, queues)
|
@@ -74,23 +191,85 @@ async def get_dashboard_stats(
|
|
74
191
|
|
75
192
|
# ============ 队列排行榜 ============
|
76
193
|
|
77
|
-
@router.get(
|
194
|
+
@router.get(
|
195
|
+
"/top-queues/{namespace}",
|
196
|
+
summary="获取队列排行榜",
|
197
|
+
description="根据指定指标获取队列排行榜,支持积压数和错误率两种排序方式",
|
198
|
+
response_model=TopQueuesResponse,
|
199
|
+
responses={
|
200
|
+
200: {
|
201
|
+
"description": "成功返回队列排行榜"
|
202
|
+
},
|
203
|
+
400: {
|
204
|
+
"description": "请求参数错误",
|
205
|
+
"content": {
|
206
|
+
"application/json": {
|
207
|
+
"example": {
|
208
|
+
"detail": "无效的指标类型: invalid_metric,仅支持 backlog 或 error"
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
},
|
213
|
+
500: {
|
214
|
+
"description": "服务器内部错误"
|
215
|
+
}
|
216
|
+
}
|
217
|
+
)
|
78
218
|
async def get_top_queues(
|
79
|
-
namespace: str,
|
80
|
-
metric: str = Query(
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
)
|
219
|
+
namespace: str = Path(..., description="命名空间名称", example="default"),
|
220
|
+
metric: str = Query(
|
221
|
+
default="backlog",
|
222
|
+
description="排序指标类型",
|
223
|
+
example="backlog",
|
224
|
+
regex="^(backlog|error)$"
|
225
|
+
),
|
226
|
+
limit: int = Query(
|
227
|
+
default=10,
|
228
|
+
ge=1,
|
229
|
+
le=100,
|
230
|
+
description="返回的队列数量限制",
|
231
|
+
example=10
|
232
|
+
),
|
233
|
+
time_range: str = Query(
|
234
|
+
default="24h",
|
235
|
+
description="统计时间范围",
|
236
|
+
example="24h",
|
237
|
+
regex="^(15m|1h|6h|24h|7d|30d)$"
|
238
|
+
),
|
239
|
+
queues: Optional[str] = Query(
|
240
|
+
None,
|
241
|
+
description="逗号分隔的队列名称列表,为空则统计所有队列",
|
242
|
+
example="email_queue,sms_queue"
|
243
|
+
)
|
244
|
+
) -> Dict[str, Any]:
|
85
245
|
"""
|
86
|
-
获取队列排行榜
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
246
|
+
## 获取队列排行榜
|
247
|
+
|
248
|
+
根据指定指标对队列进行排序,帮助快速识别需要关注的队列。
|
249
|
+
|
250
|
+
**支持的指标类型**:
|
251
|
+
- `backlog`: 按积压任务数排序(降序)
|
252
|
+
- `error`: 按错误率排序(降序)
|
253
|
+
|
254
|
+
**排行数据包括**:
|
255
|
+
- 队列名称
|
256
|
+
- 指标值
|
257
|
+
- 排名
|
258
|
+
|
259
|
+
**使用场景**:
|
260
|
+
- 识别积压严重的队列
|
261
|
+
- 发现错误率高的队列
|
262
|
+
- 优化资源分配
|
263
|
+
- 容量规划
|
264
|
+
|
265
|
+
**示例请求**:
|
266
|
+
```bash
|
267
|
+
# 获取积压最多的前10个队列
|
268
|
+
curl -X GET "http://localhost:8001/api/v1/overview/top-queues/default?metric=backlog&limit=10"
|
269
|
+
|
270
|
+
# 获取错误率最高的前5个队列
|
271
|
+
curl -X GET "http://localhost:8001/api/v1/overview/top-queues/default?metric=error&limit=5"
|
272
|
+
```
|
94
273
|
"""
|
95
274
|
try:
|
96
275
|
return await OverviewService.get_top_queues(namespace, metric, limit, time_range, queues)
|
@@ -105,18 +284,85 @@ async def get_top_queues(
|
|
105
284
|
|
106
285
|
# ============ 概览统计数据 ============
|
107
286
|
|
108
|
-
@router.post(
|
109
|
-
|
287
|
+
@router.post(
|
288
|
+
"/dashboard-overview-stats/{namespace}",
|
289
|
+
summary="获取概览页面统计数据",
|
290
|
+
description="获取概览页面所需的时间序列统计数据,包括任务处理趋势、并发数量、处理时间等",
|
291
|
+
response_model=Dict[str, Any],
|
292
|
+
responses={
|
293
|
+
200: {
|
294
|
+
"description": "成功返回时间序列统计数据",
|
295
|
+
"content": {
|
296
|
+
"application/json": {
|
297
|
+
"example": {
|
298
|
+
"task_trend": [
|
299
|
+
{"timestamp": "2025-10-18T10:00:00Z", "completed": 120, "failed": 5},
|
300
|
+
{"timestamp": "2025-10-18T10:05:00Z", "completed": 135, "failed": 3}
|
301
|
+
],
|
302
|
+
"concurrency": [
|
303
|
+
{"timestamp": "2025-10-18T10:00:00Z", "value": 15},
|
304
|
+
{"timestamp": "2025-10-18T10:05:00Z", "value": 18}
|
305
|
+
],
|
306
|
+
"processing_time": [
|
307
|
+
{"timestamp": "2025-10-18T10:00:00Z", "avg": 2.3, "p50": 2.1, "p95": 4.5},
|
308
|
+
{"timestamp": "2025-10-18T10:05:00Z", "avg": 2.1, "p50": 1.9, "p95": 4.2}
|
309
|
+
],
|
310
|
+
"creation_latency": [
|
311
|
+
{"timestamp": "2025-10-18T10:00:00Z", "avg": 0.5, "p95": 1.2}
|
312
|
+
],
|
313
|
+
"granularity": "5m"
|
314
|
+
}
|
315
|
+
}
|
316
|
+
}
|
317
|
+
},
|
318
|
+
500: {
|
319
|
+
"description": "服务器内部错误,返回空数据"
|
320
|
+
}
|
321
|
+
}
|
322
|
+
)
|
323
|
+
async def get_dashboard_overview_stats(
|
324
|
+
namespace: str = Path(..., description="命名空间名称", example="default"),
|
325
|
+
query: TimeRangeQuery = ...
|
326
|
+
) -> Dict[str, Any]:
|
110
327
|
"""
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
328
|
+
## 获取概览页面统计数据
|
329
|
+
|
330
|
+
返回概览页面所需的时间序列统计数据,用于绘制趋势图表。
|
331
|
+
|
332
|
+
**请求体参数**:
|
333
|
+
```json
|
334
|
+
{
|
335
|
+
"time_range": "1h", // 可选: 时间范围(如 15m, 1h, 6h, 24h)
|
336
|
+
"start_time": "2025-10-18T09:00:00Z", // 可选: 开始时间(ISO格式)
|
337
|
+
"end_time": "2025-10-18T10:00:00Z", // 可选: 结束时间(ISO格式)
|
338
|
+
"queue_name": "email_queue" // 可选: 队列名称
|
339
|
+
}
|
340
|
+
```
|
341
|
+
|
342
|
+
**返回的时间序列数据**:
|
343
|
+
- `task_trend`: 任务处理趋势(完成数、失败数)
|
344
|
+
- `concurrency`: 任务并发数量
|
345
|
+
- `processing_time`: 任务处理时间(平均值、P50、P95)
|
346
|
+
- `creation_latency`: 任务创建延迟(平均值、P95)
|
347
|
+
- `granularity`: 数据粒度(如 minute、5m、hour)
|
348
|
+
|
349
|
+
**数据粒度说明**:
|
350
|
+
- 时间范围 <= 1h: 粒度为 1分钟
|
351
|
+
- 时间范围 <= 6h: 粒度为 5分钟
|
352
|
+
- 时间范围 <= 24h: 粒度为 15分钟
|
353
|
+
- 时间范围 > 24h: 粒度为 1小时
|
354
|
+
|
355
|
+
**使用场景**:
|
356
|
+
- 概览页面趋势图
|
357
|
+
- 性能监控图表
|
358
|
+
- 实时数据看板
|
359
|
+
|
360
|
+
**示例请求**:
|
361
|
+
```bash
|
362
|
+
curl -X POST "http://localhost:8001/api/v1/overview/dashboard-overview-stats/default" \\
|
363
|
+
-H "Content-Type: application/json" \\
|
364
|
+
-d '{"time_range": "1h", "queue_name": "email_queue"}'
|
365
|
+
```
|
120
366
|
"""
|
121
367
|
try:
|
122
368
|
return await OverviewService.get_dashboard_overview_stats(namespace, query)
|