fix(logging): use space-separated timestamps in unified log (1.2.12)
All checks were successful
Publish Python Package to Gitea / publish (push) Successful in 16s

Replace ISO T with YYYY-MM-DD HH:MM:SS so runtime log UI can wrap and display cleanly.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-15 14:09:25 +08:00
parent c9f5c37af8
commit 28abd3509a
4 changed files with 23 additions and 2 deletions

View File

@@ -278,6 +278,8 @@ print(runtime_diagnostics_dict(diag)) # 可 JSON 序列化
诊断只读探测本地状态,不会触发 media-assets 下载。 诊断只读探测本地状态,不会触发 media-assets 下载。
自 **1.2.12** 起,统一文件日志 `jiangchang.log` 的时间戳为 `YYYY-MM-DD HH:MM:SS`(空格分隔,不再使用 ISO 的 `T`)。宿主运行日志解析需同时兼容新旧两种格式。
自 **1.2.11** 起,`runtime_diagnostics_dict` 额外包含只读字段 `machine_power`(AC 供电 / 可选 nvidia-smi 限频信息)。探不到则 `probed=false`,**不会**因此把 health 标为 fatal。 自 **1.2.11** 起,`runtime_diagnostics_dict` 额外包含只读字段 `machine_power`(AC 供电 / 可选 nvidia-smi 限频信息)。探不到则 `probed=false`,**不会**因此把 health 标为 fatal。
### RPA 有界就绪等待与启动超时(1.2.11+) ### RPA 有界就绪等待与启动超时(1.2.11+)

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "jiangchang-platform-kit" name = "jiangchang-platform-kit"
version = "1.2.11" version = "1.2.12"
description = "匠厂平台共享组件:Skill 实体 SDK + 桌面应用自动化 SDK + 桌面 UIA 暖树" description = "匠厂平台共享组件:Skill 实体 SDK + 桌面应用自动化 SDK + 桌面 UIA 暖树"
readme = "README.md" readme = "README.md"
requires-python = ">=3.10" requires-python = ">=3.10"

View File

@@ -87,7 +87,7 @@ class _SkillContextFilter(logging.Filter):
_FORMAT = ( _FORMAT = (
"%(asctime)s | %(levelname)-8s | %(trace_id)s | %(skill_slug)s | %(name)s | %(message)s" "%(asctime)s | %(levelname)-8s | %(trace_id)s | %(skill_slug)s | %(name)s | %(message)s"
) )
_DATEFMT = "%Y-%m-%dT%H:%M:%S" _DATEFMT = "%Y-%m-%d %H:%M:%S"
def _log_level_from_env() -> int: def _log_level_from_env() -> int:

View File

@@ -45,6 +45,25 @@ class TestUnifiedLogging(unittest.TestCase):
self.assertFalse(any(isinstance(h, TimedRotatingFileHandler) for h in handlers)) self.assertFalse(any(isinstance(h, TimedRotatingFileHandler) for h in handlers))
self.assertTrue(any(isinstance(h, logging.NullHandler) for h in handlers)) self.assertTrue(any(isinstance(h, logging.NullHandler) for h in handlers))
def test_log_timestamp_uses_space_not_iso_t(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
log_path = os.path.join(tmp, "skill.log")
logger_name = "test.logger.datefmt"
with patch.object(ul, "get_skill_log_file_path", return_value=log_path):
ul.setup_skill_logging("receive-order", logger_name)
ul.get_skill_logger().info("hello-datefmt")
ul._clear_logger_handlers(logging.getLogger(logger_name))
with open(log_path, encoding="utf-8") as f:
text = f.read()
self.assertRegex(
text,
r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \|",
)
self.assertNotRegex(
text,
r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2} \|",
)
def test_attach_unified_file_handler_unwritable(self) -> None: def test_attach_unified_file_handler_unwritable(self) -> None:
logger_name = "test.logger.attach.unwritable" logger_name = "test.logger.attach.unwritable"
with patch.object(ul, "_can_open_log_file", return_value=(False, "permission denied")): with patch.object(ul, "_can_open_log_file", return_value=(False, "permission denied")):