aury-boot 0.0.2__py3-none-any.whl → 0.0.3__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.
- aury/boot/__init__.py +66 -0
- aury/boot/_version.py +2 -2
- aury/boot/application/__init__.py +120 -0
- aury/boot/application/app/__init__.py +39 -0
- aury/boot/application/app/base.py +511 -0
- aury/boot/application/app/components.py +434 -0
- aury/boot/application/app/middlewares.py +101 -0
- aury/boot/application/config/__init__.py +44 -0
- aury/boot/application/config/settings.py +663 -0
- aury/boot/application/constants/__init__.py +19 -0
- aury/boot/application/constants/components.py +50 -0
- aury/boot/application/constants/scheduler.py +28 -0
- aury/boot/application/constants/service.py +29 -0
- aury/boot/application/errors/__init__.py +55 -0
- aury/boot/application/errors/chain.py +80 -0
- aury/boot/application/errors/codes.py +67 -0
- aury/boot/application/errors/exceptions.py +238 -0
- aury/boot/application/errors/handlers.py +320 -0
- aury/boot/application/errors/response.py +120 -0
- aury/boot/application/interfaces/__init__.py +76 -0
- aury/boot/application/interfaces/egress.py +224 -0
- aury/boot/application/interfaces/ingress.py +98 -0
- aury/boot/application/middleware/__init__.py +22 -0
- aury/boot/application/middleware/logging.py +451 -0
- aury/boot/application/migrations/__init__.py +13 -0
- aury/boot/application/migrations/manager.py +685 -0
- aury/boot/application/migrations/setup.py +237 -0
- aury/boot/application/rpc/__init__.py +63 -0
- aury/boot/application/rpc/base.py +108 -0
- aury/boot/application/rpc/client.py +294 -0
- aury/boot/application/rpc/discovery.py +218 -0
- aury/boot/application/scheduler/__init__.py +13 -0
- aury/boot/application/scheduler/runner.py +123 -0
- aury/boot/application/server/__init__.py +296 -0
- aury/boot/commands/__init__.py +30 -0
- aury/boot/commands/add.py +76 -0
- aury/boot/commands/app.py +105 -0
- aury/boot/commands/config.py +177 -0
- aury/boot/commands/docker.py +367 -0
- aury/boot/commands/docs.py +284 -0
- aury/boot/commands/generate.py +1277 -0
- aury/boot/commands/init.py +890 -0
- aury/boot/commands/migrate/__init__.py +37 -0
- aury/boot/commands/migrate/app.py +54 -0
- aury/boot/commands/migrate/commands.py +303 -0
- aury/boot/commands/scheduler.py +124 -0
- aury/boot/commands/server/__init__.py +21 -0
- aury/boot/commands/server/app.py +541 -0
- aury/boot/commands/templates/generate/api.py.tpl +105 -0
- aury/boot/commands/templates/generate/model.py.tpl +17 -0
- aury/boot/commands/templates/generate/repository.py.tpl +19 -0
- aury/boot/commands/templates/generate/schema.py.tpl +29 -0
- aury/boot/commands/templates/generate/service.py.tpl +48 -0
- aury/boot/commands/templates/project/CLI.md.tpl +92 -0
- aury/boot/commands/templates/project/DEVELOPMENT.md.tpl +1397 -0
- aury/boot/commands/templates/project/README.md.tpl +111 -0
- aury/boot/commands/templates/project/admin_console_init.py.tpl +50 -0
- aury/boot/commands/templates/project/config.py.tpl +30 -0
- aury/boot/commands/templates/project/conftest.py.tpl +26 -0
- aury/boot/commands/templates/project/env.example.tpl +213 -0
- aury/boot/commands/templates/project/gitignore.tpl +128 -0
- aury/boot/commands/templates/project/main.py.tpl +41 -0
- aury/boot/commands/templates/project/modules/api.py.tpl +19 -0
- aury/boot/commands/templates/project/modules/exceptions.py.tpl +84 -0
- aury/boot/commands/templates/project/modules/schedules.py.tpl +18 -0
- aury/boot/commands/templates/project/modules/tasks.py.tpl +20 -0
- aury/boot/commands/worker.py +143 -0
- aury/boot/common/__init__.py +35 -0
- aury/boot/common/exceptions/__init__.py +114 -0
- aury/boot/common/i18n/__init__.py +16 -0
- aury/boot/common/i18n/translator.py +272 -0
- aury/boot/common/logging/__init__.py +716 -0
- aury/boot/contrib/__init__.py +10 -0
- aury/boot/contrib/admin_console/__init__.py +18 -0
- aury/boot/contrib/admin_console/auth.py +137 -0
- aury/boot/contrib/admin_console/discovery.py +69 -0
- aury/boot/contrib/admin_console/install.py +172 -0
- aury/boot/contrib/admin_console/utils.py +44 -0
- aury/boot/domain/__init__.py +79 -0
- aury/boot/domain/exceptions/__init__.py +132 -0
- aury/boot/domain/models/__init__.py +51 -0
- aury/boot/domain/models/base.py +69 -0
- aury/boot/domain/models/mixins.py +135 -0
- aury/boot/domain/models/models.py +96 -0
- aury/boot/domain/pagination/__init__.py +279 -0
- aury/boot/domain/repository/__init__.py +23 -0
- aury/boot/domain/repository/impl.py +423 -0
- aury/boot/domain/repository/interceptors.py +47 -0
- aury/boot/domain/repository/interface.py +106 -0
- aury/boot/domain/repository/query_builder.py +348 -0
- aury/boot/domain/service/__init__.py +11 -0
- aury/boot/domain/service/base.py +73 -0
- aury/boot/domain/transaction/__init__.py +404 -0
- aury/boot/infrastructure/__init__.py +104 -0
- aury/boot/infrastructure/cache/__init__.py +31 -0
- aury/boot/infrastructure/cache/backends.py +348 -0
- aury/boot/infrastructure/cache/base.py +68 -0
- aury/boot/infrastructure/cache/exceptions.py +37 -0
- aury/boot/infrastructure/cache/factory.py +94 -0
- aury/boot/infrastructure/cache/manager.py +274 -0
- aury/boot/infrastructure/database/__init__.py +39 -0
- aury/boot/infrastructure/database/config.py +71 -0
- aury/boot/infrastructure/database/exceptions.py +44 -0
- aury/boot/infrastructure/database/manager.py +317 -0
- aury/boot/infrastructure/database/query_tools/__init__.py +164 -0
- aury/boot/infrastructure/database/strategies/__init__.py +198 -0
- aury/boot/infrastructure/di/__init__.py +15 -0
- aury/boot/infrastructure/di/container.py +393 -0
- aury/boot/infrastructure/events/__init__.py +33 -0
- aury/boot/infrastructure/events/bus.py +362 -0
- aury/boot/infrastructure/events/config.py +52 -0
- aury/boot/infrastructure/events/consumer.py +134 -0
- aury/boot/infrastructure/events/middleware.py +51 -0
- aury/boot/infrastructure/events/models.py +63 -0
- aury/boot/infrastructure/monitoring/__init__.py +529 -0
- aury/boot/infrastructure/scheduler/__init__.py +19 -0
- aury/boot/infrastructure/scheduler/exceptions.py +37 -0
- aury/boot/infrastructure/scheduler/manager.py +478 -0
- aury/boot/infrastructure/storage/__init__.py +38 -0
- aury/boot/infrastructure/storage/base.py +164 -0
- aury/boot/infrastructure/storage/exceptions.py +37 -0
- aury/boot/infrastructure/storage/factory.py +88 -0
- aury/boot/infrastructure/tasks/__init__.py +24 -0
- aury/boot/infrastructure/tasks/config.py +45 -0
- aury/boot/infrastructure/tasks/constants.py +37 -0
- aury/boot/infrastructure/tasks/exceptions.py +37 -0
- aury/boot/infrastructure/tasks/manager.py +490 -0
- aury/boot/testing/__init__.py +24 -0
- aury/boot/testing/base.py +122 -0
- aury/boot/testing/client.py +163 -0
- aury/boot/testing/factory.py +154 -0
- aury/boot/toolkit/__init__.py +21 -0
- aury/boot/toolkit/http/__init__.py +367 -0
- {aury_boot-0.0.2.dist-info → aury_boot-0.0.3.dist-info}/METADATA +3 -2
- aury_boot-0.0.3.dist-info/RECORD +137 -0
- aury_boot-0.0.2.dist-info/RECORD +0 -5
- {aury_boot-0.0.2.dist-info → aury_boot-0.0.3.dist-info}/WHEEL +0 -0
- {aury_boot-0.0.2.dist-info → aury_boot-0.0.3.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
"""性能监控模块。
|
|
2
|
+
|
|
3
|
+
提供组件化的性能监控功能,支持自定义监控管道和组件。
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
from functools import wraps
|
|
11
|
+
import time
|
|
12
|
+
|
|
13
|
+
from aury.boot.common.logging import logger
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class MonitorContext:
|
|
17
|
+
"""监控上下文。
|
|
18
|
+
|
|
19
|
+
包含方法执行的上下文信息,供监控组件使用。
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
func_name: str,
|
|
25
|
+
service_name: str,
|
|
26
|
+
start_time: float,
|
|
27
|
+
duration: float | None = None,
|
|
28
|
+
call_count: int | None = None,
|
|
29
|
+
exception: Exception | None = None,
|
|
30
|
+
) -> None:
|
|
31
|
+
"""初始化监控上下文。
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
func_name: 方法全名
|
|
35
|
+
service_name: 服务类名
|
|
36
|
+
start_time: 开始时间
|
|
37
|
+
duration: 执行时长(秒)
|
|
38
|
+
call_count: 调用次数
|
|
39
|
+
exception: 异常对象(如果有)
|
|
40
|
+
"""
|
|
41
|
+
self.func_name = func_name
|
|
42
|
+
self.service_name = service_name
|
|
43
|
+
self.start_time = start_time
|
|
44
|
+
self.duration = duration
|
|
45
|
+
self.call_count = call_count
|
|
46
|
+
self.exception = exception
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class MonitorComponent(ABC):
|
|
50
|
+
"""监控组件接口。
|
|
51
|
+
|
|
52
|
+
所有监控组件都应该实现此接口。
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
@abstractmethod
|
|
56
|
+
async def process(self, context: MonitorContext) -> None:
|
|
57
|
+
"""处理监控上下文。
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
context: 监控上下文
|
|
61
|
+
"""
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class CallCounterComponent(MonitorComponent):
|
|
66
|
+
"""调用次数统计组件。"""
|
|
67
|
+
|
|
68
|
+
def __init__(self) -> None:
|
|
69
|
+
"""初始化调用计数器组件。"""
|
|
70
|
+
self._counters: dict[str, int] = {}
|
|
71
|
+
|
|
72
|
+
async def process(self, context: MonitorContext) -> None:
|
|
73
|
+
"""更新调用次数。
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
context: 监控上下文
|
|
77
|
+
"""
|
|
78
|
+
self._counters[context.func_name] = self._counters.get(context.func_name, 0) + 1
|
|
79
|
+
context.call_count = self._counters[context.func_name]
|
|
80
|
+
|
|
81
|
+
def get_count(self, func_name: str) -> int:
|
|
82
|
+
"""获取方法的调用次数。
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
func_name: 方法全名
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
int: 调用次数
|
|
89
|
+
"""
|
|
90
|
+
return self._counters.get(func_name, 0)
|
|
91
|
+
|
|
92
|
+
def reset(self) -> None:
|
|
93
|
+
"""重置所有计数器。"""
|
|
94
|
+
self._counters.clear()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class SlowMethodDetectorComponent(MonitorComponent):
|
|
98
|
+
"""慢方法检测组件。
|
|
99
|
+
|
|
100
|
+
检测执行时间超过阈值的方法并记录警告。
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
def __init__(self, threshold: float) -> None:
|
|
104
|
+
"""初始化慢方法检测组件。
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
threshold: 慢方法阈值(秒)
|
|
108
|
+
"""
|
|
109
|
+
self._threshold = threshold
|
|
110
|
+
|
|
111
|
+
async def process(self, context: MonitorContext) -> None:
|
|
112
|
+
"""检测慢方法。
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
context: 监控上下文
|
|
116
|
+
"""
|
|
117
|
+
if context.duration is not None and context.duration >= self._threshold:
|
|
118
|
+
logger.warning(
|
|
119
|
+
f"慢方法检测: {context.func_name} 执行时间 {context.duration:.3f}s "
|
|
120
|
+
f"(阈值: {self._threshold}s)"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class StandardMetricsReporterComponent(MonitorComponent):
|
|
125
|
+
"""标准指标报告组件。
|
|
126
|
+
|
|
127
|
+
使用标准日志格式报告性能指标。
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
async def process(self, context: MonitorContext) -> None:
|
|
131
|
+
"""报告性能指标。
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
context: 监控上下文
|
|
135
|
+
"""
|
|
136
|
+
if context.duration is not None and context.call_count is not None:
|
|
137
|
+
logger.debug(
|
|
138
|
+
f"性能指标: {context.func_name} | "
|
|
139
|
+
f"执行时间: {context.duration:.3f}s | "
|
|
140
|
+
f"调用次数: {context.call_count}"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class PrometheusMetricsReporterComponent(MonitorComponent):
|
|
145
|
+
"""Prometheus 格式指标报告组件。
|
|
146
|
+
|
|
147
|
+
使用 Prometheus 格式报告性能指标。
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
async def process(self, context: MonitorContext) -> None:
|
|
151
|
+
"""报告 Prometheus 格式指标。
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
context: 监控上下文
|
|
155
|
+
"""
|
|
156
|
+
if context.duration is not None and context.call_count is not None:
|
|
157
|
+
logger.info(
|
|
158
|
+
f"# TYPE service_method_duration_seconds histogram\n"
|
|
159
|
+
f"service_method_duration_seconds{{"
|
|
160
|
+
f"method=\"{context.func_name}\","
|
|
161
|
+
f"service=\"{context.service_name}\""
|
|
162
|
+
f"}} {context.duration:.6f}\n"
|
|
163
|
+
f"# TYPE service_method_calls_total counter\n"
|
|
164
|
+
f"service_method_calls_total{{"
|
|
165
|
+
f"method=\"{context.func_name}\","
|
|
166
|
+
f"service=\"{context.service_name}\""
|
|
167
|
+
f"}} {context.call_count}"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class ErrorReporterComponent(MonitorComponent):
|
|
172
|
+
"""错误报告组件。
|
|
173
|
+
|
|
174
|
+
报告方法执行失败的错误信息。
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
async def process(self, context: MonitorContext) -> None:
|
|
178
|
+
"""报告错误信息。
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
context: 监控上下文
|
|
182
|
+
"""
|
|
183
|
+
if context.exception is not None and context.duration is not None:
|
|
184
|
+
logger.error(
|
|
185
|
+
f"方法执行失败: {context.func_name} | "
|
|
186
|
+
f"执行时间: {context.duration:.3f}s | "
|
|
187
|
+
f"异常: {type(context.exception).__name__}: {context.exception}"
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class MonitorPipeline:
|
|
192
|
+
"""监控管道。
|
|
193
|
+
|
|
194
|
+
组合多个监控组件,按顺序执行。
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
def __init__(self, *components: MonitorComponent) -> None:
|
|
198
|
+
"""初始化监控管道。
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
*components: 监控组件列表
|
|
202
|
+
"""
|
|
203
|
+
self._components = list(components)
|
|
204
|
+
|
|
205
|
+
def add_component(self, component: MonitorComponent) -> MonitorPipeline:
|
|
206
|
+
"""添加监控组件。
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
component: 监控组件
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
MonitorPipeline: 管道实例(支持链式调用)
|
|
213
|
+
"""
|
|
214
|
+
self._components.append(component)
|
|
215
|
+
return self
|
|
216
|
+
|
|
217
|
+
def add_components(self, *components: MonitorComponent) -> MonitorPipeline:
|
|
218
|
+
"""批量添加监控组件。
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
*components: 监控组件列表
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
MonitorPipeline: 管道实例(支持链式调用)
|
|
225
|
+
"""
|
|
226
|
+
self._components.extend(components)
|
|
227
|
+
return self
|
|
228
|
+
|
|
229
|
+
async def execute(self, context: MonitorContext) -> None:
|
|
230
|
+
"""执行所有监控组件。
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
context: 监控上下文
|
|
234
|
+
"""
|
|
235
|
+
for component in self._components:
|
|
236
|
+
await component.process(context)
|
|
237
|
+
|
|
238
|
+
def __len__(self) -> int:
|
|
239
|
+
"""返回组件数量。"""
|
|
240
|
+
return len(self._components)
|
|
241
|
+
|
|
242
|
+
def __iter__(self):
|
|
243
|
+
"""迭代组件。"""
|
|
244
|
+
return iter(self._components)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
# 全局调用计数器组件实例(所有装饰器共享,用于统计全局调用次数)
|
|
248
|
+
_global_call_counter = CallCounterComponent()
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class MonitorPipelineBuilder:
|
|
252
|
+
"""监控管道构建器。
|
|
253
|
+
|
|
254
|
+
提供便捷的方法构建监控管道。
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
def __init__(self) -> None:
|
|
258
|
+
"""初始化构建器。"""
|
|
259
|
+
self._components: list[MonitorComponent] = []
|
|
260
|
+
|
|
261
|
+
def with_call_counter(
|
|
262
|
+
self,
|
|
263
|
+
counter: CallCounterComponent | None = None,
|
|
264
|
+
) -> MonitorPipelineBuilder:
|
|
265
|
+
"""添加调用次数统计组件。
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
counter: 调用计数器组件,如果为 None 则使用全局实例
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
MonitorPipelineBuilder: 构建器实例(支持链式调用)
|
|
272
|
+
"""
|
|
273
|
+
if counter is None:
|
|
274
|
+
counter = _global_call_counter
|
|
275
|
+
self._components.append(counter)
|
|
276
|
+
return self
|
|
277
|
+
|
|
278
|
+
def with_slow_detector(
|
|
279
|
+
self,
|
|
280
|
+
threshold: float = 1.0,
|
|
281
|
+
detector: SlowMethodDetectorComponent | None = None,
|
|
282
|
+
) -> MonitorPipelineBuilder:
|
|
283
|
+
"""添加慢方法检测组件。
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
threshold: 慢方法阈值(秒)
|
|
287
|
+
detector: 慢方法检测组件,如果为 None 则创建新实例
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
MonitorPipelineBuilder: 构建器实例(支持链式调用)
|
|
291
|
+
"""
|
|
292
|
+
if detector is None:
|
|
293
|
+
detector = SlowMethodDetectorComponent(threshold)
|
|
294
|
+
self._components.append(detector)
|
|
295
|
+
return self
|
|
296
|
+
|
|
297
|
+
def with_metrics_reporter(
|
|
298
|
+
self,
|
|
299
|
+
prometheus_format: bool = False,
|
|
300
|
+
reporter: MonitorComponent | None = None,
|
|
301
|
+
) -> MonitorPipelineBuilder:
|
|
302
|
+
"""添加指标报告组件。
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
prometheus_format: 是否使用 Prometheus 格式
|
|
306
|
+
reporter: 报告组件,如果为 None 则根据 prometheus_format 创建
|
|
307
|
+
|
|
308
|
+
Returns:
|
|
309
|
+
MonitorPipelineBuilder: 构建器实例(支持链式调用)
|
|
310
|
+
"""
|
|
311
|
+
if reporter is None:
|
|
312
|
+
if prometheus_format:
|
|
313
|
+
reporter = PrometheusMetricsReporterComponent()
|
|
314
|
+
else:
|
|
315
|
+
reporter = StandardMetricsReporterComponent()
|
|
316
|
+
self._components.append(reporter)
|
|
317
|
+
return self
|
|
318
|
+
|
|
319
|
+
def with_error_reporter(
|
|
320
|
+
self,
|
|
321
|
+
reporter: ErrorReporterComponent | None = None,
|
|
322
|
+
) -> MonitorPipelineBuilder:
|
|
323
|
+
"""添加错误报告组件。
|
|
324
|
+
|
|
325
|
+
Args:
|
|
326
|
+
reporter: 错误报告组件,如果为 None 则创建新实例
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
MonitorPipelineBuilder: 构建器实例(支持链式调用)
|
|
330
|
+
"""
|
|
331
|
+
if reporter is None:
|
|
332
|
+
reporter = ErrorReporterComponent()
|
|
333
|
+
self._components.append(reporter)
|
|
334
|
+
return self
|
|
335
|
+
|
|
336
|
+
def with_component(self, component: MonitorComponent) -> MonitorPipelineBuilder:
|
|
337
|
+
"""添加自定义组件。
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
component: 监控组件
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
MonitorPipelineBuilder: 构建器实例(支持链式调用)
|
|
344
|
+
"""
|
|
345
|
+
self._components.append(component)
|
|
346
|
+
return self
|
|
347
|
+
|
|
348
|
+
def with_components(self, *components: MonitorComponent) -> MonitorPipelineBuilder:
|
|
349
|
+
"""批量添加自定义组件。
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
*components: 监控组件列表
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
MonitorPipelineBuilder: 构建器实例(支持链式调用)
|
|
356
|
+
"""
|
|
357
|
+
self._components.extend(components)
|
|
358
|
+
return self
|
|
359
|
+
|
|
360
|
+
def build(self) -> MonitorPipeline:
|
|
361
|
+
"""构建监控管道。
|
|
362
|
+
|
|
363
|
+
Returns:
|
|
364
|
+
MonitorPipeline: 监控管道实例
|
|
365
|
+
"""
|
|
366
|
+
return MonitorPipeline(*self._components)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def monitor(
|
|
370
|
+
slow_threshold: float = 1.0,
|
|
371
|
+
metrics: bool = True,
|
|
372
|
+
prometheus_format: bool = False,
|
|
373
|
+
pipeline: MonitorPipeline | None = None,
|
|
374
|
+
components: list[MonitorComponent] | None = None,
|
|
375
|
+
pipeline_builder: Callable[[], MonitorPipeline] | None = None,
|
|
376
|
+
) -> Callable:
|
|
377
|
+
"""服务层性能监控装饰器。
|
|
378
|
+
|
|
379
|
+
监控服务方法的执行时间和调用次数。
|
|
380
|
+
支持慢方法警告和 Prometheus 格式导出。
|
|
381
|
+
支持自定义监控管道和组件。
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
slow_threshold: 慢方法阈值(秒),默认 1.0 秒
|
|
385
|
+
metrics: 是否记录指标(执行时间、调用次数),默认 True
|
|
386
|
+
prometheus_format: 是否使用 Prometheus 格式记录指标,默认 False
|
|
387
|
+
pipeline: 自定义监控管道,如果提供则忽略其他参数
|
|
388
|
+
components: 自定义组件列表,如果提供则使用这些组件构建管道
|
|
389
|
+
pipeline_builder: 自定义管道构建函数,如果提供则使用此函数构建管道
|
|
390
|
+
|
|
391
|
+
用法:
|
|
392
|
+
# 基础用法
|
|
393
|
+
class UserService(BaseService):
|
|
394
|
+
@monitor(slow_threshold=0.5, metrics=True)
|
|
395
|
+
async def create_user(self, data: dict):
|
|
396
|
+
return await self.user_repo.create(data)
|
|
397
|
+
|
|
398
|
+
# 使用自定义组件
|
|
399
|
+
custom_component = MyCustomMonitorComponent()
|
|
400
|
+
@monitor(components=[custom_component])
|
|
401
|
+
async def custom_method(self):
|
|
402
|
+
pass
|
|
403
|
+
|
|
404
|
+
# 使用自定义管道
|
|
405
|
+
custom_pipeline = MonitorPipeline(
|
|
406
|
+
CallCounterComponent(),
|
|
407
|
+
SlowMethodDetectorComponent(0.5),
|
|
408
|
+
MyCustomReporterComponent(),
|
|
409
|
+
)
|
|
410
|
+
@monitor(pipeline=custom_pipeline)
|
|
411
|
+
async def advanced_method(self):
|
|
412
|
+
pass
|
|
413
|
+
|
|
414
|
+
# 使用管道构建器
|
|
415
|
+
def build_custom_pipeline():
|
|
416
|
+
return (MonitorPipelineBuilder()
|
|
417
|
+
.with_call_counter()
|
|
418
|
+
.with_slow_detector(threshold=0.3)
|
|
419
|
+
.with_component(MyCustomComponent())
|
|
420
|
+
.build())
|
|
421
|
+
|
|
422
|
+
@monitor(pipeline_builder=build_custom_pipeline)
|
|
423
|
+
async def builder_method(self):
|
|
424
|
+
pass
|
|
425
|
+
"""
|
|
426
|
+
|
|
427
|
+
# 确定使用的管道
|
|
428
|
+
if pipeline is not None:
|
|
429
|
+
# 使用提供的管道
|
|
430
|
+
monitor_pipeline = pipeline
|
|
431
|
+
elif pipeline_builder is not None:
|
|
432
|
+
# 使用构建器函数
|
|
433
|
+
monitor_pipeline = pipeline_builder()
|
|
434
|
+
elif components is not None:
|
|
435
|
+
# 使用提供的组件列表
|
|
436
|
+
monitor_pipeline = MonitorPipeline(*components)
|
|
437
|
+
else:
|
|
438
|
+
# 使用默认构建逻辑
|
|
439
|
+
builder = MonitorPipelineBuilder()
|
|
440
|
+
|
|
441
|
+
if metrics:
|
|
442
|
+
builder.with_call_counter()
|
|
443
|
+
|
|
444
|
+
builder.with_slow_detector(threshold=slow_threshold)
|
|
445
|
+
|
|
446
|
+
if metrics:
|
|
447
|
+
builder.with_metrics_reporter(prometheus_format=prometheus_format)
|
|
448
|
+
|
|
449
|
+
builder.with_error_reporter()
|
|
450
|
+
|
|
451
|
+
monitor_pipeline = builder.build()
|
|
452
|
+
|
|
453
|
+
def decorator(func: Callable) -> Callable:
|
|
454
|
+
func_name = f"{func.__module__}.{func.__qualname__}"
|
|
455
|
+
|
|
456
|
+
@wraps(func)
|
|
457
|
+
async def wrapper(self, *args, **kwargs):
|
|
458
|
+
start_time = time.time()
|
|
459
|
+
context = MonitorContext(
|
|
460
|
+
func_name=func_name,
|
|
461
|
+
service_name=self.__class__.__name__,
|
|
462
|
+
start_time=start_time,
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
try:
|
|
466
|
+
# 执行方法
|
|
467
|
+
result = await func(self, *args, **kwargs)
|
|
468
|
+
|
|
469
|
+
# 计算执行时间
|
|
470
|
+
context.duration = time.time() - start_time
|
|
471
|
+
|
|
472
|
+
# 更新调用次数(如果管道中有调用计数器)
|
|
473
|
+
for component in monitor_pipeline:
|
|
474
|
+
if isinstance(component, CallCounterComponent):
|
|
475
|
+
context.call_count = component.get_count(func_name)
|
|
476
|
+
break
|
|
477
|
+
|
|
478
|
+
# 执行监控管道(成功场景)
|
|
479
|
+
await monitor_pipeline.execute(context)
|
|
480
|
+
|
|
481
|
+
return result
|
|
482
|
+
|
|
483
|
+
except Exception as exc:
|
|
484
|
+
# 计算执行时间
|
|
485
|
+
context.duration = time.time() - start_time
|
|
486
|
+
context.exception = exc
|
|
487
|
+
|
|
488
|
+
# 执行监控管道(错误场景)
|
|
489
|
+
await monitor_pipeline.execute(context)
|
|
490
|
+
|
|
491
|
+
raise
|
|
492
|
+
|
|
493
|
+
return wrapper
|
|
494
|
+
|
|
495
|
+
return decorator
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
def get_call_count(func_name: str) -> int:
|
|
499
|
+
"""获取方法的调用次数。
|
|
500
|
+
|
|
501
|
+
Args:
|
|
502
|
+
func_name: 方法全名(格式:module.ClassName.method_name)
|
|
503
|
+
|
|
504
|
+
Returns:
|
|
505
|
+
int: 调用次数
|
|
506
|
+
"""
|
|
507
|
+
return _global_call_counter.get_count(func_name)
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
def reset_call_counters() -> None:
|
|
511
|
+
"""重置所有调用计数器。"""
|
|
512
|
+
_global_call_counter.reset()
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
__all__ = [
|
|
516
|
+
"CallCounterComponent",
|
|
517
|
+
"ErrorReporterComponent",
|
|
518
|
+
"MonitorComponent",
|
|
519
|
+
"MonitorContext",
|
|
520
|
+
"MonitorPipeline",
|
|
521
|
+
"MonitorPipelineBuilder",
|
|
522
|
+
"PrometheusMetricsReporterComponent",
|
|
523
|
+
"SlowMethodDetectorComponent",
|
|
524
|
+
"StandardMetricsReporterComponent",
|
|
525
|
+
"get_call_count",
|
|
526
|
+
"monitor",
|
|
527
|
+
"reset_call_counters",
|
|
528
|
+
]
|
|
529
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""任务调度器模块。
|
|
2
|
+
|
|
3
|
+
提供统一的任务调度接口。
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .exceptions import (
|
|
7
|
+
SchedulerBackendError,
|
|
8
|
+
SchedulerError,
|
|
9
|
+
SchedulerJobError,
|
|
10
|
+
)
|
|
11
|
+
from .manager import SchedulerManager
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"SchedulerBackendError",
|
|
15
|
+
"SchedulerError",
|
|
16
|
+
"SchedulerJobError",
|
|
17
|
+
"SchedulerManager",
|
|
18
|
+
]
|
|
19
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""调度器相关异常定义。
|
|
2
|
+
|
|
3
|
+
Infrastructure 层异常,继承自 FoundationError。
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from aury.boot.common.exceptions import FoundationError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SchedulerError(FoundationError):
|
|
12
|
+
"""调度器相关错误基类。
|
|
13
|
+
|
|
14
|
+
所有调度器相关的异常都应该继承此类。
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SchedulerJobError(SchedulerError):
|
|
21
|
+
"""调度器任务错误。"""
|
|
22
|
+
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SchedulerBackendError(SchedulerError):
|
|
27
|
+
"""调度器后端错误。"""
|
|
28
|
+
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
"SchedulerBackendError",
|
|
34
|
+
"SchedulerError",
|
|
35
|
+
"SchedulerJobError",
|
|
36
|
+
]
|
|
37
|
+
|