mdbq 4.0.82__py3-none-any.whl → 4.0.84__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/monitor.py +57 -64
- {mdbq-4.0.82.dist-info → mdbq-4.0.84.dist-info}/METADATA +1 -1
- {mdbq-4.0.82.dist-info → mdbq-4.0.84.dist-info}/RECORD +6 -6
- {mdbq-4.0.82.dist-info → mdbq-4.0.84.dist-info}/WHEEL +0 -0
- {mdbq-4.0.82.dist-info → mdbq-4.0.84.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
VERSION = '4.0.
|
1
|
+
VERSION = '4.0.84'
|
mdbq/route/monitor.py
CHANGED
@@ -50,34 +50,20 @@ logger = mylogger.MyLogger(
|
|
50
50
|
class RouteMonitor:
|
51
51
|
"""路由监控核心类"""
|
52
52
|
|
53
|
-
def __init__(self,
|
53
|
+
def __init__(self, database='api_monitor_logs'):
|
54
54
|
"""初始化监控系统"""
|
55
|
-
|
56
|
-
|
57
|
-
else:
|
58
|
-
self.init_database_pool()
|
59
|
-
|
55
|
+
self.database = database
|
56
|
+
self.init_database_pool()
|
60
57
|
self.init_database_tables()
|
61
|
-
|
62
|
-
"数据库表": "已创建/验证",
|
63
|
-
"系统状态": "就绪"
|
64
|
-
})
|
65
|
-
|
58
|
+
|
66
59
|
def init_database_pool(self):
|
67
60
|
"""初始化数据库连接池"""
|
68
61
|
try:
|
69
|
-
logger.debug("📊 初始化数据库连接池", {
|
70
|
-
"主机": host,
|
71
|
-
"端口": port,
|
72
|
-
"用户": username,
|
73
|
-
"最大连接数": 3
|
74
|
-
})
|
75
|
-
|
76
62
|
self.pool = PooledDB(
|
77
63
|
creator=pymysql,
|
78
|
-
maxconnections=
|
79
|
-
mincached=1,
|
80
|
-
maxcached=
|
64
|
+
maxconnections=2, # 监控系统连接数较小
|
65
|
+
mincached=1,
|
66
|
+
maxcached=2,
|
81
67
|
blocking=True,
|
82
68
|
host=host,
|
83
69
|
port=int(port),
|
@@ -87,36 +73,55 @@ class RouteMonitor:
|
|
87
73
|
charset='utf8mb4',
|
88
74
|
cursorclass=pymysql.cursors.DictCursor
|
89
75
|
)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
76
|
+
|
77
|
+
# 创建数据库并切换
|
78
|
+
connection = self.pool.connection()
|
79
|
+
try:
|
80
|
+
with connection.cursor() as cursor:
|
81
|
+
cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{self.database}` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci")
|
82
|
+
cursor.execute(f"USE `{self.database}`")
|
83
|
+
finally:
|
84
|
+
connection.close()
|
85
|
+
|
96
86
|
except Exception as e:
|
97
87
|
logger.error("❌ 数据库连接池初始化失败", {
|
98
88
|
"错误信息": str(e),
|
99
|
-
"
|
100
|
-
"端口": port
|
89
|
+
"数据库": self.database
|
101
90
|
})
|
102
91
|
raise
|
92
|
+
|
93
|
+
def ensure_database_context(self, cursor):
|
94
|
+
"""确保当前游标处于正确的数据库上下文中"""
|
95
|
+
try:
|
96
|
+
cursor.execute(f"USE `{self.database}`")
|
97
|
+
except Exception as e:
|
98
|
+
logger.warning("切换数据库上下文失败,尝试重新创建", {
|
99
|
+
"数据库": self.database,
|
100
|
+
"错误": str(e)
|
101
|
+
})
|
102
|
+
cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{self.database}` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci")
|
103
|
+
cursor.execute(f"USE `{self.database}`")
|
103
104
|
|
104
105
|
def init_database_tables(self):
|
105
106
|
"""初始化数据库表结构"""
|
106
107
|
try:
|
107
108
|
logger.debug("🗄️ 开始创建/验证数据库表结构", {
|
108
109
|
"操作": "表结构初始化",
|
109
|
-
"预期表数": 4
|
110
|
+
"预期表数": 4,
|
111
|
+
"数据库": self.database
|
110
112
|
})
|
111
113
|
|
112
114
|
connection = self.pool.connection()
|
113
115
|
try:
|
114
116
|
with connection.cursor() as cursor:
|
117
|
+
# 确保使用正确的数据库上下文
|
118
|
+
self.ensure_database_context(cursor)
|
119
|
+
|
115
120
|
# 创建详细请求记录表 - 修复MySQL 8.4+兼容性
|
116
121
|
cursor.execute("""
|
117
122
|
CREATE TABLE IF NOT EXISTS `api_request_logs` (
|
118
123
|
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
119
|
-
`request_id` VARCHAR(
|
124
|
+
`request_id` VARCHAR(128) NOT NULL COMMENT '请求唯一标识',
|
120
125
|
`timestamp` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '请求时间(精确到毫秒)',
|
121
126
|
`method` VARCHAR(10) NOT NULL COMMENT 'HTTP方法',
|
122
127
|
`endpoint` VARCHAR(500) NOT NULL COMMENT '请求端点',
|
@@ -138,10 +143,10 @@ class RouteMonitor:
|
|
138
143
|
`process_time` DECIMAL(10,3) COMMENT '处理时间(毫秒)',
|
139
144
|
`session_id` VARCHAR(128) COMMENT '会话ID',
|
140
145
|
`user_id` VARCHAR(64) COMMENT '用户ID',
|
141
|
-
`auth_token`
|
142
|
-
`device_fingerprint` VARCHAR(
|
146
|
+
`auth_token` TEXT COMMENT '认证令牌(脱敏)',
|
147
|
+
`device_fingerprint` VARCHAR(256) COMMENT '设备指纹',
|
143
148
|
`device_info` JSON COMMENT '设备信息',
|
144
|
-
`geo_country` VARCHAR(
|
149
|
+
`geo_country` VARCHAR(100) COMMENT '地理位置-国家',
|
145
150
|
`geo_region` VARCHAR(100) COMMENT '地理位置-地区',
|
146
151
|
`geo_city` VARCHAR(100) COMMENT '地理位置-城市',
|
147
152
|
`is_bot` BOOLEAN DEFAULT FALSE COMMENT '是否为机器人',
|
@@ -164,12 +169,6 @@ class RouteMonitor:
|
|
164
169
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
165
170
|
COMMENT='API请求详细日志表';
|
166
171
|
""")
|
167
|
-
|
168
|
-
logger.debug("✅ api_request_logs 表创建/验证成功", {
|
169
|
-
"表名": "api_request_logs",
|
170
|
-
"用途": "API请求详细日志"
|
171
|
-
})
|
172
|
-
|
173
172
|
# 创建访问统计汇总表
|
174
173
|
cursor.execute("""
|
175
174
|
CREATE TABLE IF NOT EXISTS `api_access_statistics` (
|
@@ -200,11 +199,6 @@ class RouteMonitor:
|
|
200
199
|
COMMENT='API访问统计汇总表';
|
201
200
|
""")
|
202
201
|
|
203
|
-
logger.debug("✅ api_access_statistics 表创建/验证成功", {
|
204
|
-
"表名": "api_access_statistics",
|
205
|
-
"用途": "API访问统计汇总"
|
206
|
-
})
|
207
|
-
|
208
202
|
# 创建IP访问统计表
|
209
203
|
cursor.execute("""
|
210
204
|
CREATE TABLE IF NOT EXISTS `ip_access_statistics` (
|
@@ -232,12 +226,6 @@ class RouteMonitor:
|
|
232
226
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
233
227
|
COMMENT='IP访问统计表';
|
234
228
|
""")
|
235
|
-
|
236
|
-
logger.debug("✅ ip_access_statistics 表创建/验证成功", {
|
237
|
-
"表名": "ip_access_statistics",
|
238
|
-
"用途": "IP访问统计"
|
239
|
-
})
|
240
|
-
|
241
229
|
# 创建系统性能统计表
|
242
230
|
cursor.execute("""
|
243
231
|
CREATE TABLE IF NOT EXISTS `system_performance_stats` (
|
@@ -256,16 +244,11 @@ class RouteMonitor:
|
|
256
244
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
257
245
|
COMMENT='系统性能统计表';
|
258
246
|
""")
|
259
|
-
|
260
|
-
logger.debug("✅ system_performance_stats 表创建/验证成功", {
|
261
|
-
"表名": "system_performance_stats",
|
262
|
-
"用途": "系统性能统计"
|
263
|
-
})
|
264
|
-
|
265
247
|
connection.commit()
|
266
|
-
logger.
|
248
|
+
logger.debug("🎯 所有数据库表结构初始化完成", {
|
267
249
|
"创建表数": 4,
|
268
250
|
"操作状态": "成功",
|
251
|
+
"数据库": self.database,
|
269
252
|
"数据库引擎": "InnoDB"
|
270
253
|
})
|
271
254
|
|
@@ -276,6 +259,7 @@ class RouteMonitor:
|
|
276
259
|
logger.error("❌ 数据库表结构初始化失败", {
|
277
260
|
"错误信息": str(e),
|
278
261
|
"错误类型": type(e).__name__,
|
262
|
+
"数据库": self.database,
|
279
263
|
"影响": "监控系统可能无法正常工作"
|
280
264
|
})
|
281
265
|
# 静默处理初始化错误,避免影响主应用
|
@@ -615,6 +599,9 @@ class RouteMonitor:
|
|
615
599
|
connection = self.pool.connection()
|
616
600
|
try:
|
617
601
|
with connection.cursor() as cursor:
|
602
|
+
# 确保使用正确的数据库上下文
|
603
|
+
self.ensure_database_context(cursor)
|
604
|
+
|
618
605
|
# 插入请求日志
|
619
606
|
columns = ', '.join([f"`{key}`" for key in request_data.keys()])
|
620
607
|
placeholders = ', '.join(['%s'] * len(request_data))
|
@@ -663,6 +650,9 @@ class RouteMonitor:
|
|
663
650
|
connection = self.pool.connection()
|
664
651
|
try:
|
665
652
|
with connection.cursor() as cursor:
|
653
|
+
# 确保使用正确的数据库上下文
|
654
|
+
self.ensure_database_context(cursor)
|
655
|
+
|
666
656
|
now = datetime.now()
|
667
657
|
date = now.date()
|
668
658
|
hour = now.hour
|
@@ -832,6 +822,9 @@ class RouteMonitor:
|
|
832
822
|
connection = self.pool.connection()
|
833
823
|
try:
|
834
824
|
with connection.cursor() as cursor:
|
825
|
+
# 确保使用正确的数据库上下文
|
826
|
+
self.ensure_database_context(cursor)
|
827
|
+
|
835
828
|
end_date = datetime.now().date()
|
836
829
|
start_date = end_date - timedelta(days=days)
|
837
830
|
|
@@ -856,11 +849,11 @@ class RouteMonitor:
|
|
856
849
|
summary = cursor.fetchone() or {}
|
857
850
|
|
858
851
|
logger.debug("📈 总体统计查询完成", {
|
859
|
-
"总请求数": summary.get('total_requests', 0),
|
860
|
-
"成功请求数": summary.get('success_requests', 0),
|
861
|
-
"错误请求数": summary.get('error_requests', 0),
|
862
|
-
"平均响应时间": f"{summary.get('avg_response_time', 0):.2f}ms",
|
863
|
-
"唯一端点数": summary.get('unique_endpoints', 0)
|
852
|
+
"总请求数": summary.get('total_requests', 0) or 0,
|
853
|
+
"成功请求数": summary.get('success_requests', 0) or 0,
|
854
|
+
"错误请求数": summary.get('error_requests', 0) or 0,
|
855
|
+
"平均响应时间": f"{(summary.get('avg_response_time', 0) or 0):.2f}ms",
|
856
|
+
"唯一端点数": summary.get('unique_endpoints', 0) or 0
|
864
857
|
})
|
865
858
|
|
866
859
|
# 热门端点
|
@@ -937,4 +930,4 @@ def get_request_id():
|
|
937
930
|
|
938
931
|
def get_statistics_summary(days: int = 7):
|
939
932
|
"""获取统计摘要"""
|
940
|
-
return route_monitor.get_statistics_summary(days)
|
933
|
+
return route_monitor.get_statistics_summary(days)
|
@@ -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=DKEREjda7Yk0ZlFGiwLx16SrhlGu8IWp1Fi03ZFRPMY,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
|
@@ -23,12 +23,12 @@ mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
|
|
23
23
|
mdbq/redis/getredis.py,sha256=vpBuNc22uj9Vr-_Dh25_wpwWM1e-072EAAIBdB_IpL0,23494
|
24
24
|
mdbq/route/__init__.py,sha256=M0NZuQ7-112l8K2h1eayVvSmvQrufrOcD5AYKgIf_Is,1
|
25
25
|
mdbq/route/analytics.py,sha256=iJ-LyE_LNICg4LB9XOd0L-N3Ucfl6BWUTVu9jUNAplg,28069
|
26
|
-
mdbq/route/monitor.py,sha256=
|
26
|
+
mdbq/route/monitor.py,sha256=UNcnYSaT8IauiUn9NKkC3zY5yhObcUwnxfuoD4Rq_T4,42198
|
27
27
|
mdbq/route/routes.py,sha256=DHJg0eRNi7TKqhCHuu8ia3vdQ8cTKwrTm6mwDBtNboM,19111
|
28
28
|
mdbq/selenium/__init__.py,sha256=AKzeEceqZyvqn2dEDoJSzDQnbuENkJSHAlbHAD0u0ZI,10
|
29
29
|
mdbq/selenium/get_driver.py,sha256=1NTlVUE6QsyjTrVVVqTO2LOnYf578ccFWlWnvIXGtic,20903
|
30
30
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
31
|
-
mdbq-4.0.
|
32
|
-
mdbq-4.0.
|
33
|
-
mdbq-4.0.
|
34
|
-
mdbq-4.0.
|
31
|
+
mdbq-4.0.84.dist-info/METADATA,sha256=fWgptYBJiRDu8qJ4GgEU-a8fVMnR89DHoVdEgEmO3Qw,364
|
32
|
+
mdbq-4.0.84.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
33
|
+
mdbq-4.0.84.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
34
|
+
mdbq-4.0.84.dist-info/RECORD,,
|
File without changes
|
File without changes
|