jettask 0.2.15__py3-none-any.whl → 0.2.17__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.
Files changed (149) hide show
  1. jettask/__init__.py +14 -35
  2. jettask/{webui/__main__.py → __main__.py} +4 -4
  3. jettask/api/__init__.py +103 -0
  4. jettask/api/v1/__init__.py +29 -0
  5. jettask/api/v1/alerts.py +226 -0
  6. jettask/api/v1/analytics.py +323 -0
  7. jettask/api/v1/namespaces.py +134 -0
  8. jettask/api/v1/overview.py +136 -0
  9. jettask/api/v1/queues.py +530 -0
  10. jettask/api/v1/scheduled.py +420 -0
  11. jettask/api/v1/settings.py +44 -0
  12. jettask/{webui/api.py → api.py} +4 -46
  13. jettask/{webui/backend → backend}/main.py +21 -109
  14. jettask/{webui/backend → backend}/main_unified.py +1 -1
  15. jettask/{webui/backend → backend}/namespace_api_old.py +3 -30
  16. jettask/{webui/backend → backend}/namespace_data_access.py +2 -1
  17. jettask/{webui/backend → backend}/unified_api_router.py +14 -74
  18. jettask/{core/cli.py → cli.py} +106 -26
  19. jettask/config/nacos_config.py +386 -0
  20. jettask/core/app.py +8 -100
  21. jettask/core/db_manager.py +515 -0
  22. jettask/core/event_pool.py +5 -2
  23. jettask/core/unified_manager_base.py +59 -14
  24. jettask/{webui/db_init.py → db_init.py} +1 -1
  25. jettask/executors/asyncio.py +2 -2
  26. jettask/{webui/integrated_gradio_app.py → integrated_gradio_app.py} +1 -1
  27. jettask/{webui/multi_namespace_consumer.py → multi_namespace_consumer.py} +5 -2
  28. jettask/{webui/pg_consumer.py → pg_consumer.py} +137 -69
  29. jettask/{webui/run.py → run.py} +1 -1
  30. jettask/{webui/run_webui.py → run_webui.py} +4 -4
  31. jettask/scheduler/manager.py +6 -0
  32. jettask/scheduler/multi_namespace_scheduler.py +2 -2
  33. jettask/scheduler/unified_manager.py +5 -5
  34. jettask/scheduler/unified_scheduler_manager.py +20 -12
  35. jettask/schemas/__init__.py +166 -0
  36. jettask/schemas/alert.py +99 -0
  37. jettask/schemas/backlog.py +122 -0
  38. jettask/schemas/common.py +139 -0
  39. jettask/schemas/monitoring.py +181 -0
  40. jettask/schemas/namespace.py +168 -0
  41. jettask/schemas/queue.py +83 -0
  42. jettask/schemas/scheduled_task.py +128 -0
  43. jettask/schemas/task.py +70 -0
  44. jettask/services/__init__.py +24 -0
  45. jettask/services/alert_service.py +454 -0
  46. jettask/services/analytics_service.py +46 -0
  47. jettask/services/overview_service.py +978 -0
  48. jettask/services/queue_service.py +711 -0
  49. jettask/services/redis_monitor_service.py +151 -0
  50. jettask/services/scheduled_task_service.py +207 -0
  51. jettask/services/settings_service.py +758 -0
  52. jettask/services/task_service.py +157 -0
  53. jettask/{webui/task_center.py → task_center.py} +30 -8
  54. jettask/{webui/task_center_client.py → task_center_client.py} +1 -1
  55. jettask/{webui/config.py → webui_config.py} +6 -1
  56. jettask/webui_exceptions.py +67 -0
  57. jettask/webui_sql/verify_database.sql +72 -0
  58. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/METADATA +2 -1
  59. jettask-0.2.17.dist-info/RECORD +150 -0
  60. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/entry_points.txt +1 -1
  61. jettask/webui/backend/data_api.py +0 -3294
  62. jettask/webui/backend/namespace_api.py +0 -295
  63. jettask/webui/backend/queue_backlog_api.py +0 -727
  64. jettask/webui/backend/redis_monitor_api.py +0 -476
  65. jettask/webui/frontend/index.html +0 -13
  66. jettask/webui/frontend/package.json +0 -30
  67. jettask/webui/frontend/src/App.css +0 -109
  68. jettask/webui/frontend/src/App.jsx +0 -66
  69. jettask/webui/frontend/src/components/NamespaceSelector.jsx +0 -166
  70. jettask/webui/frontend/src/components/QueueBacklogChart.jsx +0 -298
  71. jettask/webui/frontend/src/components/QueueBacklogTrend.jsx +0 -638
  72. jettask/webui/frontend/src/components/QueueDetailsTable.css +0 -65
  73. jettask/webui/frontend/src/components/QueueDetailsTable.jsx +0 -487
  74. jettask/webui/frontend/src/components/QueueDetailsTableV2.jsx +0 -465
  75. jettask/webui/frontend/src/components/ScheduledTaskFilter.jsx +0 -423
  76. jettask/webui/frontend/src/components/TaskFilter.jsx +0 -425
  77. jettask/webui/frontend/src/components/TimeRangeSelector.css +0 -21
  78. jettask/webui/frontend/src/components/TimeRangeSelector.jsx +0 -160
  79. jettask/webui/frontend/src/components/charts/QueueChart.jsx +0 -111
  80. jettask/webui/frontend/src/components/charts/QueueTrendChart.jsx +0 -115
  81. jettask/webui/frontend/src/components/charts/WorkerChart.jsx +0 -40
  82. jettask/webui/frontend/src/components/common/StatsCard.jsx +0 -18
  83. jettask/webui/frontend/src/components/layout/AppLayout.css +0 -95
  84. jettask/webui/frontend/src/components/layout/AppLayout.jsx +0 -49
  85. jettask/webui/frontend/src/components/layout/Header.css +0 -106
  86. jettask/webui/frontend/src/components/layout/Header.jsx +0 -106
  87. jettask/webui/frontend/src/components/layout/SideMenu.css +0 -137
  88. jettask/webui/frontend/src/components/layout/SideMenu.jsx +0 -209
  89. jettask/webui/frontend/src/components/layout/TabsNav.css +0 -244
  90. jettask/webui/frontend/src/components/layout/TabsNav.jsx +0 -206
  91. jettask/webui/frontend/src/components/layout/UserInfo.css +0 -197
  92. jettask/webui/frontend/src/components/layout/UserInfo.jsx +0 -197
  93. jettask/webui/frontend/src/contexts/LoadingContext.jsx +0 -27
  94. jettask/webui/frontend/src/contexts/NamespaceContext.jsx +0 -72
  95. jettask/webui/frontend/src/contexts/TabsContext.backup.jsx +0 -245
  96. jettask/webui/frontend/src/index.css +0 -114
  97. jettask/webui/frontend/src/main.jsx +0 -22
  98. jettask/webui/frontend/src/pages/Alerts.jsx +0 -684
  99. jettask/webui/frontend/src/pages/Dashboard/index.css +0 -35
  100. jettask/webui/frontend/src/pages/Dashboard/index.jsx +0 -281
  101. jettask/webui/frontend/src/pages/Dashboard.jsx +0 -1330
  102. jettask/webui/frontend/src/pages/QueueDetail.jsx +0 -1117
  103. jettask/webui/frontend/src/pages/QueueMonitor.jsx +0 -527
  104. jettask/webui/frontend/src/pages/Queues.jsx +0 -12
  105. jettask/webui/frontend/src/pages/ScheduledTasks.jsx +0 -810
  106. jettask/webui/frontend/src/pages/Settings.jsx +0 -801
  107. jettask/webui/frontend/src/pages/Workers.jsx +0 -12
  108. jettask/webui/frontend/src/services/api.js +0 -159
  109. jettask/webui/frontend/src/services/queueTrend.js +0 -166
  110. jettask/webui/frontend/src/utils/suppressWarnings.js +0 -22
  111. jettask/webui/frontend/src/utils/userPreferences.js +0 -154
  112. jettask/webui/frontend/vite.config.js +0 -26
  113. jettask/webui/sql/init_database.sql +0 -640
  114. jettask-0.2.15.dist-info/RECORD +0 -172
  115. /jettask/{webui/backend → backend}/__init__.py +0 -0
  116. /jettask/{webui/backend → backend}/api/__init__.py +0 -0
  117. /jettask/{webui/backend → backend}/api/v1/__init__.py +0 -0
  118. /jettask/{webui/backend → backend}/api/v1/monitoring.py +0 -0
  119. /jettask/{webui/backend → backend}/api/v1/namespaces.py +0 -0
  120. /jettask/{webui/backend → backend}/api/v1/queues.py +0 -0
  121. /jettask/{webui/backend → backend}/api/v1/tasks.py +0 -0
  122. /jettask/{webui/backend → backend}/config.py +0 -0
  123. /jettask/{webui/backend → backend}/core/__init__.py +0 -0
  124. /jettask/{webui/backend → backend}/core/cache.py +0 -0
  125. /jettask/{webui/backend → backend}/core/database.py +0 -0
  126. /jettask/{webui/backend → backend}/core/exceptions.py +0 -0
  127. /jettask/{webui/backend → backend}/data_access.py +0 -0
  128. /jettask/{webui/backend → backend}/dependencies.py +0 -0
  129. /jettask/{webui/backend → backend}/init_meta_db.py +0 -0
  130. /jettask/{webui/backend → backend}/main_v2.py +0 -0
  131. /jettask/{webui/backend → backend}/models/__init__.py +0 -0
  132. /jettask/{webui/backend → backend}/models/requests.py +0 -0
  133. /jettask/{webui/backend → backend}/models/responses.py +0 -0
  134. /jettask/{webui/backend → backend}/queue_stats_v2.py +0 -0
  135. /jettask/{webui/backend → backend}/services/__init__.py +0 -0
  136. /jettask/{webui/backend → backend}/start.py +0 -0
  137. /jettask/{webui/cleanup_deprecated_tables.sql → cleanup_deprecated_tables.sql} +0 -0
  138. /jettask/{webui/gradio_app.py → gradio_app.py} +0 -0
  139. /jettask/{webui/__init__.py → main.py} +0 -0
  140. /jettask/{webui/models.py → models.py} +0 -0
  141. /jettask/{webui/run_monitor.py → run_monitor.py} +0 -0
  142. /jettask/{webui/schema.sql → schema.sql} +0 -0
  143. /jettask/{webui/unified_consumer_manager.py → unified_consumer_manager.py} +0 -0
  144. /jettask/{webui/models → webui_models}/__init__.py +0 -0
  145. /jettask/{webui/models → webui_models}/namespace.py +0 -0
  146. /jettask/{webui/sql → webui_sql}/batch_upsert_functions.sql +0 -0
  147. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/WHEEL +0 -0
  148. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/licenses/LICENSE +0 -0
  149. {jettask-0.2.15.dist-info → jettask-0.2.17.dist-info}/top_level.txt +0 -0
jettask/__init__.py CHANGED
@@ -1,40 +1,19 @@
1
- from .core.app import Jettask
2
- from .core.task import Task, Request, ExecuteResponse
3
- from .core.context import TaskContext
4
- from .router import TaskRouter
5
- from .exceptions import JetTaskException, TaskTimeoutError, TaskExecutionError, TaskNotFoundError, RetryableError
6
- from .utils.error_handler import clean_task_errors, handle_task_error
7
- from .utils.task_logger import (
8
- configure_task_logging,
9
- get_task_logger,
10
- TaskContextManager,
11
- set_task_context,
12
- clear_task_context,
13
- LogContext
14
- )
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ JetTask - High Performance Distributed Task Queue System
4
+ """
15
5
 
16
- # 自动安装简化的异常显示(用户可通过环境变量 JETTASK_FULL_TRACEBACK=1 禁用)
17
- from .utils import exception_hook # 这会自动安装 excepthook
6
+ # Core class imports
7
+ from jettask.core.app import Jettask
8
+ from jettask.core.message import TaskMessage
9
+ from jettask.task_center import TaskCenter
18
10
 
11
+ # Version info
19
12
  __version__ = "0.1.0"
13
+
14
+ # Public API exports
20
15
  __all__ = [
21
- "Jettask",
22
- "Task",
23
- "TaskContext",
24
- "TaskRouter",
25
- "Request",
26
- "ExecuteResponse",
27
- "JetTaskException",
28
- "TaskTimeoutError",
29
- "TaskExecutionError",
30
- "TaskNotFoundError",
31
- "RetryableError",
32
- "clean_task_errors",
33
- "handle_task_error",
34
- "configure_task_logging",
35
- "get_task_logger",
36
- "TaskContextManager",
37
- "set_task_context",
38
- "clear_task_context",
39
- "LogContext"
16
+ "Jettask",
17
+ "TaskMessage",
18
+ "TaskCenter",
40
19
  ]
@@ -9,10 +9,10 @@ import asyncio
9
9
  sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
10
10
 
11
11
  import uvicorn
12
- from jettask.webui.api import app
13
- from jettask.webui.config import PostgreSQLConfig, WebUIConfig, RedisConfig
14
- from jettask.webui.db_init import init_database
15
- from jettask.webui.pg_consumer import PostgreSQLConsumer
12
+ from jettask.api import app
13
+ from jettask.webui_config import PostgreSQLConfig, WebUIConfig, RedisConfig
14
+ from jettask.db_init import init_database
15
+ from jettask.pg_consumer import PostgreSQLConsumer
16
16
 
17
17
  def parse_pg_config(args):
18
18
  """解析PostgreSQL配置"""
@@ -0,0 +1,103 @@
1
+ """
2
+ JetTask API 应用初始化
3
+ """
4
+ from fastapi import FastAPI
5
+ from fastapi.middleware.cors import CORSMiddleware
6
+ from contextlib import asynccontextmanager
7
+ import logging
8
+
9
+ # 设置日志
10
+ logging.basicConfig(level=logging.INFO)
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ def create_app() -> FastAPI:
15
+ """创建并配置 FastAPI 应用"""
16
+
17
+ @asynccontextmanager
18
+ async def lifespan(app: FastAPI):
19
+ """应用生命周期管理"""
20
+ # 启动时初始化
21
+ try:
22
+ import os
23
+ # 检查是否使用Nacos配置
24
+ use_nacos = os.getenv('USE_NACOS', 'false').lower() == 'true'
25
+
26
+ # 初始化数据库管理器
27
+ from jettask.core.db_manager import init_db_manager
28
+ await init_db_manager(use_nacos=use_nacos)
29
+
30
+ # 延迟导入,避免循环依赖
31
+ from jettask.backend.data_access import JetTaskDataAccess
32
+ from jettask.backend.namespace_data_access import get_namespace_data_access
33
+ from jettask.backend.config import task_center_config
34
+
35
+ # 创建数据访问实例
36
+ data_access = JetTaskDataAccess()
37
+ namespace_data_access = get_namespace_data_access()
38
+
39
+ # 存储在app.state中供路由使用
40
+ app.state.data_access = data_access
41
+ app.state.namespace_data_access = namespace_data_access
42
+
43
+ # 初始化JetTask数据访问
44
+ await data_access.initialize()
45
+
46
+ # 记录任务中心配置
47
+ logger.info("=" * 60)
48
+ logger.info("任务中心配置:")
49
+ logger.info(f" 配置模式: {'Nacos' if use_nacos else '环境变量'}")
50
+ logger.info(f" 元数据库: {task_center_config.meta_db_host}:{task_center_config.meta_db_port}/{task_center_config.meta_db_name}")
51
+ logger.info(f" API服务: {task_center_config.api_host}:{task_center_config.api_port}")
52
+ logger.info(f" 基础URL: {task_center_config.base_url}")
53
+ logger.info("=" * 60)
54
+
55
+ logger.info("JetTask Monitor API 启动成功")
56
+ except Exception as e:
57
+ logger.error(f"启动失败: {e}")
58
+ import traceback
59
+ traceback.print_exc()
60
+ raise
61
+
62
+ yield
63
+
64
+ # 关闭时清理资源
65
+ try:
66
+ await app.state.data_access.close()
67
+
68
+ # 关闭数据库管理器
69
+ from jettask.core.db_manager import close_db_manager
70
+ await close_db_manager()
71
+
72
+ logger.info("JetTask Monitor API 关闭完成")
73
+ except Exception as e:
74
+ logger.error(f"关闭时出错: {e}")
75
+ import traceback
76
+ traceback.print_exc()
77
+
78
+ # 创建 FastAPI 应用
79
+ app = FastAPI(
80
+ title="JetTask Monitor API",
81
+ version="1.0.0",
82
+ lifespan=lifespan
83
+ )
84
+
85
+ # 配置CORS
86
+ app.add_middleware(
87
+ CORSMiddleware,
88
+ allow_origins=["*"], # 生产环境应该配置具体的前端地址
89
+ allow_credentials=True,
90
+ allow_methods=["*"],
91
+ allow_headers=["*"],
92
+ )
93
+
94
+ # 注册路由
95
+ from jettask.api.v1 import api_router
96
+
97
+ app.include_router(api_router)
98
+
99
+ return app
100
+
101
+
102
+ # 创建默认应用实例
103
+ app = create_app()
@@ -0,0 +1,29 @@
1
+ """
2
+ API v1 路由模块集合
3
+ """
4
+ from fastapi import APIRouter
5
+
6
+ # 导入7个主要模块的路由
7
+ from .overview import router as overview_router # 概览
8
+ from .namespaces import router as namespaces_router # 命名空间
9
+ from .queues import router as queues_router # 队列
10
+ from .scheduled import router as scheduled_router # 定时任务
11
+ from .alerts import router as alerts_router # 告警
12
+ from .analytics import router as analytics_router # 分析
13
+ from .settings import router as settings_router # 设置
14
+
15
+ # 创建 v1 总路由,添加统一的 /api/v1 前缀
16
+ api_router = APIRouter(prefix="/api/v1")
17
+
18
+ # 按功能模块组织路由(namespaces和settings现在是平级的)
19
+ api_router.include_router(overview_router) # 系统概览、健康检查
20
+ api_router.include_router(namespaces_router) # 命名空间管理(独立路由)
21
+ api_router.include_router(queues_router) # 队列管理、任务处理
22
+ api_router.include_router(scheduled_router) # 定时任务管理
23
+ api_router.include_router(alerts_router) # 告警规则管理
24
+ api_router.include_router(analytics_router) # 数据分析查询
25
+ api_router.include_router(settings_router) # 系统配置
26
+
27
+ __all__ = ['api_router']
28
+
29
+
@@ -0,0 +1,226 @@
1
+ """
2
+ 告警管理路由
3
+ 提供轻量级的路由入口,业务逻辑在 AlertService 中实现
4
+ """
5
+ from fastapi import APIRouter, HTTPException, Query
6
+ from typing import Optional
7
+ import logging
8
+
9
+ from jettask.schemas import AlertRuleRequest
10
+ from jettask.services.alert_service import AlertService
11
+
12
+ router = APIRouter(prefix="/alerts", tags=["alerts"])
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ @router.get("/rules")
17
+ async def get_alert_rules(
18
+ page: int = Query(1, ge=1),
19
+ page_size: int = Query(20, ge=1, le=100),
20
+ is_active: Optional[bool] = None
21
+ ):
22
+ """
23
+ 获取告警规则列表
24
+
25
+ Args:
26
+ page: 页码(从1开始)
27
+ page_size: 每页数量
28
+ is_active: 是否只返回激活的规则
29
+ """
30
+ try:
31
+ return AlertService.get_alert_rules(page, page_size, is_active)
32
+ except Exception as e:
33
+ logger.error(f"获取告警规则列表失败: {e}")
34
+ raise HTTPException(status_code=500, detail=str(e))
35
+
36
+
37
+ @router.post("/rules", status_code=201)
38
+ async def create_alert_rule(request: AlertRuleRequest):
39
+ """
40
+ 创建告警规则
41
+
42
+ Args:
43
+ request: 告警规则请求数据
44
+ """
45
+ try:
46
+ return AlertService.create_alert_rule(request)
47
+ except ValueError as e:
48
+ raise HTTPException(status_code=400, detail=str(e))
49
+ except Exception as e:
50
+ logger.error(f"创建告警规则失败: {e}")
51
+ raise HTTPException(status_code=500, detail=str(e))
52
+
53
+
54
+ @router.put("/rules/{rule_id}")
55
+ async def update_alert_rule(rule_id: str, request: AlertRuleRequest):
56
+ """
57
+ 更新告警规则
58
+
59
+ Args:
60
+ rule_id: 规则ID
61
+ request: 告警规则请求数据
62
+ """
63
+ try:
64
+ return AlertService.update_alert_rule(rule_id, request)
65
+ except ValueError as e:
66
+ raise HTTPException(status_code=404, detail=str(e))
67
+ except Exception as e:
68
+ logger.error(f"更新告警规则失败: {e}")
69
+ raise HTTPException(status_code=500, detail=str(e))
70
+
71
+
72
+ @router.delete("/rules/{rule_id}")
73
+ async def delete_alert_rule(rule_id: str):
74
+ """
75
+ 删除告警规则
76
+
77
+ Args:
78
+ rule_id: 规则ID
79
+ """
80
+ try:
81
+ return AlertService.delete_alert_rule(rule_id)
82
+ except ValueError as e:
83
+ raise HTTPException(status_code=404, detail=str(e))
84
+ except Exception as e:
85
+ logger.error(f"删除告警规则失败: {e}")
86
+ raise HTTPException(status_code=500, detail=str(e))
87
+
88
+
89
+ @router.post("/rules/{rule_id}/toggle")
90
+ async def toggle_alert_rule(rule_id: str):
91
+ """
92
+ 启用/禁用告警规则
93
+
94
+ Args:
95
+ rule_id: 规则ID
96
+ """
97
+ try:
98
+ return AlertService.toggle_alert_rule(rule_id)
99
+ except ValueError as e:
100
+ raise HTTPException(status_code=404, detail=str(e))
101
+ except Exception as e:
102
+ logger.error(f"切换告警规则状态失败: {e}")
103
+ raise HTTPException(status_code=500, detail=str(e))
104
+
105
+
106
+ @router.get("/rules/{rule_id}/history")
107
+ async def get_alert_history(
108
+ rule_id: str,
109
+ page: int = Query(1, ge=1),
110
+ page_size: int = Query(20, ge=1, le=100)
111
+ ):
112
+ """
113
+ 获取告警触发历史
114
+
115
+ Args:
116
+ rule_id: 规则ID
117
+ page: 页码(从1开始)
118
+ page_size: 每页数量
119
+ """
120
+ try:
121
+ return AlertService.get_alert_history(rule_id, page, page_size)
122
+ except ValueError as e:
123
+ raise HTTPException(status_code=404, detail=str(e))
124
+ except Exception as e:
125
+ logger.error(f"获取告警历史失败: {e}")
126
+ raise HTTPException(status_code=500, detail=str(e))
127
+
128
+
129
+ @router.post("/rules/{rule_id}/test")
130
+ async def test_alert_rule(rule_id: str):
131
+ """
132
+ 测试告警规则(发送测试通知)
133
+
134
+ Args:
135
+ rule_id: 规则ID
136
+ """
137
+ try:
138
+ return AlertService.test_alert_rule(rule_id)
139
+ except ValueError as e:
140
+ raise HTTPException(status_code=404, detail=str(e))
141
+ except Exception as e:
142
+ logger.error(f"测试告警规则失败: {e}")
143
+ raise HTTPException(status_code=500, detail=str(e))
144
+
145
+
146
+ # ============ 告警统计接口 ============
147
+
148
+ @router.get("/statistics")
149
+ async def get_alert_statistics(
150
+ namespace: Optional[str] = Query(None, description="命名空间名称")
151
+ ):
152
+ """
153
+ 获取告警统计信息
154
+
155
+ Args:
156
+ namespace: 命名空间名称(可选)
157
+ """
158
+ try:
159
+ return AlertService.get_alert_statistics(namespace)
160
+ except Exception as e:
161
+ logger.error(f"获取告警统计信息失败: {e}")
162
+ raise HTTPException(status_code=500, detail=str(e))
163
+
164
+
165
+ # ============ 活跃告警管理 ============
166
+
167
+ @router.get("/active")
168
+ async def get_active_alerts(
169
+ namespace: Optional[str] = Query(None, description="命名空间名称")
170
+ ):
171
+ """
172
+ 获取当前活跃的告警
173
+
174
+ Args:
175
+ namespace: 命名空间名称(可选)
176
+ """
177
+ try:
178
+ return AlertService.get_active_alerts(namespace)
179
+ except Exception as e:
180
+ logger.error(f"获取活跃告警失败: {e}")
181
+ raise HTTPException(status_code=500, detail=str(e))
182
+
183
+
184
+ @router.post("/active/{alert_id}/acknowledge")
185
+ async def acknowledge_alert(
186
+ alert_id: str,
187
+ user: str = Query("system", description="确认用户")
188
+ ):
189
+ """
190
+ 确认告警
191
+
192
+ Args:
193
+ alert_id: 告警ID
194
+ user: 确认用户
195
+ """
196
+ try:
197
+ return AlertService.acknowledge_alert(alert_id, user)
198
+ except ValueError as e:
199
+ raise HTTPException(status_code=404, detail=str(e))
200
+ except Exception as e:
201
+ logger.error(f"确认告警失败: {e}")
202
+ raise HTTPException(status_code=500, detail=str(e))
203
+
204
+
205
+ @router.post("/active/{alert_id}/resolve")
206
+ async def resolve_alert(
207
+ alert_id: str,
208
+ resolution_note: Optional[str] = Query(None, description="解决说明")
209
+ ):
210
+ """
211
+ 解决告警
212
+
213
+ Args:
214
+ alert_id: 告警ID
215
+ resolution_note: 解决说明(可选)
216
+ """
217
+ try:
218
+ return AlertService.resolve_alert(alert_id, resolution_note)
219
+ except ValueError as e:
220
+ raise HTTPException(status_code=404, detail=str(e))
221
+ except Exception as e:
222
+ logger.error(f"解决告警失败: {e}")
223
+ raise HTTPException(status_code=500, detail=str(e))
224
+
225
+
226
+ __all__ = ['router']