mdbq 4.0.80__py3-none-any.whl → 4.0.82__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.
- mdbq/__version__.py +1 -1
- mdbq/route/__init__.py +1 -0
- mdbq/route/analytics.py +618 -0
- mdbq/route/monitor.py +940 -0
- mdbq/route/routes.py +576 -0
- {mdbq-4.0.80.dist-info → mdbq-4.0.82.dist-info}/METADATA +1 -1
- {mdbq-4.0.80.dist-info → mdbq-4.0.82.dist-info}/RECORD +9 -5
- {mdbq-4.0.80.dist-info → mdbq-4.0.82.dist-info}/WHEEL +0 -0
- {mdbq-4.0.80.dist-info → mdbq-4.0.82.dist-info}/top_level.txt +0 -0
mdbq/route/routes.py
ADDED
@@ -0,0 +1,576 @@
|
|
1
|
+
"""
|
2
|
+
路由监控管理界面
|
3
|
+
提供完整的监控数据查看和管理功能的Flask路由
|
4
|
+
|
5
|
+
主要功能:
|
6
|
+
1. 实时监控面板
|
7
|
+
2. 统计数据查看
|
8
|
+
3. 告警信息展示
|
9
|
+
4. 报告生成
|
10
|
+
5. 数据清理管理
|
11
|
+
|
12
|
+
"""
|
13
|
+
|
14
|
+
from flask import Blueprint, jsonify, request, render_template_string
|
15
|
+
from datetime import datetime, timedelta
|
16
|
+
from mdbq.route.monitor import route_monitor, monitor_request, get_request_id
|
17
|
+
from mdbq.route.analytics import (
|
18
|
+
get_realtime_metrics, get_traffic_trend, get_endpoint_analysis,
|
19
|
+
get_user_behavior_analysis, get_performance_alerts, generate_daily_report
|
20
|
+
)
|
21
|
+
import json
|
22
|
+
|
23
|
+
# 创建监控管理蓝图
|
24
|
+
monitor_bp = Blueprint('monitor', __name__, url_prefix='/admin/monitor')
|
25
|
+
|
26
|
+
|
27
|
+
@monitor_bp.route('/dashboard', methods=['GET'])
|
28
|
+
@monitor_request
|
29
|
+
def dashboard():
|
30
|
+
"""监控面板首页"""
|
31
|
+
try:
|
32
|
+
# 获取实时指标
|
33
|
+
realtime_data = get_realtime_metrics()
|
34
|
+
|
35
|
+
# 获取告警信息
|
36
|
+
alerts = get_performance_alerts()
|
37
|
+
|
38
|
+
return jsonify({
|
39
|
+
'code': 0,
|
40
|
+
'status': 'success',
|
41
|
+
'message': 'success',
|
42
|
+
'data': {
|
43
|
+
'realtime_metrics': realtime_data,
|
44
|
+
'alerts': alerts,
|
45
|
+
'timestamp': datetime.now().isoformat()
|
46
|
+
}
|
47
|
+
})
|
48
|
+
|
49
|
+
except Exception as e:
|
50
|
+
return jsonify({
|
51
|
+
'code': 500,
|
52
|
+
'status': 'error',
|
53
|
+
'message': 'Failed to get dashboard data',
|
54
|
+
'error': str(e)
|
55
|
+
}), 500
|
56
|
+
|
57
|
+
|
58
|
+
@monitor_bp.route('/metrics/realtime', methods=['GET'])
|
59
|
+
@monitor_request
|
60
|
+
def realtime_metrics():
|
61
|
+
"""获取实时监控指标"""
|
62
|
+
try:
|
63
|
+
data = get_realtime_metrics()
|
64
|
+
return jsonify({
|
65
|
+
'code': 0,
|
66
|
+
'status': 'success',
|
67
|
+
'message': 'success',
|
68
|
+
'data': data
|
69
|
+
})
|
70
|
+
except Exception as e:
|
71
|
+
return jsonify({
|
72
|
+
'code': 500,
|
73
|
+
'status': 'error',
|
74
|
+
'message': 'Failed to get realtime metrics',
|
75
|
+
'error': str(e)
|
76
|
+
}), 500
|
77
|
+
|
78
|
+
|
79
|
+
@monitor_bp.route('/traffic/trend', methods=['GET'])
|
80
|
+
@monitor_request
|
81
|
+
def traffic_trend():
|
82
|
+
"""获取流量趋势分析"""
|
83
|
+
try:
|
84
|
+
days = request.args.get('days', 7, type=int)
|
85
|
+
if days < 1 or days > 90:
|
86
|
+
days = 7
|
87
|
+
|
88
|
+
data = get_traffic_trend(days)
|
89
|
+
return jsonify({
|
90
|
+
'code': 0,
|
91
|
+
'status': 'success',
|
92
|
+
'message': 'success',
|
93
|
+
'data': data
|
94
|
+
})
|
95
|
+
except Exception as e:
|
96
|
+
return jsonify({
|
97
|
+
'code': 500,
|
98
|
+
'status': 'error',
|
99
|
+
'message': 'Failed to get traffic trend',
|
100
|
+
'error': str(e)
|
101
|
+
}), 500
|
102
|
+
|
103
|
+
|
104
|
+
@monitor_bp.route('/endpoints/analysis', methods=['GET'])
|
105
|
+
@monitor_request
|
106
|
+
def endpoint_analysis():
|
107
|
+
"""获取端点性能分析"""
|
108
|
+
try:
|
109
|
+
days = request.args.get('days', 7, type=int)
|
110
|
+
if days < 1 or days > 90:
|
111
|
+
days = 7
|
112
|
+
|
113
|
+
data = get_endpoint_analysis(days)
|
114
|
+
return jsonify({
|
115
|
+
'code': 0,
|
116
|
+
'status': 'success',
|
117
|
+
'message': 'success',
|
118
|
+
'data': data
|
119
|
+
})
|
120
|
+
except Exception as e:
|
121
|
+
return jsonify({
|
122
|
+
'code': 500,
|
123
|
+
'status': 'error',
|
124
|
+
'message': 'Failed to get endpoint analysis',
|
125
|
+
'error': str(e)
|
126
|
+
}), 500
|
127
|
+
|
128
|
+
|
129
|
+
@monitor_bp.route('/users/behavior', methods=['GET'])
|
130
|
+
@monitor_request
|
131
|
+
def user_behavior():
|
132
|
+
"""获取用户行为分析"""
|
133
|
+
try:
|
134
|
+
days = request.args.get('days', 7, type=int)
|
135
|
+
if days < 1 or days > 90:
|
136
|
+
days = 7
|
137
|
+
|
138
|
+
data = get_user_behavior_analysis(days)
|
139
|
+
return jsonify({
|
140
|
+
'code': 0,
|
141
|
+
'status': 'success',
|
142
|
+
'message': 'success',
|
143
|
+
'data': data
|
144
|
+
})
|
145
|
+
except Exception as e:
|
146
|
+
return jsonify({
|
147
|
+
'code': 500,
|
148
|
+
'status': 'error',
|
149
|
+
'message': 'Failed to get user behavior analysis',
|
150
|
+
'error': str(e)
|
151
|
+
}), 500
|
152
|
+
|
153
|
+
|
154
|
+
@monitor_bp.route('/alerts', methods=['GET'])
|
155
|
+
@monitor_request
|
156
|
+
def alerts():
|
157
|
+
"""获取性能告警信息"""
|
158
|
+
try:
|
159
|
+
data = get_performance_alerts()
|
160
|
+
return jsonify({
|
161
|
+
'code': 0,
|
162
|
+
'status': 'success',
|
163
|
+
'message': 'success',
|
164
|
+
'data': data
|
165
|
+
})
|
166
|
+
except Exception as e:
|
167
|
+
return jsonify({
|
168
|
+
'code': 500,
|
169
|
+
'status': 'error',
|
170
|
+
'message': 'Failed to get alerts',
|
171
|
+
'error': str(e)
|
172
|
+
}), 500
|
173
|
+
|
174
|
+
|
175
|
+
@monitor_bp.route('/reports/daily', methods=['GET'])
|
176
|
+
@monitor_request
|
177
|
+
def daily_report():
|
178
|
+
"""获取日报告"""
|
179
|
+
try:
|
180
|
+
date_str = request.args.get('date')
|
181
|
+
target_date = None
|
182
|
+
|
183
|
+
if date_str:
|
184
|
+
try:
|
185
|
+
target_date = datetime.strptime(date_str, '%Y-%m-%d').date()
|
186
|
+
except ValueError:
|
187
|
+
return jsonify({
|
188
|
+
'code': 400,
|
189
|
+
'status': 'error',
|
190
|
+
'message': 'Invalid date format. Use YYYY-MM-DD'
|
191
|
+
}), 400
|
192
|
+
|
193
|
+
data = generate_daily_report(target_date)
|
194
|
+
return jsonify({
|
195
|
+
'code': 0,
|
196
|
+
'status': 'success',
|
197
|
+
'message': 'success',
|
198
|
+
'data': data
|
199
|
+
})
|
200
|
+
except Exception as e:
|
201
|
+
return jsonify({
|
202
|
+
'code': 500,
|
203
|
+
'status': 'error',
|
204
|
+
'message': 'Failed to generate daily report',
|
205
|
+
'error': str(e)
|
206
|
+
}), 500
|
207
|
+
|
208
|
+
|
209
|
+
@monitor_bp.route('/requests/search', methods=['POST'])
|
210
|
+
@monitor_request
|
211
|
+
def search_requests():
|
212
|
+
"""搜索请求记录"""
|
213
|
+
try:
|
214
|
+
data = request.get_json()
|
215
|
+
if not data:
|
216
|
+
return jsonify({
|
217
|
+
'code': 400,
|
218
|
+
'status': 'error',
|
219
|
+
'message': 'Missing request data'
|
220
|
+
}), 400
|
221
|
+
|
222
|
+
# 搜索参数
|
223
|
+
page = data.get('page', 1)
|
224
|
+
page_size = min(data.get('page_size', 50), 200) # 限制页面大小
|
225
|
+
|
226
|
+
filters = data.get('filters', {})
|
227
|
+
start_time = filters.get('start_time')
|
228
|
+
end_time = filters.get('end_time')
|
229
|
+
endpoint = filters.get('endpoint')
|
230
|
+
client_ip = filters.get('client_ip')
|
231
|
+
method = filters.get('method')
|
232
|
+
status_code = filters.get('status_code')
|
233
|
+
min_response_time = filters.get('min_response_time')
|
234
|
+
|
235
|
+
connection = route_monitor.pool.connection()
|
236
|
+
try:
|
237
|
+
with connection.cursor() as cursor:
|
238
|
+
# 构建查询条件
|
239
|
+
where_conditions = ["1=1"]
|
240
|
+
params = []
|
241
|
+
|
242
|
+
if start_time:
|
243
|
+
where_conditions.append("timestamp >= %s")
|
244
|
+
params.append(start_time)
|
245
|
+
|
246
|
+
if end_time:
|
247
|
+
where_conditions.append("timestamp <= %s")
|
248
|
+
params.append(end_time)
|
249
|
+
|
250
|
+
if endpoint:
|
251
|
+
where_conditions.append("endpoint LIKE %s")
|
252
|
+
params.append(f"%{endpoint}%")
|
253
|
+
|
254
|
+
if client_ip:
|
255
|
+
where_conditions.append("client_ip = %s")
|
256
|
+
params.append(client_ip)
|
257
|
+
|
258
|
+
if method:
|
259
|
+
where_conditions.append("method = %s")
|
260
|
+
params.append(method)
|
261
|
+
|
262
|
+
if status_code:
|
263
|
+
where_conditions.append("response_status = %s")
|
264
|
+
params.append(status_code)
|
265
|
+
|
266
|
+
if min_response_time:
|
267
|
+
where_conditions.append("process_time >= %s")
|
268
|
+
params.append(min_response_time)
|
269
|
+
|
270
|
+
where_clause = " AND ".join(where_conditions)
|
271
|
+
|
272
|
+
# 获取总数
|
273
|
+
count_sql = f"SELECT COUNT(*) as total FROM api_request_logs WHERE {where_clause}"
|
274
|
+
cursor.execute(count_sql, params)
|
275
|
+
total_count = cursor.fetchone()['total']
|
276
|
+
|
277
|
+
# 分页查询
|
278
|
+
offset = (page - 1) * page_size
|
279
|
+
search_sql = f"""
|
280
|
+
SELECT
|
281
|
+
request_id, timestamp, method, endpoint, client_ip, real_ip,
|
282
|
+
response_status, process_time, user_agent, referer,
|
283
|
+
is_bot, is_mobile, browser_name, os_name
|
284
|
+
FROM api_request_logs
|
285
|
+
WHERE {where_clause}
|
286
|
+
ORDER BY timestamp DESC
|
287
|
+
LIMIT %s OFFSET %s
|
288
|
+
"""
|
289
|
+
|
290
|
+
cursor.execute(search_sql, params + [page_size, offset])
|
291
|
+
results = cursor.fetchall()
|
292
|
+
|
293
|
+
return jsonify({
|
294
|
+
'code': 0,
|
295
|
+
'status': 'success',
|
296
|
+
'message': 'success',
|
297
|
+
'data': {
|
298
|
+
'requests': results,
|
299
|
+
'pagination': {
|
300
|
+
'current_page': page,
|
301
|
+
'page_size': page_size,
|
302
|
+
'total_count': total_count,
|
303
|
+
'total_pages': (total_count + page_size - 1) // page_size
|
304
|
+
}
|
305
|
+
}
|
306
|
+
})
|
307
|
+
finally:
|
308
|
+
connection.close()
|
309
|
+
|
310
|
+
except Exception as e:
|
311
|
+
return jsonify({
|
312
|
+
'code': 500,
|
313
|
+
'status': 'error',
|
314
|
+
'message': 'Failed to search requests',
|
315
|
+
'error': str(e)
|
316
|
+
}), 500
|
317
|
+
|
318
|
+
|
319
|
+
@monitor_bp.route('/requests/<request_id>', methods=['GET'])
|
320
|
+
@monitor_request
|
321
|
+
def get_request_detail(request_id):
|
322
|
+
"""获取请求详细信息"""
|
323
|
+
try:
|
324
|
+
connection = route_monitor.pool.connection()
|
325
|
+
try:
|
326
|
+
with connection.cursor() as cursor:
|
327
|
+
cursor.execute("""
|
328
|
+
SELECT * FROM api_request_logs WHERE request_id = %s
|
329
|
+
""", (request_id,))
|
330
|
+
|
331
|
+
request_detail = cursor.fetchone()
|
332
|
+
|
333
|
+
if not request_detail:
|
334
|
+
return jsonify({
|
335
|
+
'code': 404,
|
336
|
+
'status': 'error',
|
337
|
+
'message': 'Request not found'
|
338
|
+
}), 404
|
339
|
+
|
340
|
+
# 安全地转换JSON字段
|
341
|
+
json_fields = ['request_headers', 'request_params', 'request_body', 'device_info', 'business_data', 'tags']
|
342
|
+
for field in json_fields:
|
343
|
+
if request_detail.get(field):
|
344
|
+
try:
|
345
|
+
# 使用json.loads替代eval,更安全
|
346
|
+
if isinstance(request_detail[field], str):
|
347
|
+
request_detail[field] = json.loads(request_detail[field])
|
348
|
+
except (json.JSONDecodeError, TypeError):
|
349
|
+
# 如果解析失败,保持原值
|
350
|
+
pass
|
351
|
+
|
352
|
+
return jsonify({
|
353
|
+
'code': 0,
|
354
|
+
'status': 'success',
|
355
|
+
'message': 'success',
|
356
|
+
'data': request_detail
|
357
|
+
})
|
358
|
+
finally:
|
359
|
+
connection.close()
|
360
|
+
|
361
|
+
except Exception as e:
|
362
|
+
return jsonify({
|
363
|
+
'code': 500,
|
364
|
+
'status': 'error',
|
365
|
+
'message': 'Failed to get request detail',
|
366
|
+
'error': str(e)
|
367
|
+
}), 500
|
368
|
+
|
369
|
+
|
370
|
+
@monitor_bp.route('/statistics/summary', methods=['GET'])
|
371
|
+
@monitor_request
|
372
|
+
def statistics_summary():
|
373
|
+
"""获取统计摘要"""
|
374
|
+
try:
|
375
|
+
days = request.args.get('days', 7, type=int)
|
376
|
+
if days < 1 or days > 90:
|
377
|
+
days = 7
|
378
|
+
|
379
|
+
connection = route_monitor.pool.connection()
|
380
|
+
try:
|
381
|
+
with connection.cursor() as cursor:
|
382
|
+
end_date = datetime.now().date()
|
383
|
+
start_date = end_date - timedelta(days=days)
|
384
|
+
|
385
|
+
# 综合统计
|
386
|
+
cursor.execute("""
|
387
|
+
SELECT
|
388
|
+
COUNT(*) as total_requests,
|
389
|
+
COUNT(DISTINCT client_ip) as unique_ips,
|
390
|
+
COUNT(DISTINCT endpoint) as unique_endpoints,
|
391
|
+
COUNT(DISTINCT DATE(timestamp)) as active_days,
|
392
|
+
AVG(process_time) as avg_response_time,
|
393
|
+
MAX(process_time) as max_response_time,
|
394
|
+
SUM(CASE WHEN response_status >= 400 THEN 1 ELSE 0 END) as error_count,
|
395
|
+
SUM(CASE WHEN response_status >= 400 THEN 1 ELSE 0 END) / COUNT(*) * 100 as error_rate,
|
396
|
+
SUM(CASE WHEN is_bot = 1 THEN 1 ELSE 0 END) as bot_requests,
|
397
|
+
SUM(CASE WHEN is_mobile = 1 THEN 1 ELSE 0 END) as mobile_requests,
|
398
|
+
SUM(request_size) as total_request_size,
|
399
|
+
SUM(response_size) as total_response_size
|
400
|
+
FROM api_request_logs
|
401
|
+
WHERE DATE(timestamp) BETWEEN %s AND %s
|
402
|
+
""", (start_date, end_date))
|
403
|
+
|
404
|
+
summary = cursor.fetchone()
|
405
|
+
|
406
|
+
# 每日趋势
|
407
|
+
cursor.execute("""
|
408
|
+
SELECT
|
409
|
+
DATE(timestamp) as date,
|
410
|
+
COUNT(*) as requests,
|
411
|
+
COUNT(DISTINCT client_ip) as unique_ips,
|
412
|
+
AVG(process_time) as avg_response_time,
|
413
|
+
SUM(CASE WHEN response_status >= 400 THEN 1 ELSE 0 END) as errors
|
414
|
+
FROM api_request_logs
|
415
|
+
WHERE DATE(timestamp) BETWEEN %s AND %s
|
416
|
+
GROUP BY DATE(timestamp)
|
417
|
+
ORDER BY date
|
418
|
+
""", (start_date, end_date))
|
419
|
+
|
420
|
+
daily_trend = cursor.fetchall()
|
421
|
+
|
422
|
+
return jsonify({
|
423
|
+
'code': 0,
|
424
|
+
'status': 'success',
|
425
|
+
'message': 'success',
|
426
|
+
'data': {
|
427
|
+
'period': f'{start_date} to {end_date}',
|
428
|
+
'summary': summary,
|
429
|
+
'daily_trend': daily_trend
|
430
|
+
}
|
431
|
+
})
|
432
|
+
finally:
|
433
|
+
connection.close()
|
434
|
+
|
435
|
+
except Exception as e:
|
436
|
+
return jsonify({
|
437
|
+
'code': 500,
|
438
|
+
'status': 'error',
|
439
|
+
'message': 'Failed to get statistics summary',
|
440
|
+
'error': str(e)
|
441
|
+
}), 500
|
442
|
+
|
443
|
+
|
444
|
+
@monitor_bp.route('/data/cleanup', methods=['POST'])
|
445
|
+
@monitor_request
|
446
|
+
def data_cleanup():
|
447
|
+
"""数据清理功能"""
|
448
|
+
try:
|
449
|
+
data = request.get_json()
|
450
|
+
if not data:
|
451
|
+
return jsonify({
|
452
|
+
'code': 400,
|
453
|
+
'status': 'error',
|
454
|
+
'message': 'Missing request data'
|
455
|
+
}), 400
|
456
|
+
|
457
|
+
cleanup_type = data.get('type', 'old_logs')
|
458
|
+
days_to_keep = data.get('days_to_keep', 30)
|
459
|
+
|
460
|
+
if days_to_keep < 7: # 至少保留7天
|
461
|
+
return jsonify({
|
462
|
+
'code': 400,
|
463
|
+
'status': 'error',
|
464
|
+
'message': 'Must keep at least 7 days of data'
|
465
|
+
}), 400
|
466
|
+
|
467
|
+
connection = route_monitor.pool.connection()
|
468
|
+
try:
|
469
|
+
with connection.cursor() as cursor:
|
470
|
+
cleanup_date = datetime.now() - timedelta(days=days_to_keep)
|
471
|
+
|
472
|
+
if cleanup_type == 'old_logs':
|
473
|
+
# 清理旧的请求日志
|
474
|
+
cursor.execute("""
|
475
|
+
DELETE FROM api_request_logs
|
476
|
+
WHERE timestamp < %s
|
477
|
+
""", (cleanup_date,))
|
478
|
+
|
479
|
+
deleted_count = cursor.rowcount
|
480
|
+
|
481
|
+
elif cleanup_type == 'old_statistics':
|
482
|
+
# 清理旧的统计数据
|
483
|
+
cursor.execute("""
|
484
|
+
DELETE FROM api_access_statistics
|
485
|
+
WHERE date < %s
|
486
|
+
""", (cleanup_date.date(),))
|
487
|
+
|
488
|
+
deleted_count = cursor.rowcount
|
489
|
+
|
490
|
+
elif cleanup_type == 'old_ip_stats':
|
491
|
+
# 清理旧的IP统计
|
492
|
+
cursor.execute("""
|
493
|
+
DELETE FROM ip_access_statistics
|
494
|
+
WHERE date < %s
|
495
|
+
""", (cleanup_date.date(),))
|
496
|
+
|
497
|
+
deleted_count = cursor.rowcount
|
498
|
+
|
499
|
+
else:
|
500
|
+
return jsonify({
|
501
|
+
'code': 400,
|
502
|
+
'status': 'error',
|
503
|
+
'message': 'Invalid cleanup type'
|
504
|
+
}), 400
|
505
|
+
|
506
|
+
connection.commit()
|
507
|
+
|
508
|
+
return jsonify({
|
509
|
+
'code': 0,
|
510
|
+
'status': 'success',
|
511
|
+
'message': 'Data cleanup completed',
|
512
|
+
'data': {
|
513
|
+
'cleanup_type': cleanup_type,
|
514
|
+
'deleted_count': deleted_count,
|
515
|
+
'cleanup_date': cleanup_date.isoformat()
|
516
|
+
}
|
517
|
+
})
|
518
|
+
finally:
|
519
|
+
connection.close()
|
520
|
+
|
521
|
+
except Exception as e:
|
522
|
+
return jsonify({
|
523
|
+
'code': 500,
|
524
|
+
'status': 'error',
|
525
|
+
'message': 'Failed to cleanup data',
|
526
|
+
'error': str(e)
|
527
|
+
}), 500
|
528
|
+
|
529
|
+
|
530
|
+
@monitor_bp.route('/health', methods=['GET'])
|
531
|
+
def health_check():
|
532
|
+
"""监控系统健康检查"""
|
533
|
+
try:
|
534
|
+
# 检查数据库连接
|
535
|
+
connection = route_monitor.pool.connection()
|
536
|
+
try:
|
537
|
+
with connection.cursor() as cursor:
|
538
|
+
cursor.execute("SELECT 1")
|
539
|
+
db_status = "OK"
|
540
|
+
|
541
|
+
# 检查最近的数据
|
542
|
+
with connection.cursor() as cursor:
|
543
|
+
cursor.execute("""
|
544
|
+
SELECT COUNT(*) as recent_count
|
545
|
+
FROM api_request_logs
|
546
|
+
WHERE timestamp >= %s
|
547
|
+
""", (datetime.now() - timedelta(hours=1),))
|
548
|
+
|
549
|
+
recent_requests = cursor.fetchone()['recent_count']
|
550
|
+
finally:
|
551
|
+
connection.close()
|
552
|
+
|
553
|
+
return jsonify({
|
554
|
+
'code': 0,
|
555
|
+
'status': 'success',
|
556
|
+
'message': 'Monitor system is healthy',
|
557
|
+
'data': {
|
558
|
+
'database_status': db_status,
|
559
|
+
'recent_requests_count': recent_requests,
|
560
|
+
'timestamp': datetime.now().isoformat()
|
561
|
+
}
|
562
|
+
})
|
563
|
+
|
564
|
+
except Exception as e:
|
565
|
+
return jsonify({
|
566
|
+
'code': 500,
|
567
|
+
'status': 'error',
|
568
|
+
'message': 'Monitor system health check failed',
|
569
|
+
'error': str(e)
|
570
|
+
}), 500
|
571
|
+
|
572
|
+
|
573
|
+
# 导出蓝图注册函数
|
574
|
+
def register_routes(app):
|
575
|
+
"""注册监控路由到Flask应用"""
|
576
|
+
app.register_blueprint(monitor_bp)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
|
2
|
-
mdbq/__version__.py,sha256=
|
2
|
+
mdbq/__version__.py,sha256=EhiuwCH5w9iu_L2CjC33SiyfBk24L8BEGAIfGV49q3E,18
|
3
3
|
mdbq/log/__init__.py,sha256=Mpbrav0s0ifLL7lVDAuePEi1hJKiSHhxcv1byBKDl5E,15
|
4
4
|
mdbq/log/mylogger.py,sha256=DyBftCMNLe1pTTXsa830pUtDISJxpJHFIradYtE3lFA,26418
|
5
5
|
mdbq/myconf/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
@@ -21,10 +21,14 @@ mdbq/pbix/pbix_refresh.py,sha256=JUjKW3bNEyoMVfVfo77UhguvS5AWkixvVhDbw4_MHco,239
|
|
21
21
|
mdbq/pbix/refresh_all.py,sha256=OBT9EewSZ0aRS9vL_FflVn74d4l2G00wzHiikCC4TC0,5926
|
22
22
|
mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
|
23
23
|
mdbq/redis/getredis.py,sha256=vpBuNc22uj9Vr-_Dh25_wpwWM1e-072EAAIBdB_IpL0,23494
|
24
|
+
mdbq/route/__init__.py,sha256=M0NZuQ7-112l8K2h1eayVvSmvQrufrOcD5AYKgIf_Is,1
|
25
|
+
mdbq/route/analytics.py,sha256=iJ-LyE_LNICg4LB9XOd0L-N3Ucfl6BWUTVu9jUNAplg,28069
|
26
|
+
mdbq/route/monitor.py,sha256=jO5QnlZeug7SIbwm4DS7dIhfoYu4iF2rVPcoLobg6u4,42194
|
27
|
+
mdbq/route/routes.py,sha256=DHJg0eRNi7TKqhCHuu8ia3vdQ8cTKwrTm6mwDBtNboM,19111
|
24
28
|
mdbq/selenium/__init__.py,sha256=AKzeEceqZyvqn2dEDoJSzDQnbuENkJSHAlbHAD0u0ZI,10
|
25
29
|
mdbq/selenium/get_driver.py,sha256=1NTlVUE6QsyjTrVVVqTO2LOnYf578ccFWlWnvIXGtic,20903
|
26
30
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
27
|
-
mdbq-4.0.
|
28
|
-
mdbq-4.0.
|
29
|
-
mdbq-4.0.
|
30
|
-
mdbq-4.0.
|
31
|
+
mdbq-4.0.82.dist-info/METADATA,sha256=jwoqL8TsKwNR_JEcxHOS1UMy4i0cVvHRJs-orjOdy6I,364
|
32
|
+
mdbq-4.0.82.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
33
|
+
mdbq-4.0.82.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
34
|
+
mdbq-4.0.82.dist-info/RECORD,,
|
File without changes
|
File without changes
|