资讯详情

资讯详情

jiuwensymbiosis 日志配置实战:configure_logging 统一入口、滚动文件输出与 Trace 联动机制解析

具身智能人工智能AI Agent机器人计算机视觉Agent 编排【免费下载链接】jiuwensymbiosisJiuwen Symbiosis就是一个能懂人话、看得见物理世界、长了四肢的智能助手。用户不需要示教不需要教它怎么抓东西怎么走路就像指挥一个经验丰富的工人一样用自然语言下任务它就能自己完成感知、理解、规划、执行。项目地址https://gitcode.com/openJiuwen/jiuwensymbiosis点击查看免费下载本文以 docs/en/how-to/configure-logging.md中文基线见 docs/zh/how-to/configure-logging.md为骨架结合 jiuwensymbiosis/utils/logging.py 实现与配套测试深入展开帮助你在 jiuwensymbiosis 框架中快速接入统一日志、按需调整级别与落盘目录并理解关键日志进执行轨迹的底层机制。jiuwensymbiosis 把整个框架的日志配置收敛为唯一的入口模块jiuwensymbiosis.utils.logging一处configure_logging统一格式并可选写文件一处get_logger呼出 logger外加一个TraceLogHandler把WARNING及以上日志推入执行轨迹Trace。读完本文你将掌握如何在业务代码中记日志、如何用 YAMLagent:块或 CLI--debug控制日志级别与目录、如何把日志与 trace 联动以及这套机制在源码层面如何保证幂等、隔离与零侵入。一、快速上手用get_logger记日志1.1 在应用代码里记日志直接get_logger取一个 logger按需调用debug/info/warning/error即可from jiuwensymbiosis.utils import get_logger # 或 from jiuwensymbiosis.utils.logging import get_logger logger get_logger(__name__) logger.info(connected to CAN %s, can_port) logger.warning(target out of bounds, clamped to (%.1f, %.1f, %.1f), x, y, z) logger.error(enable timed out: %s, exc)几个关键约定get_logger(__name__)与标准库logging.getLogger(__name__)完全等价——既有logging.getLogger(__name__)调用无需改动照样享受统一配置。这是刻意设计的兼容性该模块引入之前各包文件各自logging.getLogger(__name__)格式不统一、也没有集中文件出口见 design/logging.md 的动机描述。get_logger()无参通过inspect.currentframebest-effort 探测调用方模块名对齐logging.getLogger(__name__)惯用法CPython 专属探测失败回退到jiuwensymbiosis。实现见 jiuwensymbiosis/utils/logging.py 的get_logger取frame.f_back的f_globals[__name__]拿不到就用包名兜底。日志格式全局统一整个框架走同一个 formatter%(asctime)s %(levelname)s %(name)s: %(message)s常量DEFAULT_FMT时间格式为%H:%M:%S。你不需要、也不应该自行setFormatter或basicConfig——否则会与configure_logging重复挂 handler导致控制台每条日志打印两次原因见下文handler 所有权模型。⚠️不要在模块顶层做任何全局日志配置。build_robot_agent会在合适的时机调用一次configure_logging重复配置或basicConfig会造成 handler 叠加。1.2 默认行为开箱即落盘到./logs零配置时框架日志同时输出到两处控制台stderr——一个StreamHandler统一格式不过滤jiuwensymbiosis.*和 openjiuwen 用标准库logging打的日志都会显示调试时能看全貌。文件log_dir/jiuwensymbiosis.log——RotatingFileHandler单文件 5 MB、保留 3 个备份encodingutf-8见configure_logging实现。默认log_dir./logs。只记录jiuwensymbiosis.*命名空间的日志文件 handler 上挂了_FrameworkFilter挡掉 openjiuwen 冒泡到 root 的标准库日志保持文件干净。默认./logs是刻意选择的。openjiuwen 自有日志后端因实现原因落在logs/logs/下两者独立、互不干扰logs/ ├── jiuwensymbiosis.log ← 【框架】agent / rails / 各模块日志 └── logs/ ← 【openjiuwen】自有日志后端 ├── run/jiuwen.log ← 运行日志 ├── runner.log ← runner 日志 ├── interface/jiuwen_interface.log └── performance/jiuwen_performance.log每次运行的运动产物单独成一个目录由agent.logging.motion_dir配置默认./jiuwen_motion_logjiuwen_motion_log/时间戳/ ← 每次运行一个目录 ├── commands.log ← 【框架】Piper 每次运行的命令轨迹仅 piper └── grasp_debug/ ← 【框架】检测/抓取位姿调试图det/raw/info_NNN各来源日志的归属来源落点是否进jiuwensymbiosis.logjiuwensymbiosis.*agent/rails/适配器代码logs/jiuwensymbiosis.log✅ 是Piper 命令日志 抓取调试图motion_log_dir/stamp/{commands.log, grasp_debug/}默认./jiuwen_motion_log❌每次运行独立目录openjiuwen 自有日志后端json/trace_id 那套logs/logs/run/、logs/logs/interface/、logs/logs/performance/下各文件❌绕过标准库 loggingopenjiuwen 用标准库logging打的日志如初始化时的Registered parser ...控制台可见不落jiuwensymbiosis.log❌被_FrameworkFilter挡掉简言之jiuwensymbiosis.log只存框架自己的日志openjiuwen 的日志在它自己的logs/logs/子目录里或仅控制台可见控制台则全量显示。./logs是相对当前工作目录的路径。从不同目录运行日志会落在不同位置——请固定运行目录pin the run directory。二、通过配置控制日志日志由RobotAgentConfig的logging.level/logging.dir两个字段控制最终经build_robot_agent → configure_logging生效。两种设置方式YAMLagent:块声明式推荐和CLI 参数临时覆盖。两者可叠加CLI 优先级更高。规范配置为logging.level/logging.dir/logging.motion_dir仅支持分组结构。完整默认值与约束见 Agent 全量配置。省略目录字段仍写入./logs只有显式null才关闭文件日志。2.1 YAMLagent:块声明式配置在任务配置文件如 configs/piper/piper.yaml其agent:块末尾即logging.level: INFO/logging.dir: ./logs里写agent:块agent: logging: level: INFO dir: ./logs加载链路与源码一一对应YAML → raw[agent] → RobotAgentConfig.from_dict(raw[agent]) # examples/run_task.py / jiuwensymbiosis-run → build_robot_agent(config...) → configure_logging(levelconfig.logging.level, log_dirconfig.logging.dir)RobotAgentConfig.from_dict递归合并显式覆盖_merge深合并并校验分组字段和类型_typed按注解逐字段校验。未知键会抛TypeErrorjiuwensymbiosis/agent/config.py 的_parse_settingsunknown set(data) - names后直接报unknown fields in agent.logging: [...]——拼错键如把modules.tracing.enabled写成enabld会在加载期立刻失败而不是被静默忽略。字段级校验也在validate()logging.level必须是DEBUG/INFO/WARNING/WARN/ERROR/CRITICAL/FATAL/NOTSET之一否则抛ValueError(agent.logging.level is not a logging level)。logging.level/logging.dir字段定义于LoggingConfigdataclass字段默认说明logging.levelINFO根 logger 级别logging的 level 名字符串经_to_level转成 int只接受已知级别名非法值抛错logging.dir./logs日志文件目录None/null 仅控制台。默认./logsopenjiuwen 日志因其实现落在logs/logs/与本目录独立logging.motion_dirnull生效为./jiuwen_motion_log每次运行运动产物的根目录RobotAgentConfig.prepare_session会把该值写到session.motion_log_dirRobotSession.connect()时经begin_run建立root/stamp运行目录关掉文件落盘仅控制台agent: logging: dir: null调到 DEBUG 抓更详细日志agent: logging: level: DEBUG dir: ./logs2.2 CLI 参数覆盖demo 临时调级examples/run_task.py 提供--debug通过RobotAgentConfig.from_dict(..., overrides...)把logging.level改成DEBUG优先级高于 YAMLoverrides {logging: {level: DEBUG}} if args.debug else {} agent_cfg RobotAgentConfig.from_dict(raw.get(agent), overridesoverrides) result run_robot_task(session, args.query, agent_cfg)# 临时看 DEBUG 级日志覆盖 YAML 的 logging.level不必改配置文件 python examples/run_task.py --config configs/piper/piper.yaml --mock --debug关于basicConfig的一个细节需要澄清demo 的main()在开头确实调了一次logging.basicConfig(level..., formatDEFAULT_FMT)这是为了让语音监听阶段首次 agent 构建之前的 INFO 日志可见随后build_robot_agent → configure_logging接管根 logger。要点在于不要在应用代码里对全局日志做二次配置basicConfig会另挂一个configure_logging不认识的 handler导致控制台重复打印机制见 §3.5。2.3 与执行轨迹trace联动日志还能进入执行轨迹modules.tracing.enabled开启时。相关配置在agent:块里详见 执行轨迹参考agent: modules: tracing: enabled: true capture_loggers: [jiuwensymbiosis]capture_loggers默认就是[jiuwensymbiosis]见TracingConfig即jiuwensymbiosis.*命名空间下任何WARNING及以上的记录都会被捕获。工具步骤执行期间产生的记录会出现在该步骤entry的log_events里没有活跃步骤时出现在 trace 级trace_log中见 jiuwensymbiosis/agent/trace.py 的ExecutionTrace.record_log_event分发逻辑。三、API 与机制参考3.1configure_logging(levelINFO, *, log_dirNone, fmtDEFAULT_FMT)幂等地配置根 logger。普通开发者通常不直接调用——build_robot_agent会替你调见 jiuwensymbiosis/agent/builder.py 中_build_agent的configure_logging(levelconfig.logging.level, log_dirconfig.logging.dir)。仅在你脱离build_robot_agent独立使用框架时才手动调一次from jiuwensymbiosis.utils.logging import configure_logging configure_logging() # 控制台 默认行为 configure_logging(levelDEBUG, log_dir/var/log/js) # 控制台 指定目录的文件 configure_logging(levelINFO, log_dirNone) # 仅控制台关闭文件幂等机制每个由本模块创建的 handler 都被打上_OWNED_TAG _jiuwensymbiosis_owned标记setattr(handler, _OWNED_TAG, True)。重复调用时StreamHandler存在则只更新 formatter不新增。FileHandlerlog_dir从无→有则新增并挂_FrameworkFilter从有→无则移除并关闭旧的从一个非空路径直接换到另一个非空路径不会替换已有 handler。需要先configure_logging(log_dirNone)再传新路径或重启进程。configure_logging(level, log_dir) │ ├─ root.setLevel(int_level) ├─ _owned_handlers() 为空 │ ├─ 是 → 新建 StreamHandler不过滤打 _OWNED_TAG加到 root │ └─ 否 → 更新已有 owned handler 的 formatter └─ log_dir 给定 ├─ 是 且 无 owned FileHandler → 新建 RotatingFileHandler(5MB, 3 backup, utf-8) │ 挂 _FrameworkFilter只放行 jiuwensymbiosis.* └─ 否 且 有 owned FileHandler → 移除并 close配套单元测试 tests/unit_tests/utils/test_logging.py 直接验证了这些约束test_idempotent_no_duplicate_handlers断言重复调用后 root handler 数量不变test_file_handler_written_when_log_dir_given验证jiuwensymbiosis.*命名空间的日志确实写入dir/jiuwensymbiosis.logtest_uses_uniform_format只挑选带_owned标记的 handler 检查格式说明测试也依赖所有权标记来区分 pytest 注入的捕获 handler。文件 handler 的过滤范围_FrameworkFilter只加在RotatingFileHandler上不加在 StreamHandler 上——所以jiuwensymbiosis.log只存框架自己的日志而控制台仍显示 openjiuwen 等全部来源调试时看全貌。_FrameworkFilter.filter按 logger 名的点号前缀匹配jiuwensymbiosis与jiuwensymbiosis.agent都放行openjiuwen.*、common、alembic等一律丢弃。openjiuwen 自有的日志后端写logs/run/等根本不走标准库 logging不受此影响。额外健壮性_Formatter在record.msg无法正常格式化时抛ValueError/TypeError/KeyError回退到repr(record.msg)保证异常消息不会击穿日志路径对应测试test_formatter_repr_fallback_on_bad_record_to_level对未知级别名回退到logging.INFO。3.2get_logger(nameNone)logging.getLogger的薄封装留作未来加结构化字段的单一入口。无参时探测调用方模块名见 §1.1。jiuwensymbiosis/utils/__init__.py中 re-export 了configure_logging/get_logger/TraceLogHandler/DEFAULT_FMT因此两种导入路径都可使用。3.3TraceLogHandler把 WARNING 推入 trace把WARNING 的日志记录转发给一个绑定的 trace sink通常是TraceRail。这是关键日志进 trace的实现核心——只要把 handler 挂到对应 logger 上业务模块里既有的logger.warning(...)就自动成为 trace 的log_events无需改业务代码from jiuwensymbiosis.utils.logging import TraceLogHandler handler TraceLogHandler(sinktrace_rail, levellogging.WARNING) logging.getLogger(jiuwensymbiosis).addHandler(handler) # 此后 jiuwensymbiosis.* 下任何 logger.warning(...) 都会进入 trace捕获级别固定WARNING在build_robot_agent里硬编码capture_log_level_logging.WARNING见 jiuwensymbiosis/agent/builder.py 的_attach_trace_log_handlers调用处不开放配置。理由见 design/logging.md。emit 行为sink is None时 no-op可提前构造否则组装{logger, level, msg, ts}调sink.record_log_event(...)sink 异常被精确类型(AttributeError, TypeError, ValueError)吞掉——日志 handler 绝不能抛。对应测试test_no_sink_does_not_raise与test_bad_sink_does_not_raise。生命周期由TraceRail管理见 design/tracing.md 与 jiuwensymbiosis/agent/trace.pyset_sink(sink)切换 sink——before_invoke开始时绑回 TraceRail 自身、finalize/after_invoke结束后置Nonedetach_log_handler在 Session 结束时把 handler 从所有目标 logger 移除避免长进程中 handler 泄漏。builder 在挂载前还会先清除旧的TraceLogHandler实例保证重复build_robot_agent不累积无操作 handler。注意若 warnings 未出现在 trace 中请依次确认modules.tracing.enabled为true、modules.tracing.capture_loggers覆盖了对应 logger 前缀且记录级别至少为WARNING。此外RobotAgentConfig.validate()还会强制modules.diagnosis.enabled必须伴随modules.tracing.enabled诊断 rail 依赖 TraceRail 读取活跃 trace。3.4 常量常量值用途DEFAULT_FMT%(asctime)s %(levelname)s %(name)s: %(message)s默认 formatter 格式_OWNED_TAG_jiuwensymbiosis_owned标记本模块创建的 handler用于幂等识别_FrameworkFilterlogging.Filter子类_PREFIX jiuwensymbiosis只放行jiuwensymbiosis.*记录挂在文件 handler 上使jiuwensymbiosis.log不混入 openjiuwen 日志3.5 handler 所有权模型模块通过_OWNED_TAG区分自己创建的 handler与外部pytest、应用代码注入的 handlerroot.handlers [ StreamHandler(_ownedTrue) ← 不过滤控制台全量显示 RotatingFileHandler(_ownedTrue, _FrameworkFilter) ← 只记 jiuwensymbiosis.* LogCaptureHandler ← pytest 注入configure_logging 不碰 ]这保证了configure_logging不会误删 pytest 的日志捕获 handler_owned_handlers()只按_OWNED_TAG筛选。重复调用不会堆叠 owned handler幂等性测试test_idempotent_no_duplicate_handlers覆盖。log_dir启停时只动 owned FileHandler非空路径之间的切换需先显式关闭旧 handler。选择显式管理 handler 标记而不是logging.config.dictConfig是为了保留宿主应用的日志配置并让重复构建不叠加这一约束可直接用标记实现和测试见 design/logging.md §3.1。四、每次运行的独立产物目录begin_run/current_run_dir除常规框架日志外每次运行的运动产物Pipercommands.log与抓取调试grasp_debug/共享同一个按时间戳命名的运行目录由begin_run/current_run_dir提供begin_run(root)建立root/stampstamp 形如2026-08-10_14-30-05同一秒内两次运行自动加后缀stamp-2…区分目录惰性创建——一次运行什么都没写就不会留下空目录。RobotSession.connect()jiuwensymbiosis/agent/session.py在 env 驱动挂载命令日志之前调用begin_run(self.motion_log_dir or ./jiuwen_motion_log)使同一运行的所有运动产物归入一个文件夹current_run_dir()在未经过 connect 的临时脚本里惰性回退到默认根。Piper 侧jiuwensymbiosis/adapters/piper/lowlevel.py 的_attach_cmd_log_handler把current_run_dir() / commands.log作为真机命令轨迹文件复用统一格式DEFAULT_FMT与_OWNED_TAG机制可用环境变量关闭或重定向JIUWEN_PIPER_CMD_LOG0关闭命令日志JIUWEN_GRASP_DEBUG_DIRdir覆盖抓取调试图目录jiuwensymbiosis/perception/vision.py 的_default_debug_dir默认per-run dir/grasp_debug检测产物从001起编号raw_NNN.jpg/depth_NNN.npy/ 检测叠加图与 JSON 快照。对应测试见 tests/unit_tests/utils/test_logging.py 的TestPerRunDirstamp 命名、同秒去重、惰性创建等。五、相关文件文件角色jiuwensymbiosis/utils/logging.py集中日志模块实现configure_logging/get_logger/TraceLogHandler/begin_run/current_run_dirjiuwensymbiosis/utils/init.pyre-exportconfigure_logging/get_logger/TraceLogHandler/DEFAULT_FMTjiuwensymbiosis/agent/config.pyLoggingConfiglevel/dir/motion_dir与RobotAgentConfig.from_dictYAML 透传、未知键报错、级别白名单校验jiuwensymbiosis/agent/builder.pybuild_robot_agent调configure_loggingtracing 开启时挂TraceLogHandlercapture_log_levelWARNING并交由TraceRail管理生命周期jiuwensymbiosis/agent/trace.pyTraceRail与ExecutionTracerecord_log_event分发到步骤log_events或 trace 级trace_logjiuwensymbiosis/agent/session.pyRobotSession.connect()经begin_run建立每次运行的产物目录motion_log_direxamples/run_task.py--debug覆盖logging.level演示 YAMLagent:块加载链路jiuwensymbiosis/adapters/piper/lowlevel.pyPiper_attach_cmd_log_handler复用统一格式与运行目录jiuwensymbiosis/perception/vision.pydump_grasp_debug把检测/抓取调试图写入per-run dir/grasp_debugdesign/logging.md日志模块设计文档所有权、幂等、隔离、生命周期与一致性约束docs/zh/reference/agent-config.mdAgent 全量配置参考含logging字段默认值与校验规则tests/unit_tests/utils/test_logging.py幂等性、文件输出、_FrameworkFilter、TraceLogHandler与运行目录的单元测试六、排查速查表症状排查方向控制台每条日志打印两次宿主应用/代码里另有basicConfig()或手动addHandler叠加了 handler只应让configure_logging管理根 loggerjiuwensymbiosis.log为空而控制台有输出确认logging.dir非null、写入的 logger 名以jiuwensymbiosis开头_FrameworkFilter会挡掉其他命名空间换logging.dir后文件没变非空路径间的切换不会替换已有 FileHandler先configure_logging(log_dirNone)再传新路径或重启进程warnings 没进 trace依次确认modules.tracing.enabled、modules.tracing.capture_loggers覆盖目标 logger、记录级别 ≥WARNING真机 Piper 命令轨迹缺失检查JIUWEN_PIPER_CMD_LOG是否被设为0以及是否经过RobotSession.connect()建立了运行目录赞分享具身智能人工智能AI Agent机器人计算机视觉Agent 编排【免费下载链接】jiuwensymbiosisJiuwen Symbiosis就是一个能懂人话、看得见物理世界、长了四肢的智能助手。用户不需要示教不需要教它怎么抓东西怎么走路就像指挥一个经验丰富的工人一样用自然语言下任务它就能自己完成感知、理解、规划、执行。项目地址https://gitcode.com/openJiuwen/jiuwensymbiosis点击查看免费下载相关推荐astron-agent Trace 日志配置解析TraceLogs Config 的统一入口、类型体系与时间/树形处理机制astron agent Trace 日志配置解析TraceLogs Config 的统一入口、类型体系与时间/树形处理机制 在 astron agent 的人工智能AI AgentAgent 工作流RPA后端前端工具调用Dropwizard日志Appender配置控制台与文件输出Dropwizard日志Appender配置控制台与文件输出 在开发和运维过程中日志是排查问题、监控系统运行状态的重要依据。Dropwizard提供了灵活的后端Web框架PMD 日志机制深度解析基于 SLF4J 的统一日志体系与配置实战PMD 日志机制深度解析基于 SLF4J 的统一日志体系与配置实战 PMD 是采用可扩展多语言架构的静态代码分析器其内部所有日志统一通过 SLF4J 门面静态分析代码质量上一篇Alchemy 框架使用教程下一篇Social-Analyzer 教程在 1000 社交媒体网站中快速定位一个用户名的注册踪迹创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →