故障排查
先确认失败发生在哪一步:安装、加载配置、读取输入、计算、读取结果或发布。保留完整异常链;CLI默认文字报告便于定位,validate/explain --format json用于程序读取。以下处理不会要求修改原始日志或覆盖既有结果。
Python调用:按失败阶段处理
PlanValidationError.diagnostics包含本次可确认的错误,单错也是一项;blocked_checks说明因无效依赖暂未检查的部分。每项同时保存path、message、code。path是配置字段位置,source是文件路径;二者不可混用。只打印$.batch_version不够判断问题,应保留message中的实际约束及code,存在时再展示行列与hint。
from chronaxis import load_analysis_plan, PlanValidationError
try:
plan = load_analysis_plan("analysis.yaml")
except PlanValidationError as error:
for item in error.diagnostics:
print(item.source, item.path, item.code, item.message, item.hint)
print(error.blocked_checks)
raise # 保留原始异常链;不要把加载失败当成空计划继续运行| 阶段 | 常见错误/结果 | 调用者应做什么 |
|---|---|---|
| 加载或构造 | PlanValidationError,含unknown_field等机器code | 根据path/message修正配置;有source/location时一同定位 |
| 静态检查 | ValidationReport.errors或execution_ready=False | 处理报告;validate不代表输入文件已读取 |
| 运行 | AnalysisError;exc.__cause__可能为SourceReadError、BudgetExceededError、ValueError等,也可能为None |
保留异常链,按读取/资源/表达式原因修正;不要吞成无事件 |
| 流式读结果 | ResultClosedError、ContributionsUnavailableError或暂存读取错误 | 在结果仍打开时读;缺贡献需要重新请求full运行 |
| 发布 | AnalysisError及其exc.__cause__,例如路径不是目录或文件写入失败;原因链可能为None |
检查结果目录写入权限并修正环境;结果未关闭时可重新发布,无需重读输入 |
| 批量 | 正常返回也可能有failed任务;基础设施异常可能带batch_report | 查jobs中的error_type/error_message/error_chain;保留已完成结果,对cleanup_pending调用close |
| 关闭 | 实际文件/资源关闭错误 | 保留结果或异常提供的清理对象,解除占用后重试close |
下面的片段接前面的plan加载代码。捕获运行或发布异常后,通过exc.__cause__读取被包装的原始异常;直接抛出的错误可能没有包装原因,此时为None。AnalysisError没有承诺名为cause或diagnostics的统一属性,详见AnalysisRunner异常说明。
from chronaxis import AnalysisRunner, AnalysisError
try:
with AnalysisRunner().run(plan) as result:
result.write("results")
except AnalysisError as exc:
print(type(exc).__name__, str(exc))
if exc.__cause__ is not None:
print(type(exc.__cause__).__name__, str(exc.__cause__))
raise # 保留异常链,不把失败当作空结果KeyboardInterrupt/SystemExit表示取消,不应作为成功返回。异常链上的runner_cleanup_owner或analysis_result_cleanup_owner只在失败清理未完成时出现;检查属性存在后才调用其close,不假定每个错误都有这些属性。
环境与配置
计算项缺少operation时,先补计算方法。程序明确方法后才检查该方法需要的字段,不会要求你补其他方法才使用的rule、window或q。其他独立字段的错误仍会一并报告。
condition_duration缺少duration_comparison时,请按业务选择:">="包含恰好达到门槛的活动,">"要求严格超过。
| 现象或错误 | 原因与检查 | 修正动作 |
|---|---|---|
| No module named chronaxis | 当前解释器未安装项目,或编辑安装目录已移动 | 使用安装时的Python,按安装页重新安装当前源码目录。 |
| 找不到numpy、ruamel.yaml或CAN模块 | 依赖装在其他环境,或安装时跳过了依赖 | 在运行任务的同一Python环境重新安装chronaxis;CAN依赖随正常安装提供。 |
PlanValidationError,路径如$.signals[0].source |
字段缺失、类型不符或引用名称不存在 | 按source/行列/字段路径检查;source应等于sources[].name,不填文件路径。 |
| 重复键、未知字段或旧版本错误 | 配置结构不符合当前规则 | 合并重复映射,核对大小写与拼写;分析配置只接受整数4;旧配置须按当前字段和单位规则迁移,不能只改版本数字。见配置版本。 |
| YAML锚点/别名/标签被拒绝 | 当前语法不支持这些功能 | 使用普通映射/列表;共享定义采用imports。 |
unit: 1被拒绝 |
YAML将1解析为数字,单位要求字符串 | 无量纲写unit: '1';只有确需显式指定预设版本时才写version: '1',通常省略。 |
| 表达式不合法 | 使用原始列名、Python任意函数或不允许的属性路径 | 先在signals绑定name,再按表达式语法填写;YAML true与表达式True属于不同层。 |
文件、时间与解码
| 现象 | 检查步骤 | 修正动作 |
|---|---|---|
| 配置校验通过但run提示文件/列不存在 | 静态检查没有读取业务文件;相对路径以声明文件目录为起点 | 用config origins查看声明位置;核对path、time_column、field的实际拼写。 |
| 连续文件时间回退 | 后一个文件从0重新计时,或paths顺序错误 | 只有连续试验才放在同一来源;根据已知起点明确offset/offsets,不能任意增加时间掩盖回退。 |
| 两来源不能联合计算 | time.time_type/time.clock/单位或偏移不能证明同一时刻 | 使用真实同步依据设置共同时间基准,见时间同步。 |
| CAN报文不能解码 | 通道、标准/扩展帧、FD标志、ID或DBC定义不相符 | 核对field中的channel、frame_id、signal和DBC映射;帧型通常自动识别,提示歧义时才补充is_extended或is_fd。再检查实际帧长度。 |
| ASC或原始CSV格式错误 | reader.version、列映射、分隔符或时间格式与文件不一致 | 对照文本CAN输入;结构错误不能靠partial解码策略跳过。 |
结果为空或不完整
| 结果 | 如何解释与检查 | 后续动作 |
|---|---|---|
| value为空 | 查看operation、scope、status、reason、quality;没有样本、零长度、全未知和strict拒绝均可能为空 | 先确认请求范围与观测范围,再检查信号valid_for、无效值、条件。不要改成0掩盖原因。 |
| status=partial | 只算出所需范围内可确认的部分 | 对照部分结果判断是否接受;调整policy不会补回原始观测。 |
| 没有事件 | 条件未持续够久、没有已知边沿、有效期不足或阈值/单位错误 | 检查规则类型和minimum_duration/emit_initial;用小段可手算数据复现。 |
| 请求配对indeterminate | 等待期间条件未知,或观测提前结束 | 核对响应来源覆盖与valid_for,不能直接报告设备无响应。 |
| 覆盖字段缺失 | minimum_coverage省略或为0,或操作不属于相关时间统计 | 查看实际行模型;公开摘要不提供三个数值覆盖率。 |
| ContributionsUnavailableError | 运行时未保存逐消息贡献 | 确有需要时设outputs.contributions: full并重新运行。 |
| iter_input_trace报AnalysisError | 未开启输入追溯 | 设diagnostics.trace: true后重新运行;它不等于全日志备份。 |
| ResultClosedError | 结果或游标已关闭/正在关闭 | 在AnalysisResult的with范围内完成读取;游标用try/finally显式close,不支持直接对游标使用with。 |
资源与发布
| 错误 | 原因与处理 |
|---|---|
| BudgetExceededError | 按异常资源项区分内存、结果缓冲或暂存磁盘;可减小batch_rows/result_buffer_rows,或在确认资源足够后调整对应配额。状态本身需要的内存未必随批次减小。 |
| 输出路径不可用 | 已有目录可以复用;若该路径是文件、不可写或位于受保护位置,选择可写目录。程序用时间后缀避免覆盖旧文件。 |
| 发布目录位于自有工作目录内 | 默认close会清理该工作目录;把正式输出放在工作目录外。 |
| 平台能力不足导致运行或发布失败 | 查看原异常链。Linux 实际启动受管工作进程需要 pidfd 进程组信号;结果发布需要 renameat2、目标文件系统支持 RENAME_NOREPLACE,且移动在同一文件系统。普通/fast静态校验只对实际需要受管工作进程的路径检查当前能力,并把无法确认或不可用的原因放入warnings;独立批量在派发前发出Python告警。这些提示不改变配置有效性。发布的EINVAL也可能来自无效的源/目标组合或参数,不能仅凭此错误认定文件系统不支持。按安装说明核对失败阶段和已验证环境;实际启动及发布仍会检查。 |
| metadata.device_label校验失败 | 省略该字段即可使用pending;需要记录设备时填写非空文本,如lab-pc或试验台一号。空值、全空白及非字符串无效,见导出说明。 |
| 暂存格式损坏或读取OSError | 停止使用该结果,保留异常及必要现场,检查文件访问和磁盘;不要吞掉异常当作空表。 |
| 批量返回报告但部分任务失败 | 查看CLI返回report路径中的每个任务的状态、错误与输出路径;修正失败项后独立重跑,同目录重跑会生成另一批时间文件名。 |
需要保留现场时,在下一次复现配置中设置diagnostics.retain_work: true;需要输入位置时再单独开启trace。记录配置、命令、错误链、运行清单和可共享的最小合成输入,以便重现。
高性能积分器的会话失败
fast run的任一分卷失败都会终止本次会话,不发布正常成功汇总。先用fast validate或fast explain检查配置;它们不代替实际读取验证。
| 现象 | 检查与处理 |
|---|---|
| 进程数无效或嵌套进程被拒绝 | execution.process_count填写正整数;独立batch模板内省略该字段或填1,批量并发在根级process_count设置。 |
| 目标报文时间回退 | 核对文件时间、通道和目标ID。time_order检查各分卷目标候选报文,范围外记录也检查;不要通过平移时间或去重隐藏问题。 |
| 必要暂存额度不足 | time_order多文件归并需要暂存全部贡献。根据输入规模提高execution.spool_quota_bytes及可用磁盘;删除已读暂存不返还累计额度。 |
| 后续文件预读暂停 | concatenate模式的可选预读额度不足时暂停,轮到该文件后直接读取;通常只影响速度。实际写盘失败仍会终止会话。 |
| 贡献块缺失、损坏、重复或worker退出 | 保留完整异常链,核对磁盘和进程环境后重新运行;不使用残留文件作为完整结果。 |
| Python主动取消 | cancel_event.set()后run抛InterruptedError;本次进程和暂存会回收,不发布成功清单。 |
字段默认值、可运行配置和状态解释见高性能积分器。