ecFlow笔记:ecFlow日志解析 - child 命令记录
本文属于介绍 NWPC 工作流日志工具的系列文章。
之前的文章《ecFlow笔记:ecFlow日志解析 - 通用字段》介绍如何解析 ecFlow 日志的通用字段。
本文介绍如何解析 child 命令记录(ChildLogRecord
)类型的 ecFlow 日志条目。
本文代码均来自 nwpc-oper/nwpc-workflow-log-model 项目。
介绍
ecFlow 服务并不负责监控任务的运行状态,而是要求任务自身将运行状态告知给 ecFlow 服务,这就需要使用到 child 命令。
child 命令是 ecflow_client
的一组子命令,主要用于实现任务脚本与 ecFlow 服务之间的通讯,修改 ecFlow 服务中与某个任务节点相关的属性。
目前,NWPC 的数值预报业务系统中使用的 child 命令主要包括以下两种类型:
- 修改任务节点状态:
init
,complete
和abort
,命令调用不需要额外的参数,全部由环境变量指定 - 修改任务节点的属性子节点:
event
,meter
和label
,任务节点可能有多个同一类的属性子节点,所以命令调用时需要指定属性的名称
child 命令示意图如下所示:
示例
下面举例说明各个命令的日志。
init
init 命令用于告知 ecFlow 服务任务已实际开始运行。
执行 init
命令后,节点状态会变为 active
。
MSG:[13:25:26 14.5.2020] chd:init /grapes_emer_v1_2/00_2/upload/upload_plot_ty
LOG:[13:25:26 14.5.2020] active: /grapes_emer_v1_2/00_2/upload/upload_plot_ty
complete
complete 命令用于告知 ecFlow 服务任务已经正常结束。
执行 complete
命令后,节点状态会变为 complete
。
MSG:[13:25:27 14.5.2020] chd:complete /grapes_emer_v1_2/00_2/typhoon/check_plot_typhoon
LOG:[13:25:27 14.5.2020] complete: /grapes_emer_v1_2/00_2/typhoon/check_plot_typhoon
abort
abort 命令用于告知 ecFlow 服务任务运行出错。调用 abort
命令是可以附带出错原因。
执行 abort
命令后,节点状态会变为 aborted
。
如果任务节点配置了自动重新运行,那么 ecFlow 会根据当前的 try no 确定是否自动重新提交该任务。
MSG:[23:13:17 14.5.2020] chd:abort /meso_post/21/uploadAll/upload_chartos/3h/conv_prep_3hr/upload_conv_prep_3hr_011 trap
LOG:[23:13:17 14.5.2020] aborted: /meso_post/21/uploadAll/upload_chartos/3h/conv_prep_3hr/upload_conv_prep_3hr_011 try-no: 1 reason: trap
event
event 命令设置属于某个节点的事件,一般用于触发后续任务。
ecFlow 日志仅记录 event
命令的执行记录。
MSG:[23:13:18 14.5.2020] chd:event grapes_postvar_019 /grapes_meso_3km_post/18/initial
meter
meter 命令用于修改属于某个节点的标尺的值,一般用于指示任务执行进度,并触发后续任务。
ecFlow 日志仅记录 meter
命令的执行记录。
MSG:[23:18:44 14.5.2020] chd:meter progress 70 /meso_post/21/meso_chartos/rundir_area_diag1/diag1_grapes_meso_reg_850_div_wind/diag1_grapes_meso_reg_850_div_wind_sep_022
label
label 命令用于修改属于某个节点的标签内容,一般用于向运维人员提供额外消息。
ecFlow 日志仅记录 label
命令的执行记录。
MSG:[23:18:39 14.5.2020] chd:label info 'checking for 009...' /gmf_grapes_gfs_post/18/initial_togrib2
结构
child 命令记录(ChildLogRecord)的结构继承自通用日志结构(EcflowLogRecord),
将 Event
字段设置为状态变化 EventType.Child
。
同时增加命令(Command)字段,记录执行的命令。
对于不同的命令,在附加信息(Additional Information)字段中会记录额外的信息,例如:Abort 命令记录出错原因,Meter 命令记录标尺名称和值。
解析
在经过通用解析后,从 command 字段中提取 child 命令设置为命令字段(Command)。 并根据命令进行相应的解析。
对于 init 和 complete 两种每个命令,仅需解析节点路径。
对于 aborted,event,meter 和 label 几种命令,在解析节点路径基础上,还需解析附加信息。
其他情况的条目直接被忽略。
实现
请参考 nwpc-workflow-log-model 项目的 ChildLogRecord
类的 parse_record 函数
以下代码来自该函数,其中 self
表示 EcflowLogParser
类,line
是解析过通用字段后剩余的日志条目字符串。即
label info 'checking for 009...' /gmf_grapes_gfs_post/18/initial_togrib2
获取命令
查找 " "
,获取命令
start_pos = 0
end_pos = line.find(" ", start_pos)
if end_pos == -1:
if debug:
logger.error(f"[ERROR] child record: event not found => {self.log_record}")
return
event = line[start_pos:end_pos]
self.event = event
self.command = self.event
init/complete/abort
这三种命令都修改节点的状态,abort 命令会附带出错原因字段
start_pos = end_pos + 1
end_pos = line.find(" ", start_pos)
if end_pos == -1:
# MSG:[08:17:04 29.6.2018] chd:complete /gmf_grapes_025L60_v2.2_post/18/typhoon/post/tc_post
self.node_path = line[start_pos:].strip()
else:
# MSG:[12:22:53 19.10.2018] chd:abort /3km_post/06/3km_togrib2/grib2WORK/030/after_data2grib2_030 trap
self.node_path = line[start_pos:end_pos]
self.additional_attrs["reason"] = line[end_pos + 1:]
event
event 命令包含名称和节点路径,均由 " "
分割
start_pos = end_pos + 1
line = line[start_pos:]
tokens = line.split(" ")
if len(tokens) == 2:
self.node_path = tokens[1]
self.additional_attrs["name"] = tokens[0]
meter
meter 命令包含名称,值和节点路径,均由 " "
分割
start_pos = end_pos + 1
line = line[start_pos:]
tokens = line.split(" ")
if len(tokens) == 3:
self.node_path = tokens[2]
self.additional_attrs["name"] = tokens[0]
self.additional_attrs["value"] = int(tokens[1])
label
label 命令包含名称,值和节点路径,均由 " "
分割
start_pos = end_pos + 1
line = line[start_pos:]
line = line.rstrip()
name_end_pos = line.find(" ")
self.additional_attrs["name"] = line[:name_end_pos]
node_start_pos = line.rfind(" ")
self.node_path = line[node_start_pos+1:]
self.additional_attrs["value"] = line[name_end_pos+2: node_start_pos-1]
参考
项目: