sdpy-kit 0.4.0__tar.gz → 0.4.1__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.
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/PKG-INFO +1 -1
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/__init__.py +1 -1
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/config/log_config.py +42 -5
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/.gitignore +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/README.md +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/__init__.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/base_service.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/chat_service.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/embedding_service.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/exceptions.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/failover.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/image_service.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/model_builder.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/model_client.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/pool.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/profiles.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/rerank_service.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/runner.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/ai/types.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/anydoc_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/common_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/config/__init__.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/config/kit_config.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/crawl/__init__.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/crawl/article_models.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/crawl/web_article_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/crawl/wx_article_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/__init__.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/base_db_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/crud.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/engine.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/exceptions.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/models/__init__.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/models/base.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/mysql_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/pg_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/query.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/session.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/sqlite_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/db/transaction.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/docx_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/file_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/laya_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/marker_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/md2doc_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/mineru_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/kit/redis_kit.py +0 -0
- {sdpy_kit-0.4.0 → sdpy_kit-0.4.1}/pyproject.toml +0 -0
|
@@ -24,6 +24,7 @@ Author: Clark Chang
|
|
|
24
24
|
import logging
|
|
25
25
|
import os
|
|
26
26
|
import sys
|
|
27
|
+
import threading
|
|
27
28
|
from logging.handlers import RotatingFileHandler
|
|
28
29
|
|
|
29
30
|
from kit.config.kit_config import get_settings
|
|
@@ -49,6 +50,43 @@ def ensure_log_dir(log_dir: str) -> None:
|
|
|
49
50
|
os.makedirs(log_dir, exist_ok=True)
|
|
50
51
|
|
|
51
52
|
|
|
53
|
+
# 同一日志文件路径共享单例文件 handler:
|
|
54
|
+
# 进程内该文件仅一个句柄,避免 Windows 下多句柄占用导致轮转必失败(WinError 32)。
|
|
55
|
+
# 参数策略 first-wins:maxBytes / backupCount / formatter 以首个创建者为准。
|
|
56
|
+
_file_handlers: dict[str, RotatingFileHandler] = {}
|
|
57
|
+
_file_handlers_lock = threading.Lock()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _file_handler_cache_key(log_file_path: str) -> str:
|
|
61
|
+
"""计算共享 handler 缓存 key(归一 Windows 大小写、分隔符与相对路径)"""
|
|
62
|
+
return os.path.normcase(os.path.abspath(log_file_path))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _get_shared_file_handler(
|
|
66
|
+
log_file_path: str, max_bytes: int, backup_count: int, formatter: logging.Formatter
|
|
67
|
+
) -> RotatingFileHandler:
|
|
68
|
+
"""获取指定日志文件路径的共享文件 handler(不存在则创建)"""
|
|
69
|
+
key = _file_handler_cache_key(log_file_path)
|
|
70
|
+
with _file_handlers_lock:
|
|
71
|
+
handler = _file_handlers.get(key)
|
|
72
|
+
if handler is None:
|
|
73
|
+
handler = RotatingFileHandler(
|
|
74
|
+
log_file_path,
|
|
75
|
+
maxBytes=max_bytes,
|
|
76
|
+
backupCount=backup_count,
|
|
77
|
+
encoding="utf-8",
|
|
78
|
+
)
|
|
79
|
+
handler.setFormatter(formatter)
|
|
80
|
+
_file_handlers[key] = handler
|
|
81
|
+
return handler
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _reset_file_handlers() -> None:
|
|
85
|
+
"""复位共享 handler 缓存(仅供测试隔离使用,不进 __all__)"""
|
|
86
|
+
with _file_handlers_lock:
|
|
87
|
+
_file_handlers.clear()
|
|
88
|
+
|
|
89
|
+
|
|
52
90
|
def setup_logger(
|
|
53
91
|
name: str | None = None,
|
|
54
92
|
log_level: str | None = None,
|
|
@@ -77,13 +115,12 @@ def setup_logger(
|
|
|
77
115
|
if settings.LOG_TO_FILE:
|
|
78
116
|
ensure_log_dir(settings.LOG_DIR)
|
|
79
117
|
log_file_path = log_file or os.path.join(settings.LOG_DIR, settings.LOG_FILE)
|
|
80
|
-
file_handler =
|
|
118
|
+
file_handler = _get_shared_file_handler(
|
|
81
119
|
log_file_path,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
120
|
+
max_bytes=max_bytes,
|
|
121
|
+
backup_count=backup_count,
|
|
122
|
+
formatter=formatter,
|
|
85
123
|
)
|
|
86
|
-
file_handler.setFormatter(formatter)
|
|
87
124
|
logger.addHandler(file_handler)
|
|
88
125
|
|
|
89
126
|
return logger
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|