mdbq 4.2.17__py3-none-any.whl → 4.2.19__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.
Potentially problematic release.
This version of mdbq might be problematic. Click here for more details.
- mdbq/__version__.py +1 -1
- mdbq/redis/redis_cache.py +15 -2
- mdbq/route/monitor.py +56 -15
- {mdbq-4.2.17.dist-info → mdbq-4.2.19.dist-info}/METADATA +2 -2
- {mdbq-4.2.17.dist-info → mdbq-4.2.19.dist-info}/RECORD +7 -7
- {mdbq-4.2.17.dist-info → mdbq-4.2.19.dist-info}/WHEEL +1 -1
- {mdbq-4.2.17.dist-info → mdbq-4.2.19.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION = '4.2.
|
|
1
|
+
VERSION = '4.2.19'
|
mdbq/redis/redis_cache.py
CHANGED
|
@@ -914,16 +914,23 @@ def flask_redis_cache(cache_key_func=None, ttl=1200, namespace="default",
|
|
|
914
914
|
def wrapper(*args, **kwargs):
|
|
915
915
|
# 导入Flask相关模块(延迟导入避免依赖问题)
|
|
916
916
|
try:
|
|
917
|
-
from flask import request, jsonify
|
|
917
|
+
from flask import request, jsonify, g
|
|
918
918
|
except ImportError:
|
|
919
919
|
# 如果没有Flask环境,直接执行原函数
|
|
920
920
|
return func(*args, **kwargs)
|
|
921
921
|
|
|
922
|
+
# 初始化数据源标记(默认为 none)
|
|
923
|
+
g.data_source = 'none'
|
|
924
|
+
g.cache_hit = False
|
|
925
|
+
|
|
922
926
|
# 获取缓存系统
|
|
923
927
|
cache_system = cache_manager.get_cache()
|
|
924
928
|
|
|
925
929
|
# 如果缓存系统不可用,直接执行原函数
|
|
926
930
|
if not cache_system:
|
|
931
|
+
# 标记为直接查询数据库(无缓存系统)
|
|
932
|
+
g.data_source = 'mysql'
|
|
933
|
+
g.cache_hit = False
|
|
927
934
|
return func(*args, **kwargs)
|
|
928
935
|
|
|
929
936
|
try:
|
|
@@ -952,12 +959,18 @@ def flask_redis_cache(cache_key_func=None, ttl=1200, namespace="default",
|
|
|
952
959
|
try:
|
|
953
960
|
cached_result = cache_system.get(cache_key, namespace)
|
|
954
961
|
if cached_result is not None:
|
|
962
|
+
# 缓存命中:标记为 redis
|
|
963
|
+
g.data_source = 'redis'
|
|
964
|
+
g.cache_hit = True
|
|
955
965
|
return jsonify(cached_result)
|
|
956
966
|
except Exception as e:
|
|
957
967
|
if not skip_cache_on_error:
|
|
958
968
|
raise
|
|
959
969
|
|
|
960
|
-
#
|
|
970
|
+
# 缓存未命中,执行原函数(会查询数据库)
|
|
971
|
+
# 标记为 mysql 查询
|
|
972
|
+
g.data_source = 'mysql'
|
|
973
|
+
g.cache_hit = False
|
|
961
974
|
result = func(*args, **kwargs)
|
|
962
975
|
|
|
963
976
|
# 如果结果是Flask Response对象,提取JSON数据进行缓存
|
mdbq/route/monitor.py
CHANGED
|
@@ -176,6 +176,8 @@ class RouteMonitor:
|
|
|
176
176
|
`客户端ip` VARCHAR(45) NOT NULL COMMENT '客户端 ip 地址(支持 IPv6)',
|
|
177
177
|
`状态码` SMALLINT COMMENT 'HTTP 状态码',
|
|
178
178
|
`响应耗时` DECIMAL(10,3) COMMENT '请求处理耗时(毫秒)',
|
|
179
|
+
`数据源` VARCHAR(20) COMMENT '数据源类型:redis/mysql/hybrid/none',
|
|
180
|
+
`缓存命中` TINYINT(1) DEFAULT 0 COMMENT '是否命中缓存:1-命中,0-未命中',
|
|
179
181
|
`用户标识` VARCHAR(64) COMMENT '用户id或标识(如有)',
|
|
180
182
|
`用户代理` VARCHAR(500) COMMENT '浏览器 User-Agent(精简版)',
|
|
181
183
|
`请求参数` TEXT COMMENT '请求参数(JSON格式,可选记录)',
|
|
@@ -188,8 +190,11 @@ class RouteMonitor:
|
|
|
188
190
|
INDEX `idx_路由地址` (`路由地址`(191)),
|
|
189
191
|
INDEX `idx_客户端ip` (`客户端ip`),
|
|
190
192
|
INDEX `idx_状态码` (`状态码`),
|
|
193
|
+
INDEX `idx_数据源` (`数据源`),
|
|
194
|
+
INDEX `idx_缓存命中` (`缓存命中`),
|
|
191
195
|
INDEX `idx_用户标识` (`用户标识`),
|
|
192
|
-
INDEX `idx_时间_接口` (`请求时间`, `路由地址`(191))
|
|
196
|
+
INDEX `idx_时间_接口` (`请求时间`, `路由地址`(191)),
|
|
197
|
+
INDEX `idx_时间_数据源` (`请求时间`, `数据源`)
|
|
193
198
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
194
199
|
COMMENT='API 访问日志表 - 记录每次请求的核心信息'
|
|
195
200
|
ROW_FORMAT=COMPRESSED;
|
|
@@ -207,6 +212,8 @@ class RouteMonitor:
|
|
|
207
212
|
`请求总数` INT UNSIGNED DEFAULT 0 COMMENT '总请求次数',
|
|
208
213
|
`成功次数` INT UNSIGNED DEFAULT 0 COMMENT '成功响应次数(状态码 < 400)',
|
|
209
214
|
`失败次数` INT UNSIGNED DEFAULT 0 COMMENT '失败响应次数(状态码 >= 400)',
|
|
215
|
+
`缓存命中次数` INT UNSIGNED DEFAULT 0 COMMENT '缓存命中次数',
|
|
216
|
+
`数据库查询次数` INT UNSIGNED DEFAULT 0 COMMENT '没有命中缓存,直接查询数据库的次数',
|
|
210
217
|
`平均耗时` DECIMAL(10,3) DEFAULT 0 COMMENT '平均响应耗时(毫秒)',
|
|
211
218
|
`最大耗时` DECIMAL(10,3) DEFAULT 0 COMMENT '最大响应耗时(毫秒)',
|
|
212
219
|
`最小耗时` DECIMAL(10,3) DEFAULT NULL COMMENT '最小响应耗时(毫秒)',
|
|
@@ -451,11 +458,27 @@ class RouteMonitor:
|
|
|
451
458
|
user_agent = user_agent[:500]
|
|
452
459
|
|
|
453
460
|
# 获取用户标识(如果有)
|
|
461
|
+
# 安全获取 user_id,允许为空时使用默认值
|
|
454
462
|
user_id = None
|
|
455
463
|
if hasattr(g, 'current_user_id'):
|
|
456
|
-
user_id = str(g.current_user_id)
|
|
464
|
+
user_id = str(g.current_user_id) if g.current_user_id else None
|
|
457
465
|
elif hasattr(g, 'user_id'):
|
|
458
|
-
user_id = str(g.user_id)
|
|
466
|
+
user_id = str(g.user_id) if g.user_id else None
|
|
467
|
+
|
|
468
|
+
# 如果还是获取不到,尝试从 request.current_user 获取
|
|
469
|
+
if not user_id and hasattr(request, 'current_user'):
|
|
470
|
+
try:
|
|
471
|
+
current_user = request.current_user
|
|
472
|
+
if isinstance(current_user, dict):
|
|
473
|
+
user_id = current_user.get('user_id') or current_user.get('id')
|
|
474
|
+
if user_id:
|
|
475
|
+
user_id = str(user_id)
|
|
476
|
+
except Exception:
|
|
477
|
+
pass
|
|
478
|
+
|
|
479
|
+
# 兜底:使用默认值,避免 None
|
|
480
|
+
if not user_id:
|
|
481
|
+
user_id = 'anonymous'
|
|
459
482
|
|
|
460
483
|
# 收集请求参数(GET 参数 + POST 数据)
|
|
461
484
|
request_params = None
|
|
@@ -483,6 +506,10 @@ class RouteMonitor:
|
|
|
483
506
|
if params_dict:
|
|
484
507
|
request_params = self.sanitize_params(params_dict)
|
|
485
508
|
|
|
509
|
+
# 获取数据源信息(从 g 对象中读取,由缓存装饰器设置)
|
|
510
|
+
data_source = getattr(g, 'data_source', 'none')
|
|
511
|
+
cache_hit = getattr(g, 'cache_hit', False)
|
|
512
|
+
|
|
486
513
|
# 构建请求数据字典
|
|
487
514
|
request_data = {
|
|
488
515
|
'请求id': request_id,
|
|
@@ -490,6 +517,8 @@ class RouteMonitor:
|
|
|
490
517
|
'请求方法': request.method,
|
|
491
518
|
'路由地址': request.endpoint or request.path,
|
|
492
519
|
'客户端ip': client_ip,
|
|
520
|
+
'数据源': data_source,
|
|
521
|
+
'缓存命中': 1 if cache_hit else 0,
|
|
493
522
|
'用户标识': user_id,
|
|
494
523
|
'用户代理': user_agent,
|
|
495
524
|
'请求参数': request_params,
|
|
@@ -523,9 +552,10 @@ class RouteMonitor:
|
|
|
523
552
|
sql = """
|
|
524
553
|
INSERT INTO `api_访问日志` (
|
|
525
554
|
`请求id`, `请求时间`, `请求方法`, `路由地址`, `客户端ip`,
|
|
526
|
-
`状态码`, `响应耗时`,
|
|
555
|
+
`状态码`, `响应耗时`, `数据源`, `缓存命中`,
|
|
556
|
+
`用户标识`, `用户代理`, `请求参数`, `错误信息`
|
|
527
557
|
) VALUES (
|
|
528
|
-
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
|
|
558
|
+
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
|
|
529
559
|
)
|
|
530
560
|
"""
|
|
531
561
|
|
|
@@ -537,6 +567,8 @@ class RouteMonitor:
|
|
|
537
567
|
request_data.get('客户端ip'),
|
|
538
568
|
request_data.get('状态码'),
|
|
539
569
|
request_data.get('响应耗时'),
|
|
570
|
+
request_data.get('数据源', 'none'),
|
|
571
|
+
request_data.get('缓存命中', 0),
|
|
540
572
|
request_data.get('用户标识'),
|
|
541
573
|
request_data.get('用户代理'),
|
|
542
574
|
request_data.get('请求参数'),
|
|
@@ -581,18 +613,27 @@ class RouteMonitor:
|
|
|
581
613
|
is_error = 1 if status_code >= 400 else 0
|
|
582
614
|
response_time = request_data.get('响应耗时', 0)
|
|
583
615
|
|
|
616
|
+
# 获取数据源信息
|
|
617
|
+
cache_hit = request_data.get('缓存命中', 0)
|
|
618
|
+
data_source = request_data.get('数据源', 'none')
|
|
619
|
+
is_cache_hit = 1 if cache_hit else 0
|
|
620
|
+
is_db_query = 1 if data_source in ['mysql', 'hybrid'] else 0
|
|
621
|
+
|
|
584
622
|
# 1. 更新接口统计表
|
|
585
623
|
cursor.execute("""
|
|
586
624
|
INSERT INTO `api_接口统计` (
|
|
587
625
|
`统计日期`, `统计小时`, `路由地址`, `请求方法`,
|
|
588
626
|
`请求总数`, `成功次数`, `失败次数`,
|
|
627
|
+
`缓存命中次数`, `数据库查询次数`,
|
|
589
628
|
`平均耗时`, `最大耗时`, `最小耗时`
|
|
590
629
|
) VALUES (
|
|
591
|
-
%s, %s, %s, %s, 1, %s, %s, %s, %s, %s
|
|
630
|
+
%s, %s, %s, %s, 1, %s, %s, %s, %s, %s, %s, %s
|
|
592
631
|
) ON DUPLICATE KEY UPDATE
|
|
593
632
|
`请求总数` = `请求总数` + 1,
|
|
594
633
|
`成功次数` = `成功次数` + %s,
|
|
595
634
|
`失败次数` = `失败次数` + %s,
|
|
635
|
+
`缓存命中次数` = `缓存命中次数` + %s,
|
|
636
|
+
`数据库查询次数` = `数据库查询次数` + %s,
|
|
596
637
|
`平均耗时` = (
|
|
597
638
|
(`平均耗时` * `请求总数` + %s) / (`请求总数` + 1)
|
|
598
639
|
),
|
|
@@ -607,13 +648,13 @@ class RouteMonitor:
|
|
|
607
648
|
date, hour,
|
|
608
649
|
request_data.get('路由地址', ''),
|
|
609
650
|
request_data.get('请求方法', ''),
|
|
610
|
-
is_success, is_error,
|
|
651
|
+
is_success, is_error, is_cache_hit, is_db_query,
|
|
611
652
|
response_time, response_time, response_time,
|
|
612
|
-
is_success, is_error,
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
653
|
+
is_success, is_error, is_cache_hit, is_db_query,
|
|
654
|
+
response_time,
|
|
655
|
+
response_time,
|
|
656
|
+
response_time,
|
|
657
|
+
response_time
|
|
617
658
|
))
|
|
618
659
|
|
|
619
660
|
# 2. 更新 IP 统计表
|
|
@@ -686,7 +727,7 @@ class RouteMonitor:
|
|
|
686
727
|
|
|
687
728
|
# 收集请求数据
|
|
688
729
|
request_data = self.collect_request_data(request)
|
|
689
|
-
request_id = request_data.get('请求id', 'unknown')
|
|
730
|
+
# request_id = request_data.get('请求id', 'unknown')
|
|
690
731
|
|
|
691
732
|
# 统计总请求数(线程安全)
|
|
692
733
|
with self._stats_lock:
|
|
@@ -723,7 +764,7 @@ class RouteMonitor:
|
|
|
723
764
|
# 合并数据
|
|
724
765
|
request_data.update(response_data)
|
|
725
766
|
|
|
726
|
-
#
|
|
767
|
+
# 优先使用 Redis 队列(非阻塞)
|
|
727
768
|
queued = self._push_to_queue({
|
|
728
769
|
'type': 'request_log',
|
|
729
770
|
'data': request_data,
|
|
@@ -754,7 +795,7 @@ class RouteMonitor:
|
|
|
754
795
|
# 合并数据
|
|
755
796
|
request_data.update(error_data)
|
|
756
797
|
|
|
757
|
-
#
|
|
798
|
+
# 优先使用 Redis 队列(非阻塞)
|
|
758
799
|
queued = self._push_to_queue({
|
|
759
800
|
'type': 'request_log',
|
|
760
801
|
'data': request_data,
|
|
@@ -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=r7N-NWrrPPVAUY93eumJUOnKKVt6StlWP43PDbmquBI,18
|
|
3
3
|
mdbq/auth/__init__.py,sha256=pnPMAt63sh1B6kEvmutUuro46zVf2v2YDAG7q-jV_To,24
|
|
4
4
|
mdbq/auth/auth_backend.py,sha256=iLN7AqiSq7fQgFtNtge_TIlVOR1hrCSZXH6oId6uGX4,116924
|
|
5
5
|
mdbq/auth/crypto.py,sha256=M0i4dRljJuE30WH_13ythA2QGKPXZm6TgpnYp6aHOzw,17431
|
|
@@ -27,15 +27,15 @@ mdbq/pbix/pbix_refresh.py,sha256=JUjKW3bNEyoMVfVfo77UhguvS5AWkixvVhDbw4_MHco,239
|
|
|
27
27
|
mdbq/pbix/refresh_all.py,sha256=OBT9EewSZ0aRS9vL_FflVn74d4l2G00wzHiikCC4TC0,5926
|
|
28
28
|
mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
|
|
29
29
|
mdbq/redis/getredis.py,sha256=vdg7YQEjhoMp5QzxygNGx5DQKRnePrcwPYgUrDypA6g,23672
|
|
30
|
-
mdbq/redis/redis_cache.py,sha256=
|
|
30
|
+
mdbq/redis/redis_cache.py,sha256=CGNkc0kf-BCyAgakpQj4OtdPE2GIsIdQktnD00jcGCs,46329
|
|
31
31
|
mdbq/route/__init__.py,sha256=BT_dAY7V-U2o72bevq1B9Mq9QA7GodwtkxyLNdGaoE8,22
|
|
32
32
|
mdbq/route/analytics.py,sha256=dngj5hVwKddEUy59nSYbOoJ9C7OVrtCmCkvW6Uj9RYM,28097
|
|
33
|
-
mdbq/route/monitor.py,sha256=
|
|
33
|
+
mdbq/route/monitor.py,sha256=EfB948tm3WoDYVSifjk4HvYLR4mQ11i5ssk-NMnCAL0,43234
|
|
34
34
|
mdbq/route/routes.py,sha256=QVGfTvDgu0CpcKCvk1ra74H8uojgqTLUav1fnVAqLEA,29433
|
|
35
35
|
mdbq/selenium/__init__.py,sha256=AKzeEceqZyvqn2dEDoJSzDQnbuENkJSHAlbHAD0u0ZI,10
|
|
36
36
|
mdbq/selenium/get_driver.py,sha256=1NTlVUE6QsyjTrVVVqTO2LOnYf578ccFWlWnvIXGtic,20903
|
|
37
37
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
|
38
|
-
mdbq-4.2.
|
|
39
|
-
mdbq-4.2.
|
|
40
|
-
mdbq-4.2.
|
|
41
|
-
mdbq-4.2.
|
|
38
|
+
mdbq-4.2.19.dist-info/METADATA,sha256=Q8_N3EfvmZH2I1NxiZCEK3iaHtZWgmAnJAIIHWg3r1w,364
|
|
39
|
+
mdbq-4.2.19.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
|
40
|
+
mdbq-4.2.19.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
|
41
|
+
mdbq-4.2.19.dist-info/RECORD,,
|
|
File without changes
|