# 插件镜像规范

# 综述

此规范旨在指导开发者编写和构建标注平台插件,并提供标注平台插件运行的内部机制和原理的简要说明,定义需要实现或遵循的接口规则。

# 实现原理

标注平台提供了如下界面来实现可视化地运行某个镜像。

数据处理-运行Docker image进行数据处理

  • 系统管理员将镜像通过tar包的方式导入到平台,在数据处理模块中展示镜像,进行选择运行;
  • 在输入和输出数据集分别指定相应的数据集名称后,平台会从系统下载相应的输入数据集作为插件的输入,并将经过插件处理后的结果作为输出并上传到系统中作为相应的输出数据集;
  • 如果运行时需要指定参数,需要提供一个“Key=Value”格式的字符串到参数设置文本框中,多个参数以空格进行分割(例如:--env OPTION=2 --privileged=true);

后台读取表单信息并按照如下的方式启动镜像:

docker run -d -v 输入绝对路径:/input -v 结果的绝对路径:/result —env PARAMS=参数设置中的参数内容 IMAGE_NAME:VERSION

下面是平台创建一个人脸检测容器并运行的示例:

docker run -d -v /data_sjt/docker/67/1591684436580/input:/input -v /data_sjt/docker/67/1591684436580:/result --privileged=true fac_det-cpu:v0.1

# 镜像打包规范

插件需要按照如下规范实现:

  1. 读取 /input下的所有文件作为输入文件;
  2. 将处理的结果输出到 /result下。该/result结果输出文件目录,需要和 /input下的输入目录保持严格一致;
  3. 处理所需的参数从环境变量PARAMS中获取;
  4. 参数可以为空,建议默认填写下面参数将让docker应用容器获取宿主机root权限:--privileged=true;
  5. 镜像的启动命令需要在Dockfile中定义;
  6. 插件的运行状态等需要和系统通讯的信息,通过日志的方式实现,需要遵循下面的“镜像日志格式定义”。

# 注意事项

下面的注意事项是初次接触镜像制作会经常遇到的问题,如想避坑,请一定认真阅读。

  1. 建议阅读手册文档或者标注结果导出等方式先熟悉标准的预识别文件格式,错误的预识别格式将导致平台模板无法回显预识别信息;
  2. 建议镜像打包前在本地做好充分调试,使用docker run命令通过目录挂载方式尝试是否正确产生json预识别文件(命令格式请效仿上面给出的命令代码示例并结合本地实际环境修改);
  3. 线下生成预识别文件后,通过管理后台上传数据集“原始文件”+“预识别文件”匹配对上传到平台进行预识别回显测试,确认无误后再进行镜像打包;
  4. 标注平台数据集支持“多目录”、“多层级”、“包含中文的目录或数据”。也就是说,镜像的/input下的数据目录结构要充分考虑此类情况,且生成的/result目录下需要同输入保持同样的结构。不一致的目录结构将导致平台侧无法正常加载预识别文件;
  5. 生成的json预识别文件要和原始输入文件保持在相同的目录结构下,并使用相同的文件名。原始文件无需拷贝到/result下。
  6. 预识别json文件的编码格式需要设置为“utf-8”;
  7. 不同的镜像会对服务器资源(CPU、内存、GPU等)有不同的要求。服务器上传运行某一个镜像前,需要提前确认并保证满足该镜像运行的资源需求;
  8. 预识别上传时,需要选择数据处理类型为“预识别”,并正确设置处理文件的类型。其他数据处理形式也需要相应的选择正确的选项;
  9. 如果使用了env参数,请上传镜像时做好参数说明,以保证用户可以正确书写和调用。

# 镜像日志格式定义

为了镜像能顺利的运行,以及在镜像运行出错时更快速高效的通过日志进行问题排查,特制订下面的镜像日志格式定义规范。

# 基本字段及定义

  • event_type:事件类型,取值为整数1~8,具体含义见第二节;
  • message:消息内容;
  • level:log等级;
  • timestamp:日志发出的时间戳;
  • extra:其他信息,根据event_type而变化 示例:
{
  "event_type": "EventType.TASK_STARTED",
  "message": "abc",
  "level": "debug/info/warn/error",
  "timestamp": "2019-10-25T16:22.549Z",
  "extra": {}  #根据event_type不同而变化
}

# 字段具体含义及取值

# event_type

1. LOG:日志消息;
2. TASK_STARTED:容器已启动,任务开始执行;
3. TASK_FINISHED:任务运行结束,容器即将关闭
4. TASK_STOPPED:任务被从页面中手动终止
5. TASK_CRASHED:程序内部崩溃导致任务执行失败;
6. STEP_COMPLETE:任务中某一步执行完毕;
7. PROGRESS:进度百分比显示;
8. METRICS:度量信息显示;

# extra

  1. event_type为TASK_CRASHED时,message为失败原因,extra包含系统调用栈中的记录,样例如下:
{
  "event_type": "EventType.TASK_CRASHED",
  "message": "人脸检测",
  "level": "info",
  "timestamp": "2019-10-25T16:22.549Z",
  "extra": {
		"exc_info": "Traceback (most recent call last):\nFile \"E:/HttpRunnerManager-jh/ApiManager/tests.py\", line 42, in <module>\n    func(1, 0)\n  File \"E:/HttpRunnerManager-jh/ApiManager/tests.py\", line 33, in func\n    return a / b\nZeroDivisionError: division by zero"
	}
}

  1. event_type为PROGRESS时,message即可任务名称(”用于区别多任务的情况”),extra包含total和current两个字段,分别表示总共要处理的数量和当前已处理,current会每隔几个周期发一次,不是连续的,样例如下;
{
  "event_type":"EventType.PROGRESS",
  "message": "人脸检测",
  "level": "info",
  "timestamp": "2019-10-25T16:22.549Z",
  "extra": {
		"total": 100,
      "current": 12
	}
}
  1. event_type为METRICS时,extra为各个统计项指标,依照如下格式:
{
  "event_type":"EventType.METRICS",
  "message": "人脸检测",
  "level": "info",
  "timestamp": "2019-10-25T16:22.549Z",
  "extra": {
    "metrics": [
       {
          "name": "total-time",
          "desc": "运行总时长",
          "value": 3600.12
       },
       {
          "name": "total-bbox",
          "desc": "检测总框数",
          "value": 25},
    ]
  }
}