springbootAI 1.8.0__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 (175) hide show
  1. spring/__init__.py +66 -0
  2. spring/ai/__init__.py +78 -0
  3. spring/ai/advisors.py +139 -0
  4. spring/ai/annotations.py +74 -0
  5. spring/ai/autoconfig.py +481 -0
  6. spring/ai/core.py +391 -0
  7. spring/ai/etl.py +188 -0
  8. spring/ai/memory.py +109 -0
  9. spring/ai/observability.py +129 -0
  10. spring/ai/providers.py +789 -0
  11. spring/ai/resilience.py +258 -0
  12. spring/ai/tools.py +106 -0
  13. spring/ai/vectorstore.py +303 -0
  14. spring/annotations/__init__.py +188 -0
  15. spring/annotations/cache.py +126 -0
  16. spring/annotations/cloud.py +207 -0
  17. spring/annotations/conditional.py +272 -0
  18. spring/annotations/core.py +864 -0
  19. spring/annotations/messaging.py +107 -0
  20. spring/aop/__init__.py +4 -0
  21. spring/aop/cloud_aop.py +404 -0
  22. spring/aop/comprehensive_aop.py +1015 -0
  23. spring/aop/method_interceptor.py +19 -0
  24. spring/aop/proxy_factory.py +55 -0
  25. spring/cloud/__init__.py +76 -0
  26. spring/cloud/discovery.py +364 -0
  27. spring/cloud/feign.py +469 -0
  28. spring/cloud/gateway.py +452 -0
  29. spring/cloud/load_balancer.py +149 -0
  30. spring/cloud/seata.py +557 -0
  31. spring/cloud/sentinel.py +525 -0
  32. spring/cloud/tracer.py +337 -0
  33. spring/config/__init__.py +21 -0
  34. spring/config/binding.py +206 -0
  35. spring/config/config_loader.py +405 -0
  36. spring/context/__init__.py +13 -0
  37. spring/context/application_context.py +589 -0
  38. spring/context/bean_definition.py +70 -0
  39. spring/context/bean_factory.py +1052 -0
  40. spring/context/registry.py +58 -0
  41. spring/context/scanner.py +106 -0
  42. spring/core/__init__.py +3 -0
  43. spring/core/graceful_shutdown.py +196 -0
  44. spring/core/typing_utils.py +50 -0
  45. spring/csv/__init__.py +52 -0
  46. spring/csv/annotations.py +402 -0
  47. spring/csv/converters.py +69 -0
  48. spring/csv/easy_csv.py +95 -0
  49. spring/csv/exceptions.py +27 -0
  50. spring/csv/reader.py +195 -0
  51. spring/csv/writer.py +155 -0
  52. spring/data/__init__.py +54 -0
  53. spring/data/page.py +181 -0
  54. spring/data/repository.py +274 -0
  55. spring/data/specification.py +228 -0
  56. spring/datasource/__init__.py +66 -0
  57. spring/datasource/annotations.py +133 -0
  58. spring/datasource/context.py +69 -0
  59. spring/datasource/dynamic.py +148 -0
  60. spring/event/__init__.py +7 -0
  61. spring/event/publisher.py +69 -0
  62. spring/excel/__init__.py +51 -0
  63. spring/excel/annotations.py +405 -0
  64. spring/excel/converters.py +231 -0
  65. spring/excel/easy_excel.py +94 -0
  66. spring/excel/exceptions.py +31 -0
  67. spring/excel/reader.py +254 -0
  68. spring/excel/style.py +95 -0
  69. spring/excel/writer.py +197 -0
  70. spring/i18n/__init__.py +97 -0
  71. spring/i18n/accessor.py +94 -0
  72. spring/i18n/auto_config.py +177 -0
  73. spring/i18n/holder.py +106 -0
  74. spring/i18n/locale.py +152 -0
  75. spring/i18n/locale_resolver.py +367 -0
  76. spring/i18n/message_source.py +250 -0
  77. spring/i18n/middleware.py +79 -0
  78. spring/i18n/properties.py +168 -0
  79. spring/i18n/sources.py +255 -0
  80. spring/logging/__init__.py +1 -0
  81. spring/logging/loguru_logger.py +228 -0
  82. spring/main.py +378 -0
  83. spring/messaging/__init__.py +1 -0
  84. spring/messaging/rabbitmq.py +302 -0
  85. spring/monitoring/__init__.py +1 -0
  86. spring/monitoring/prometheus.py +199 -0
  87. spring/orm/__init__.py +258 -0
  88. spring/orm/database.py +222 -0
  89. spring/orm/ddl_auto.py +1217 -0
  90. spring/orm/migration.py +419 -0
  91. spring/orm/mybatis_integration.py +400 -0
  92. spring/orm/pymybatis/__init__.py +86 -0
  93. spring/orm/pymybatis/annotations/__init__.py +30 -0
  94. spring/orm/pymybatis/annotations/annotations.py +332 -0
  95. spring/orm/pymybatis/cache/__init__.py +47 -0
  96. spring/orm/pymybatis/cache/cache.py +371 -0
  97. spring/orm/pymybatis/cache/redis_cache.py +434 -0
  98. spring/orm/pymybatis/circuit_breaker/__init__.py +21 -0
  99. spring/orm/pymybatis/circuit_breaker/circuit_breaker.py +424 -0
  100. spring/orm/pymybatis/configuration.py +525 -0
  101. spring/orm/pymybatis/core/__init__.py +10 -0
  102. spring/orm/pymybatis/core/sql_session.py +1382 -0
  103. spring/orm/pymybatis/core/sql_session_factory.py +76 -0
  104. spring/orm/pymybatis/dialect/__init__.py +9 -0
  105. spring/orm/pymybatis/dialect/dialect.py +445 -0
  106. spring/orm/pymybatis/dynamic_sql/__init__.py +9 -0
  107. spring/orm/pymybatis/dynamic_sql/dynamic_sql.py +900 -0
  108. spring/orm/pymybatis/interceptor/__init__.py +31 -0
  109. spring/orm/pymybatis/interceptor/interceptor.py +427 -0
  110. spring/orm/pymybatis/mapper/__init__.py +9 -0
  111. spring/orm/pymybatis/mapper/mapper.py +540 -0
  112. spring/orm/pymybatis/metrics/__init__.py +41 -0
  113. spring/orm/pymybatis/metrics/metrics.py +595 -0
  114. spring/orm/pymybatis/pool/__init__.py +9 -0
  115. spring/orm/pymybatis/pool/connection_pool.py +711 -0
  116. spring/orm/pymybatis/security/__init__.py +19 -0
  117. spring/orm/pymybatis/security/access_control.py +415 -0
  118. spring/orm/pymybatis/security/password_encoder.py +293 -0
  119. spring/orm/pymybatis/security/sensitive_data_masker.py +326 -0
  120. spring/orm/pymybatis/security/sql_injection_detector.py +675 -0
  121. spring/orm/pymybatis/transaction/__init__.py +9 -0
  122. spring/orm/pymybatis/transaction/transaction.py +288 -0
  123. spring/orm/pymybatis/type_handler/__init__.py +37 -0
  124. spring/orm/pymybatis/type_handler/type_handler.py +473 -0
  125. spring/orm/pymybatis/version.py +9 -0
  126. spring/orm/pymybatis/xml_parser/__init__.py +9 -0
  127. spring/orm/pymybatis/xml_parser/xml_parser.py +761 -0
  128. spring/retry/__init__.py +12 -0
  129. spring/retry/retry_annotations.py +71 -0
  130. spring/retry/retry_decorator.py +155 -0
  131. spring/scheduling/__init__.py +3 -0
  132. spring/scheduling/scheduler.py +389 -0
  133. spring/security/__init__.py +39 -0
  134. spring/security/jwt_utils.py +281 -0
  135. spring/security/replay_protection.py +206 -0
  136. spring/security/secret_manager.py +226 -0
  137. spring/security/security_aop.py +248 -0
  138. spring/security/security_context.py +172 -0
  139. spring/test/__init__.py +45 -0
  140. spring/test/slicing.py +341 -0
  141. spring/tracing/__init__.py +11 -0
  142. spring/tracing/skywalking.py +229 -0
  143. spring/tx/__init__.py +52 -0
  144. spring/tx/events.py +172 -0
  145. spring/tx/synchronization.py +143 -0
  146. spring/utils/__init__.py +5 -0
  147. spring/utils/banner.py +32 -0
  148. spring/utils/logger.py +73 -0
  149. spring/utils/redis_client.py +526 -0
  150. spring/validation/__init__.py +55 -0
  151. spring/validation/aop.py +141 -0
  152. spring/validation/constraints.py +357 -0
  153. spring/validation/exceptions.py +55 -0
  154. spring/validation/validator.py +139 -0
  155. spring/web/__init__.py +12 -0
  156. spring/web/actuator.py +319 -0
  157. spring/web/exception_handler.py +61 -0
  158. spring/web/health.py +399 -0
  159. spring/web/interceptor.py +91 -0
  160. spring/web/result.py +44 -0
  161. spring/web/swagger.py +601 -0
  162. spring/web/web_context.py +755 -0
  163. spring/websocket/__init__.py +86 -0
  164. spring/websocket/annotations.py +169 -0
  165. spring/websocket/broker.py +238 -0
  166. spring/websocket/exceptions.py +26 -0
  167. spring/websocket/handler.py +243 -0
  168. spring/websocket/router.py +526 -0
  169. spring/websocket/session.py +216 -0
  170. springbootai-1.8.0.dist-info/METADATA +2796 -0
  171. springbootai-1.8.0.dist-info/RECORD +175 -0
  172. springbootai-1.8.0.dist-info/WHEEL +5 -0
  173. springbootai-1.8.0.dist-info/entry_points.txt +2 -0
  174. springbootai-1.8.0.dist-info/licenses/LICENSE +7 -0
  175. springbootai-1.8.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,595 @@
1
+ """
2
+ PyMyBatis监控指标模块
3
+
4
+ 提供Prometheus兼容的指标收集和导出功能
5
+
6
+ 核心指标类型:
7
+ - Counter: 计数器,只能递增
8
+ - Gauge: 仪表盘,可以增减
9
+ - Histogram: 直方图,统计分布
10
+ - Timer: 计时器,基于直方图
11
+
12
+ 导出格式:
13
+ - Prometheus文本格式
14
+ - JSON格式
15
+ """
16
+
17
+ import time
18
+ import threading
19
+ import logging
20
+ from typing import Dict, Any, List, Optional, Callable
21
+ from collections import defaultdict
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class Counter:
27
+ """计数器指标"""
28
+
29
+ def __init__(self, name: str, help_text: str, labels: Optional[List[str]] = None):
30
+ """
31
+ 初始化计数器
32
+
33
+ Args:
34
+ name: 指标名称
35
+ help_text: 帮助文本
36
+ labels: 标签列表
37
+ """
38
+ self.name = name
39
+ self.help_text = help_text
40
+ self.labels = labels or []
41
+ self._values: Dict[str, float] = defaultdict(float)
42
+ self._lock = threading.RLock()
43
+
44
+ def inc(self, value: float = 1.0, **labels):
45
+ """
46
+ 增加计数
47
+
48
+ Args:
49
+ value: 增加的值
50
+ **labels: 标签值
51
+ """
52
+ key = self._generate_key(labels)
53
+ with self._lock:
54
+ self._values[key] += value
55
+
56
+ def reset(self, **labels):
57
+ """重置计数"""
58
+ key = self._generate_key(labels)
59
+ with self._lock:
60
+ self._values[key] = 0.0
61
+
62
+ def get(self, **labels) -> float:
63
+ """获取当前值"""
64
+ key = self._generate_key(labels)
65
+ return self._values[key]
66
+
67
+ def _generate_key(self, labels: Dict[str, Any]) -> str:
68
+ """生成标签key"""
69
+ if not self.labels:
70
+ return ''
71
+ return ','.join([f"{k}={labels.get(k, '')}" for k in self.labels])
72
+
73
+ def to_prometheus(self) -> str:
74
+ """转换为Prometheus格式"""
75
+ lines = []
76
+ lines.append(f"# HELP {self.name} {self.help_text}")
77
+ lines.append(f"# TYPE {self.name} counter")
78
+
79
+ for key, value in self._values.items():
80
+ if key:
81
+ label_parts = []
82
+ for part in key.split(','):
83
+ k, v = part.split('=', 1)
84
+ label_parts.append(f'{k}="{v}"')
85
+ label_str = '{' + ','.join(label_parts) + '}'
86
+ lines.append(f"{self.name}{label_str} {value}")
87
+ else:
88
+ lines.append(f"{self.name} {value}")
89
+
90
+ return '\n'.join(lines)
91
+
92
+
93
+ class Gauge:
94
+ """仪表盘指标"""
95
+
96
+ def __init__(self, name: str, help_text: str, labels: Optional[List[str]] = None):
97
+ """
98
+ 初始化仪表盘
99
+
100
+ Args:
101
+ name: 指标名称
102
+ help_text: 帮助文本
103
+ labels: 标签列表
104
+ """
105
+ self.name = name
106
+ self.help_text = help_text
107
+ self.labels = labels or []
108
+ self._values: Dict[str, float] = defaultdict(float)
109
+ self._lock = threading.RLock()
110
+
111
+ def set(self, value: float, **labels):
112
+ """设置值"""
113
+ key = self._generate_key(labels)
114
+ with self._lock:
115
+ self._values[key] = value
116
+
117
+ def inc(self, value: float = 1.0, **labels):
118
+ """增加"""
119
+ key = self._generate_key(labels)
120
+ with self._lock:
121
+ self._values[key] += value
122
+
123
+ def dec(self, value: float = 1.0, **labels):
124
+ """减少"""
125
+ key = self._generate_key(labels)
126
+ with self._lock:
127
+ self._values[key] -= value
128
+
129
+ def get(self, **labels) -> float:
130
+ """获取当前值"""
131
+ key = self._generate_key(labels)
132
+ return self._values[key]
133
+
134
+ def _generate_key(self, labels: Dict[str, Any]) -> str:
135
+ """生成标签key"""
136
+ if not self.labels:
137
+ return ''
138
+ return ','.join([f"{k}={labels.get(k, '')}" for k in self.labels])
139
+
140
+ def to_prometheus(self) -> str:
141
+ """转换为Prometheus格式"""
142
+ lines = []
143
+ lines.append(f"# HELP {self.name} {self.help_text}")
144
+ lines.append(f"# TYPE {self.name} gauge")
145
+
146
+ for key, value in self._values.items():
147
+ if key:
148
+ label_parts = []
149
+ for part in key.split(','):
150
+ k, v = part.split('=', 1)
151
+ label_parts.append(f'{k}="{v}"')
152
+ label_str = '{' + ','.join(label_parts) + '}'
153
+ lines.append(f"{self.name}{label_str} {value}")
154
+ else:
155
+ lines.append(f"{self.name} {value}")
156
+
157
+ return '\n'.join(lines)
158
+
159
+
160
+ class Histogram:
161
+ """直方图指标"""
162
+
163
+ def __init__(self, name: str, help_text: str,
164
+ buckets: Optional[List[float]] = None,
165
+ labels: Optional[List[str]] = None):
166
+ """
167
+ 初始化直方图
168
+
169
+ Args:
170
+ name: 指标名称
171
+ help_text: 帮助文本
172
+ buckets: 桶边界
173
+ labels: 标签列表
174
+ """
175
+ self.name = name
176
+ self.help_text = help_text
177
+ self.buckets = buckets or [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0, 10.0]
178
+ self.labels = labels or []
179
+
180
+ # 每个标签组合对应一组桶
181
+ self._buckets: Dict[str, List[int]] = defaultdict(lambda: [0] * (len(self.buckets) + 1))
182
+ self._sums: Dict[str, float] = defaultdict(float)
183
+ self._counts: Dict[str, int] = defaultdict(int)
184
+ self._lock = threading.RLock()
185
+
186
+ def observe(self, value: float, **labels):
187
+ """
188
+ 观察值
189
+
190
+ Args:
191
+ value: 观察的值
192
+ **labels: 标签值
193
+ """
194
+ key = self._generate_key(labels)
195
+
196
+ with self._lock:
197
+ self._counts[key] += 1
198
+ self._sums[key] += value
199
+
200
+ # 更新桶计数
201
+ buckets = self._buckets[key]
202
+ for i, bucket in enumerate(self.buckets):
203
+ if value <= bucket:
204
+ buckets[i] += 1
205
+ buckets[-1] += 1 # +Inf桶
206
+
207
+ def get_counts(self, **labels) -> List[int]:
208
+ """获取桶计数"""
209
+ key = self._generate_key(labels)
210
+ return list(self._buckets[key])
211
+
212
+ def get_sum(self, **labels) -> float:
213
+ """获取总和"""
214
+ key = self._generate_key(labels)
215
+ return self._sums[key]
216
+
217
+ def get_count(self, **labels) -> int:
218
+ """获取计数"""
219
+ key = self._generate_key(labels)
220
+ return self._counts[key]
221
+
222
+ def _generate_key(self, labels: Dict[str, Any]) -> str:
223
+ """生成标签key"""
224
+ if not self.labels:
225
+ return ''
226
+ return ','.join([f"{k}={labels.get(k, '')}" for k in self.labels])
227
+
228
+ def to_prometheus(self) -> str:
229
+ """转换为Prometheus格式"""
230
+ lines = []
231
+ lines.append(f"# HELP {self.name} {self.help_text}")
232
+ lines.append(f"# TYPE {self.name} histogram")
233
+
234
+ for key, buckets in self._buckets.items():
235
+ # 解析标签
236
+ label_items = []
237
+ if key:
238
+ for part in key.split(','):
239
+ k, v = part.split('=', 1)
240
+ label_items.append(f'{k}="{v}"')
241
+
242
+ # 输出桶
243
+ for i, bucket in enumerate(self.buckets):
244
+ bucket_labels = label_items + [f'le="{bucket}"']
245
+ bucket_label_str = '{' + ','.join(bucket_labels) + '}'
246
+ lines.append(f"{self.name}_bucket{bucket_label_str} {buckets[i]}")
247
+
248
+ # +Inf桶
249
+ inf_labels = label_items + ['le="+Inf"']
250
+ inf_label_str = '{' + ','.join(inf_labels) + '}'
251
+ lines.append(f"{self.name}_bucket{inf_label_str} {buckets[-1]}")
252
+
253
+ # sum和count
254
+ base_label_str = '{' + ','.join(label_items) + '}' if label_items else ''
255
+ lines.append(f"{self.name}_sum{base_label_str} {self._sums[key]}")
256
+ lines.append(f"{self.name}_count{base_label_str} {self._counts[key]}")
257
+
258
+ return '\n'.join(lines)
259
+
260
+
261
+ class Timer:
262
+ """计时器指标"""
263
+
264
+ def __init__(self, name: str, help_text: str,
265
+ buckets: Optional[List[float]] = None,
266
+ labels: Optional[List[str]] = None):
267
+ """
268
+ 初始化计时器
269
+
270
+ Args:
271
+ name: 指标名称
272
+ help_text: 帮助文本
273
+ buckets: 桶边界(秒)
274
+ labels: 标签列表
275
+ """
276
+ self._histogram = Histogram(name, help_text, buckets, labels)
277
+
278
+ def observe(self, duration: float, **labels):
279
+ """观察耗时(秒)"""
280
+ self._histogram.observe(duration, **labels)
281
+
282
+ def time(self, **labels) -> 'TimerContext':
283
+ """
284
+ 上下文管理器,自动计时
285
+
286
+ Returns:
287
+ 计时器上下文
288
+ """
289
+ return TimerContext(self, labels)
290
+
291
+ def to_prometheus(self) -> str:
292
+ """转换为Prometheus格式"""
293
+ return self._histogram.to_prometheus()
294
+
295
+
296
+ class TimerContext:
297
+ """计时器上下文管理器"""
298
+
299
+ def __init__(self, timer: Timer, labels: Dict[str, Any]):
300
+ self._timer = timer
301
+ self._labels = labels
302
+ self._start_time = None
303
+
304
+ def __enter__(self):
305
+ """进入上下文,开始计时"""
306
+ self._start_time = time.time()
307
+ return self
308
+
309
+ def __exit__(self, exc_type, exc_val, exc_tb):
310
+ """退出上下文,记录耗时"""
311
+ if self._start_time is not None:
312
+ duration = time.time() - self._start_time
313
+ self._timer.observe(duration, **self._labels)
314
+
315
+
316
+ class MetricsCollector:
317
+ """
318
+ 指标收集器
319
+
320
+ 收集和管理所有指标,支持Prometheus格式导出
321
+ """
322
+
323
+ def __init__(self):
324
+ """初始化指标收集器"""
325
+ self._counters: Dict[str, Counter] = {}
326
+ self._gauges: Dict[str, Gauge] = {}
327
+ self._histograms: Dict[str, Histogram] = {}
328
+ self._timers: Dict[str, Timer] = {}
329
+ self._lock = threading.RLock()
330
+
331
+ def counter(self, name: str, help_text: str, labels: Optional[List[str]] = None) -> Counter:
332
+ """
333
+ 获取或创建计数器
334
+
335
+ Args:
336
+ name: 指标名称
337
+ help_text: 帮助文本
338
+ labels: 标签列表
339
+
340
+ Returns:
341
+ 计数器实例
342
+ """
343
+ with self._lock:
344
+ if name not in self._counters:
345
+ self._counters[name] = Counter(name, help_text, labels)
346
+ return self._counters[name]
347
+
348
+ def gauge(self, name: str, help_text: str, labels: Optional[List[str]] = None) -> Gauge:
349
+ """
350
+ 获取或创建仪表盘
351
+
352
+ Args:
353
+ name: 指标名称
354
+ help_text: 帮助文本
355
+ labels: 标签列表
356
+
357
+ Returns:
358
+ 仪表盘实例
359
+ """
360
+ with self._lock:
361
+ if name not in self._gauges:
362
+ self._gauges[name] = Gauge(name, help_text, labels)
363
+ return self._gauges[name]
364
+
365
+ def histogram(self, name: str, help_text: str,
366
+ buckets: Optional[List[float]] = None,
367
+ labels: Optional[List[str]] = None) -> Histogram:
368
+ """
369
+ 获取或创建直方图
370
+
371
+ Args:
372
+ name: 指标名称
373
+ help_text: 帮助文本
374
+ buckets: 桶边界
375
+ labels: 标签列表
376
+
377
+ Returns:
378
+ 直方图实例
379
+ """
380
+ with self._lock:
381
+ if name not in self._histograms:
382
+ self._histograms[name] = Histogram(name, help_text, buckets, labels)
383
+ return self._histograms[name]
384
+
385
+ def timer(self, name: str, help_text: str,
386
+ buckets: Optional[List[float]] = None,
387
+ labels: Optional[List[str]] = None) -> Timer:
388
+ """
389
+ 获取或创建计时器
390
+
391
+ Args:
392
+ name: 指标名称
393
+ help_text: 帮助文本
394
+ buckets: 桶边界(秒)
395
+ labels: 标签列表
396
+
397
+ Returns:
398
+ 计时器实例
399
+ """
400
+ with self._lock:
401
+ if name not in self._timers:
402
+ self._timers[name] = Timer(name, help_text, buckets, labels)
403
+ return self._timers[name]
404
+
405
+ def collect(self) -> List[str]:
406
+ """
407
+ 收集所有指标
408
+
409
+ Returns:
410
+ 指标字符串列表
411
+ """
412
+ lines = []
413
+
414
+ for counter in self._counters.values():
415
+ lines.append(counter.to_prometheus())
416
+
417
+ for gauge in self._gauges.values():
418
+ lines.append(gauge.to_prometheus())
419
+
420
+ for histogram in self._histograms.values():
421
+ lines.append(histogram.to_prometheus())
422
+
423
+ for timer in self._timers.values():
424
+ lines.append(timer.to_prometheus())
425
+
426
+ return lines
427
+
428
+ def to_prometheus(self) -> str:
429
+ """
430
+ 转换为Prometheus文本格式
431
+
432
+ Returns:
433
+ Prometheus格式字符串
434
+ """
435
+ return '\n'.join(self.collect()) + '\n'
436
+
437
+ def to_dict(self) -> Dict[str, Any]:
438
+ """
439
+ 转换为字典格式
440
+
441
+ Returns:
442
+ 指标字典
443
+ """
444
+ result = {}
445
+
446
+ # 计数器
447
+ result['counters'] = {}
448
+ for name, counter in self._counters.items():
449
+ result['counters'][name] = {
450
+ 'help': counter.help_text,
451
+ 'labels': counter.labels,
452
+ 'values': dict(counter._values)
453
+ }
454
+
455
+ # 仪表盘
456
+ result['gauges'] = {}
457
+ for name, gauge in self._gauges.items():
458
+ result['gauges'][name] = {
459
+ 'help': gauge.help_text,
460
+ 'labels': gauge.labels,
461
+ 'values': dict(gauge._values)
462
+ }
463
+
464
+ # 直方图
465
+ result['histograms'] = {}
466
+ for name, histogram in self._histograms.items():
467
+ result['histograms'][name] = {
468
+ 'help': histogram.help_text,
469
+ 'labels': histogram.labels,
470
+ 'buckets': histogram.buckets,
471
+ 'data': {}
472
+ }
473
+
474
+ # 计时器
475
+ result['timers'] = {}
476
+ for name, timer in self._timers.items():
477
+ result['timers'][name] = {
478
+ 'help': timer._histogram.help_text,
479
+ 'labels': timer._histogram.labels,
480
+ 'buckets': timer._histogram.buckets
481
+ }
482
+
483
+ return result
484
+
485
+ def reset(self):
486
+ """重置所有指标"""
487
+ with self._lock:
488
+ self._counters.clear()
489
+ self._gauges.clear()
490
+ self._histograms.clear()
491
+ self._timers.clear()
492
+
493
+
494
+ # 全局默认指标收集器
495
+ _global_collector = MetricsCollector()
496
+
497
+
498
+ def get_default_collector() -> MetricsCollector:
499
+ """
500
+ 获取全局默认指标收集器
501
+
502
+ Returns:
503
+ 指标收集器实例
504
+ """
505
+ return _global_collector
506
+
507
+
508
+ # 便捷函数
509
+ def counter(name: str, help_text: str, labels: Optional[List[str]] = None) -> Counter:
510
+ """便捷函数:获取或创建计数器"""
511
+ return _global_collector.counter(name, help_text, labels)
512
+
513
+
514
+ def gauge(name: str, help_text: str, labels: Optional[List[str]] = None) -> Gauge:
515
+ """便捷函数:获取或创建仪表盘"""
516
+ return _global_collector.gauge(name, help_text, labels)
517
+
518
+
519
+ def histogram(name: str, help_text: str,
520
+ buckets: Optional[List[float]] = None,
521
+ labels: Optional[List[str]] = None) -> Histogram:
522
+ """便捷函数:获取或创建直方图"""
523
+ return _global_collector.histogram(name, help_text, buckets, labels)
524
+
525
+
526
+ def timer(name: str, help_text: str,
527
+ buckets: Optional[List[float]] = None,
528
+ labels: Optional[List[str]] = None) -> Timer:
529
+ """便捷函数:获取或创建计时器"""
530
+ return _global_collector.timer(name, help_text, buckets, labels)
531
+
532
+
533
+ # 预定义的PyMyBatis核心指标
534
+ # 查询计数
535
+ QUERY_COUNTER = counter(
536
+ 'pymybatis_query_total',
537
+ 'Total number of SQL queries executed',
538
+ labels=['operation', 'table', 'status']
539
+ )
540
+
541
+ # 查询耗时
542
+ QUERY_TIMER = timer(
543
+ 'pymybatis_query_duration_seconds',
544
+ 'Duration of SQL queries in seconds',
545
+ buckets=[0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0, 10.0],
546
+ labels=['operation', 'table']
547
+ )
548
+
549
+ # 连接池活跃连接数
550
+ ACTIVE_CONNECTIONS = gauge(
551
+ 'pymybatis_connection_pool_active_connections',
552
+ 'Number of active connections in the pool',
553
+ labels=['pool']
554
+ )
555
+
556
+ # 连接池空闲连接数
557
+ IDLE_CONNECTIONS = gauge(
558
+ 'pymybatis_connection_pool_idle_connections',
559
+ 'Number of idle connections in the pool',
560
+ labels=['pool']
561
+ )
562
+
563
+ # 缓存命中率
564
+ CACHE_HIT_COUNTER = counter(
565
+ 'pymybatis_cache_hits_total',
566
+ 'Total number of cache hits',
567
+ labels=['cache_type']
568
+ )
569
+
570
+ CACHE_MISS_COUNTER = counter(
571
+ 'pymybatis_cache_misses_total',
572
+ 'Total number of cache misses',
573
+ labels=['cache_type']
574
+ )
575
+
576
+ # 事务计数
577
+ TRANSACTION_COUNTER = counter(
578
+ 'pymybatis_transactions_total',
579
+ 'Total number of transactions',
580
+ labels=['status']
581
+ )
582
+
583
+ # 熔断器状态
584
+ CIRCUIT_BREAKER_STATE = gauge(
585
+ 'pymybatis_circuit_breaker_state',
586
+ 'Circuit breaker state (0=closed, 1=open, 2=half-open)',
587
+ labels=['name']
588
+ )
589
+
590
+ # 熔断器失败率
591
+ CIRCUIT_BREAKER_FAILURE_RATE = gauge(
592
+ 'pymybatis_circuit_breaker_failure_rate',
593
+ 'Circuit breaker failure rate percentage',
594
+ labels=['name']
595
+ )
@@ -0,0 +1,9 @@
1
+ """
2
+ PyMyBatis连接池模块
3
+
4
+ 实现高性能数据库连接池管理,支持多数据源
5
+ """
6
+
7
+ from .connection_pool import ConnectionPool, create_connection_pool
8
+
9
+ __all__ = ['ConnectionPool', 'create_connection_pool']