sycommon-python-lib 0.1.54__tar.gz → 0.1.55__tar.gz
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.
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/PKG-INFO +9 -8
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/pyproject.toml +9 -8
- sycommon_python_lib-0.1.55/src/sycommon/database/async_base_db_service.py +36 -0
- sycommon_python_lib-0.1.55/src/sycommon/database/async_database_service.py +96 -0
- sycommon_python_lib-0.1.55/src/sycommon/logging/async_sql_logger.py +65 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/logging/kafka_log.py +21 -9
- sycommon_python_lib-0.1.55/src/sycommon/logging/logger_levels.py +23 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/middleware/context.py +2 -0
- sycommon_python_lib-0.1.55/src/sycommon/middleware/traceid.py +289 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/services.py +73 -60
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/synacos/feign.py +15 -8
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/synacos/feign_client.py +24 -10
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/synacos/nacos_service.py +1 -0
- sycommon_python_lib-0.1.55/src/sycommon/tools/merge_headers.py +97 -0
- sycommon_python_lib-0.1.55/src/sycommon/tools/snowflake.py +300 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon_python_lib.egg-info/PKG-INFO +9 -8
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon_python_lib.egg-info/SOURCES.txt +5 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon_python_lib.egg-info/requires.txt +8 -7
- sycommon_python_lib-0.1.54/src/sycommon/middleware/traceid.py +0 -166
- sycommon_python_lib-0.1.54/src/sycommon/tools/snowflake.py +0 -33
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/README.md +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/setup.cfg +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/command/cli.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/__init__.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/config/Config.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/config/DatabaseConfig.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/config/EmbeddingConfig.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/config/LLMConfig.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/config/MQConfig.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/config/RerankerConfig.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/config/__init__.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/database/base_db_service.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/database/database_service.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/health/__init__.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/health/health_check.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/health/metrics.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/health/ping.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/logging/__init__.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/logging/logger_wrapper.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/logging/sql_logger.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/middleware/cors.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/middleware/docs.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/middleware/exception.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/middleware/middleware.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/middleware/monitor_memory.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/middleware/mq.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/middleware/timeout.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/models/__init__.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/models/base_http.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/models/log.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/models/mqlistener_config.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/models/mqmsg_model.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/models/mqsend_config.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/models/sso_user.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/sse/__init__.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/sse/event.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/sse/sse.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/synacos/__init__.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/synacos/example.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/synacos/example2.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/synacos/param.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/tools/__init__.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/tools/docs.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon/tools/timing.py +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
- {sycommon_python_lib-0.1.54 → sycommon_python_lib-0.1.55}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sycommon-python-lib
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.55
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
Requires-Dist: aio-pika>=9.5.8
|
|
8
8
|
Requires-Dist: aiohttp>=3.13.2
|
|
9
|
+
Requires-Dist: aiomysql>=0.3.2
|
|
9
10
|
Requires-Dist: decorator>=5.2.1
|
|
10
|
-
Requires-Dist: fastapi>=0.
|
|
11
|
-
Requires-Dist: kafka-python>=2.
|
|
11
|
+
Requires-Dist: fastapi>=0.127.0
|
|
12
|
+
Requires-Dist: kafka-python>=2.3.0
|
|
12
13
|
Requires-Dist: loguru>=0.7.3
|
|
13
14
|
Requires-Dist: mysql-connector-python>=9.5.0
|
|
14
15
|
Requires-Dist: nacos-sdk-python<3.0,>=2.0.9
|
|
15
|
-
Requires-Dist:
|
|
16
|
+
Requires-Dist: psutil>=7.1.3
|
|
17
|
+
Requires-Dist: pydantic>=2.12.5
|
|
16
18
|
Requires-Dist: python-dotenv>=1.2.1
|
|
17
19
|
Requires-Dist: pyyaml>=6.0.3
|
|
18
|
-
Requires-Dist: sqlalchemy>=2.0.
|
|
19
|
-
Requires-Dist: starlette>=0.
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist: uvicorn>=0.38.0
|
|
20
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.45
|
|
21
|
+
Requires-Dist: starlette>=0.50.0
|
|
22
|
+
Requires-Dist: uvicorn>=0.40.0
|
|
22
23
|
|
|
23
24
|
# sycommon-python-lib
|
|
24
25
|
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sycommon-python-lib"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.55"
|
|
4
4
|
description = "Add your description here"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
dependencies = [
|
|
8
8
|
"aio-pika>=9.5.8",
|
|
9
9
|
"aiohttp>=3.13.2",
|
|
10
|
+
"aiomysql>=0.3.2",
|
|
10
11
|
"decorator>=5.2.1",
|
|
11
|
-
"fastapi>=0.
|
|
12
|
-
"kafka-python>=2.
|
|
12
|
+
"fastapi>=0.127.0",
|
|
13
|
+
"kafka-python>=2.3.0",
|
|
13
14
|
"loguru>=0.7.3",
|
|
14
15
|
"mysql-connector-python>=9.5.0",
|
|
15
16
|
"nacos-sdk-python>=2.0.9,<3.0",
|
|
16
|
-
"
|
|
17
|
+
"psutil>=7.1.3",
|
|
18
|
+
"pydantic>=2.12.5",
|
|
17
19
|
"python-dotenv>=1.2.1",
|
|
18
20
|
"pyyaml>=6.0.3",
|
|
19
|
-
"sqlalchemy>=2.0.
|
|
20
|
-
"starlette>=0.
|
|
21
|
-
"
|
|
22
|
-
"uvicorn>=0.38.0",
|
|
21
|
+
"sqlalchemy[asyncio]>=2.0.45",
|
|
22
|
+
"starlette>=0.50.0",
|
|
23
|
+
"uvicorn>=0.40.0",
|
|
23
24
|
]
|
|
24
25
|
|
|
25
26
|
[tool.setuptools]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from contextlib import asynccontextmanager
|
|
2
|
+
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
|
3
|
+
from sycommon.config.Config import SingletonMeta
|
|
4
|
+
from sycommon.database.async_database_service import AsyncDatabaseService
|
|
5
|
+
from sycommon.logging.kafka_log import SYLogger
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AsyncBaseDBService(metaclass=SingletonMeta):
|
|
9
|
+
"""数据库操作基础服务类,封装异步会话管理功能"""
|
|
10
|
+
|
|
11
|
+
def __init__(self):
|
|
12
|
+
# 获取异步引擎 (假设 DatabaseService.engine() 返回的是 AsyncEngine)
|
|
13
|
+
self.engine = AsyncDatabaseService.engine()
|
|
14
|
+
|
|
15
|
+
# 创建异步 Session 工厂
|
|
16
|
+
# class_=AsyncSession 是必须的,用于指定生成的是异步会话
|
|
17
|
+
self.Session = async_sessionmaker(
|
|
18
|
+
bind=self.engine,
|
|
19
|
+
class_=AsyncSession,
|
|
20
|
+
expire_on_commit=False
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
@asynccontextmanager
|
|
24
|
+
async def session(self):
|
|
25
|
+
"""
|
|
26
|
+
异步数据库会话上下文管理器
|
|
27
|
+
自动处理会话的创建、提交、回滚和关闭
|
|
28
|
+
"""
|
|
29
|
+
async with self.Session() as session:
|
|
30
|
+
try:
|
|
31
|
+
yield session
|
|
32
|
+
await session.commit()
|
|
33
|
+
except Exception as e:
|
|
34
|
+
await session.rollback()
|
|
35
|
+
SYLogger.error(f"Database operation failed: {str(e)}")
|
|
36
|
+
raise
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
2
|
+
from sqlalchemy import text
|
|
3
|
+
|
|
4
|
+
from sycommon.config.Config import SingletonMeta
|
|
5
|
+
from sycommon.config.DatabaseConfig import DatabaseConfig, convert_dict_keys
|
|
6
|
+
from sycommon.logging.kafka_log import SYLogger
|
|
7
|
+
from sycommon.logging.async_sql_logger import AsyncSQLTraceLogger
|
|
8
|
+
from sycommon.synacos.nacos_service import NacosService
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AsyncDatabaseService(metaclass=SingletonMeta):
|
|
12
|
+
_engine = None
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
async def setup_database(config: dict, shareConfigKey: str):
|
|
16
|
+
common = NacosService(config).share_configs.get(shareConfigKey, {})
|
|
17
|
+
if common and common.get('spring', {}).get('datasource', None):
|
|
18
|
+
databaseConfig = common.get('spring', {}).get('datasource', None)
|
|
19
|
+
converted_dict = convert_dict_keys(databaseConfig)
|
|
20
|
+
db_config = DatabaseConfig.model_validate(converted_dict)
|
|
21
|
+
|
|
22
|
+
# 初始化 DatabaseConnector (传入配置)
|
|
23
|
+
connector = AsyncDatabaseConnector(db_config)
|
|
24
|
+
|
|
25
|
+
# 赋值 engine
|
|
26
|
+
AsyncDatabaseService._engine = connector.engine
|
|
27
|
+
|
|
28
|
+
# 执行异步测试连接
|
|
29
|
+
if not await connector.test_connection():
|
|
30
|
+
raise Exception("Database connection test failed")
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def engine():
|
|
34
|
+
return AsyncDatabaseService._engine
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class AsyncDatabaseConnector(metaclass=SingletonMeta):
|
|
38
|
+
def __init__(self, db_config: DatabaseConfig):
|
|
39
|
+
# 从 DatabaseConfig 中提取数据库连接信息
|
|
40
|
+
self.db_user = db_config.username
|
|
41
|
+
self.db_password = db_config.password
|
|
42
|
+
|
|
43
|
+
# 提取 URL 中的主机、端口和数据库名
|
|
44
|
+
url_parts = db_config.url.split('//')[1].split('/')
|
|
45
|
+
host_port = url_parts[0].split(':')
|
|
46
|
+
self.db_host = host_port[0]
|
|
47
|
+
self.db_port = host_port[1]
|
|
48
|
+
self.db_name = url_parts[1].split('?')[0]
|
|
49
|
+
|
|
50
|
+
# 提取 URL 中的参数
|
|
51
|
+
params_str = url_parts[1].split('?')[1] if len(
|
|
52
|
+
url_parts[1].split('?')) > 1 else ''
|
|
53
|
+
params = {}
|
|
54
|
+
for param in params_str.split('&'):
|
|
55
|
+
if param:
|
|
56
|
+
key, value = param.split('=')
|
|
57
|
+
params[key] = value
|
|
58
|
+
|
|
59
|
+
# 在params中去掉指定的参数
|
|
60
|
+
for key in ['useUnicode', 'characterEncoding', 'serverTimezone', 'zeroDateTimeBehavior']:
|
|
61
|
+
if key in params:
|
|
62
|
+
del params[key]
|
|
63
|
+
|
|
64
|
+
# 构建数据库连接 URL
|
|
65
|
+
# 注意:这里将 mysqlconnector 替换为 aiomysql 以支持异步
|
|
66
|
+
self.db_url = f'mysql+aiomysql://{self.db_user}:{self.db_password}@{self.db_host}:{self.db_port}/{self.db_name}'
|
|
67
|
+
|
|
68
|
+
SYLogger.info(f"Database URL: {self.db_url}")
|
|
69
|
+
|
|
70
|
+
# 优化连接池配置
|
|
71
|
+
# 使用 create_async_engine 替代 create_engine
|
|
72
|
+
self.engine = create_async_engine(
|
|
73
|
+
self.db_url,
|
|
74
|
+
connect_args=params,
|
|
75
|
+
pool_size=10, # 连接池大小
|
|
76
|
+
max_overflow=20, # 最大溢出连接数
|
|
77
|
+
pool_timeout=30, # 连接超时时间(秒)
|
|
78
|
+
pool_recycle=3600, # 连接回收时间(秒)
|
|
79
|
+
pool_pre_ping=True, # 每次获取连接前检查连接是否有效
|
|
80
|
+
echo=False, # 打印 SQL 语句
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# 注册 SQL 日志拦截器 (注意:SQLTraceLogger 需要支持异步引擎,或者您可能需要调整日志逻辑)
|
|
84
|
+
# 假设 SQLTraceLogger.setup_sql_logging 能够处理 AsyncEngine
|
|
85
|
+
AsyncSQLTraceLogger.setup_sql_logging(self.engine)
|
|
86
|
+
|
|
87
|
+
async def test_connection(self):
|
|
88
|
+
try:
|
|
89
|
+
# 异步上下文管理器
|
|
90
|
+
async with self.engine.connect() as connection:
|
|
91
|
+
# 执行简单查询
|
|
92
|
+
await connection.execute(text("SELECT 1"))
|
|
93
|
+
return True
|
|
94
|
+
except Exception as e:
|
|
95
|
+
SYLogger.error(f"Database connection test failed: {e}")
|
|
96
|
+
return False
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from sqlalchemy import event
|
|
2
|
+
from sqlalchemy.ext.asyncio import AsyncEngine
|
|
3
|
+
from sycommon.logging.kafka_log import SYLogger
|
|
4
|
+
import time
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from decimal import Decimal
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AsyncSQLTraceLogger:
|
|
10
|
+
@staticmethod
|
|
11
|
+
def setup_sql_logging(engine):
|
|
12
|
+
"""
|
|
13
|
+
为 SQLAlchemy 异步引擎注册事件监听器
|
|
14
|
+
注意:必须监听 engine.sync_engine,而不能直接监听 AsyncEngine
|
|
15
|
+
"""
|
|
16
|
+
def serialize_params(params):
|
|
17
|
+
"""处理特殊类型参数的序列化"""
|
|
18
|
+
if isinstance(params, (list, tuple)):
|
|
19
|
+
return [serialize_params(p) for p in params]
|
|
20
|
+
elif isinstance(params, dict):
|
|
21
|
+
return {k: serialize_params(v) for k, v in params.items()}
|
|
22
|
+
elif isinstance(params, datetime):
|
|
23
|
+
return params.isoformat()
|
|
24
|
+
elif isinstance(params, Decimal):
|
|
25
|
+
return float(params)
|
|
26
|
+
else:
|
|
27
|
+
return params
|
|
28
|
+
|
|
29
|
+
# ========== 核心修改 ==========
|
|
30
|
+
# 必须通过 engine.sync_engine 来获取底层的同步引擎进行监听
|
|
31
|
+
target = engine.sync_engine
|
|
32
|
+
|
|
33
|
+
@event.listens_for(target, "after_cursor_execute")
|
|
34
|
+
def after_cursor_execute(
|
|
35
|
+
conn, cursor, statement, parameters, context, executemany
|
|
36
|
+
):
|
|
37
|
+
try:
|
|
38
|
+
# 从连接选项中获取开始时间
|
|
39
|
+
# conn 在这里是同步连接对象
|
|
40
|
+
start_time = conn.info.get('_start_time') or \
|
|
41
|
+
conn._execution_options.get("_start_time", time.time())
|
|
42
|
+
|
|
43
|
+
execution_time = (time.time() - start_time) * 1000
|
|
44
|
+
|
|
45
|
+
sql_log = {
|
|
46
|
+
"type": "SQL",
|
|
47
|
+
"statement": statement,
|
|
48
|
+
"parameters": serialize_params(parameters),
|
|
49
|
+
"execution_time_ms": round(execution_time, 2),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# 注意:SYLogger.info 必须是线程安全的或非阻塞的,否则可能影响异步性能
|
|
53
|
+
SYLogger.info(f"SQL执行: {sql_log}")
|
|
54
|
+
except Exception as e:
|
|
55
|
+
SYLogger.error(f"SQL日志处理失败: {str(e)}")
|
|
56
|
+
|
|
57
|
+
@event.listens_for(target, "before_cursor_execute")
|
|
58
|
+
def before_cursor_execute(
|
|
59
|
+
conn, cursor, statement, parameters, context, executemany
|
|
60
|
+
):
|
|
61
|
+
try:
|
|
62
|
+
# 记录开始时间到 execution_options
|
|
63
|
+
conn = conn.execution_options(_start_time=time.time())
|
|
64
|
+
except Exception as e:
|
|
65
|
+
SYLogger.error(f"SQL开始时间记录失败: {str(e)}")
|
|
@@ -15,7 +15,7 @@ from kafka import KafkaProducer
|
|
|
15
15
|
from loguru import logger
|
|
16
16
|
import loguru
|
|
17
17
|
from sycommon.config.Config import Config, SingletonMeta
|
|
18
|
-
from sycommon.middleware.context import current_trace_id
|
|
18
|
+
from sycommon.middleware.context import current_trace_id, current_headers
|
|
19
19
|
from sycommon.tools.snowflake import Snowflake
|
|
20
20
|
|
|
21
21
|
# 配置Loguru的颜色方案
|
|
@@ -114,7 +114,7 @@ class KafkaLogger(metaclass=SingletonMeta):
|
|
|
114
114
|
trace_id = None
|
|
115
115
|
|
|
116
116
|
if not trace_id:
|
|
117
|
-
trace_id = SYLogger.get_trace_id() or Snowflake.
|
|
117
|
+
trace_id = SYLogger.get_trace_id() or Snowflake.id
|
|
118
118
|
|
|
119
119
|
# 获取线程/协程信息
|
|
120
120
|
thread_info = SYLogger._get_execution_context()
|
|
@@ -173,7 +173,7 @@ class KafkaLogger(metaclass=SingletonMeta):
|
|
|
173
173
|
"className": "",
|
|
174
174
|
"sqlCost": 0,
|
|
175
175
|
"size": len(str(message)),
|
|
176
|
-
"uid": int(Snowflake.
|
|
176
|
+
"uid": int(Snowflake.id) # 独立新的id
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
# 智能队列管理
|
|
@@ -212,7 +212,7 @@ class KafkaLogger(metaclass=SingletonMeta):
|
|
|
212
212
|
return
|
|
213
213
|
|
|
214
214
|
# 获取当前的trace_id
|
|
215
|
-
trace_id = SYLogger.get_trace_id() or Snowflake.
|
|
215
|
+
trace_id = SYLogger.get_trace_id() or Snowflake.id
|
|
216
216
|
|
|
217
217
|
# 构建错误日志
|
|
218
218
|
error_log = {
|
|
@@ -441,6 +441,18 @@ class SYLogger:
|
|
|
441
441
|
"""重置当前的 trace_id"""
|
|
442
442
|
current_trace_id.reset(token)
|
|
443
443
|
|
|
444
|
+
@staticmethod
|
|
445
|
+
def get_headers():
|
|
446
|
+
return current_headers.get()
|
|
447
|
+
|
|
448
|
+
@staticmethod
|
|
449
|
+
def set_headers(headers: list[tuple[str, str]]):
|
|
450
|
+
return current_headers.set(headers)
|
|
451
|
+
|
|
452
|
+
@staticmethod
|
|
453
|
+
def reset_headers(token):
|
|
454
|
+
current_headers.reset(token)
|
|
455
|
+
|
|
444
456
|
@staticmethod
|
|
445
457
|
def _get_execution_context() -> str:
|
|
446
458
|
"""获取当前执行上下文的线程或协程信息,返回格式化字符串"""
|
|
@@ -459,7 +471,7 @@ class SYLogger:
|
|
|
459
471
|
|
|
460
472
|
@staticmethod
|
|
461
473
|
def _log(msg: any, level: str = "INFO"):
|
|
462
|
-
trace_id = SYLogger.get_trace_id() or Snowflake.
|
|
474
|
+
trace_id = SYLogger.get_trace_id() or Snowflake.id
|
|
463
475
|
|
|
464
476
|
if isinstance(msg, dict) or isinstance(msg, list):
|
|
465
477
|
msg_str = json.dumps(msg, ensure_ascii=False)
|
|
@@ -473,7 +485,7 @@ class SYLogger:
|
|
|
473
485
|
request_log = {}
|
|
474
486
|
if level == "ERROR":
|
|
475
487
|
request_log = {
|
|
476
|
-
"trace_id": str(trace_id) if trace_id else Snowflake.
|
|
488
|
+
"trace_id": str(trace_id) if trace_id else Snowflake.id,
|
|
477
489
|
"message": msg_str,
|
|
478
490
|
"traceback": traceback.format_exc(),
|
|
479
491
|
"level": level,
|
|
@@ -481,7 +493,7 @@ class SYLogger:
|
|
|
481
493
|
}
|
|
482
494
|
else:
|
|
483
495
|
request_log = {
|
|
484
|
-
"trace_id": str(trace_id) if trace_id else Snowflake.
|
|
496
|
+
"trace_id": str(trace_id) if trace_id else Snowflake.id,
|
|
485
497
|
"message": msg_str,
|
|
486
498
|
"level": level,
|
|
487
499
|
"threadName": thread_info
|
|
@@ -521,7 +533,7 @@ class SYLogger:
|
|
|
521
533
|
@staticmethod
|
|
522
534
|
def exception(msg: any, *args, **kwargs):
|
|
523
535
|
"""记录异常信息,包括完整堆栈"""
|
|
524
|
-
trace_id = SYLogger.get_trace_id() or Snowflake.
|
|
536
|
+
trace_id = SYLogger.get_trace_id() or Snowflake.id
|
|
525
537
|
|
|
526
538
|
if isinstance(msg, dict) or isinstance(msg, list):
|
|
527
539
|
msg_str = json.dumps(msg, ensure_ascii=False)
|
|
@@ -533,7 +545,7 @@ class SYLogger:
|
|
|
533
545
|
|
|
534
546
|
# 构建包含异常堆栈的日志
|
|
535
547
|
request_log = {
|
|
536
|
-
"trace_id": str(trace_id) if trace_id else Snowflake.
|
|
548
|
+
"trace_id": str(trace_id) if trace_id else Snowflake.id,
|
|
537
549
|
"message": msg_str,
|
|
538
550
|
"level": "ERROR",
|
|
539
551
|
"threadName": thread_info
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def setup_logger_levels():
|
|
5
|
+
"""配置各模块的日志级别,抑制无关INFO/DEBUG日志"""
|
|
6
|
+
# Nacos 客户端:仅输出WARNING及以上(屏蔽INFO级的心跳/注册日志)
|
|
7
|
+
logging.getLogger("nacos.client").setLevel(logging.WARNING)
|
|
8
|
+
|
|
9
|
+
# Kafka Python客户端:屏蔽INFO级的连接/版本检测日志
|
|
10
|
+
logging.getLogger("kafka.conn").setLevel(logging.WARNING)
|
|
11
|
+
logging.getLogger("kafka.producer").setLevel(logging.WARNING)
|
|
12
|
+
|
|
13
|
+
# Uvicorn/FastAPI:屏蔽启动/应用初始化的INFO日志(保留ERROR/WARNING)
|
|
14
|
+
# logging.getLogger("uvicorn").setLevel(logging.WARNING)
|
|
15
|
+
# logging.getLogger("uvicorn.access").setLevel(logging.WARNING) # 屏蔽访问日志
|
|
16
|
+
# logging.getLogger("uvicorn.error").setLevel(logging.ERROR) # 仅保留错误
|
|
17
|
+
|
|
18
|
+
# 自定义的root日志(如同步数据库/监听器初始化):屏蔽INFO
|
|
19
|
+
logging.getLogger("root").setLevel(logging.WARNING)
|
|
20
|
+
|
|
21
|
+
# RabbitMQ相关日志(如果有专属日志器)
|
|
22
|
+
logging.getLogger("pika").setLevel(logging.WARNING) # 若使用pika客户端
|
|
23
|
+
logging.getLogger("rabbitmq").setLevel(logging.WARNING)
|