news 2026/9/11 4:41:20

如何在 Go 程序中用 Compose SDK 的 EventProcessor 捕获操作进度并选择输出渲染器?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何在 Go 程序中用 Compose SDK 的 EventProcessor 捕获操作进度并选择输出渲染器?

如何在 Go 程序中用 Compose SDK 的 EventProcessor 捕获操作进度并选择输出渲染器?

【免费下载链接】composeDefine and run multi-container applications with Docker项目地址: https://gitcode.com/GitHub_Trending/compose/compose

当你在自己的 Go 程序里嵌入 Compose SDK(github.com/docker/compose/v5)来执行updownbuild这类操作时,SDK 对 Docker 资源(镜像、容器、卷、网络)的每一次改动默认只发生在后台,程序拿不到中间进度。要捕获这些进度并决定“打印成文本”还是“输出成 JSON 供下游解析”,做法是在NewComposeService时传入compose.WithEventProcessor(...)选项,再从cmd/display包中选择一个内置渲染器(或自己实现api.EventProcessor接口)。

前提:先按标准方式创建 Compose SDK 服务

事件处理是挂在 Compose service 实例上的,所以先要有可用的 service。按 docs/sdk.md 的示例,初始化顺序是:创建 Docker CLI、初始化、创建 service:

package main import ( "context" "log" "os" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/flags" "github.com/docker/compose/v5/cmd/display" "github.com/docker/compose/v5/pkg/api" "github.com/docker/compose/v5/pkg/compose" ) func main() { ctx := context.Background() dockerCLI, err := command.NewDockerCli() if err != nil { log.Fatalf("Failed to create docker CLI: %v", err) } err = dockerCLI.Initialize(&flags.ClientOptions{}) if err != nil { log.Fatalf("Failed to initialize docker CLI: %v", err) } // 传入 WithEventProcessor,捕获操作进度 service, err := compose.NewComposeService(dockerCLI, compose.WithEventProcessor(display.JSON(os.Stdout)), ) if err != nil { log.Fatalf("Failed to create compose service: %v", err) } project, err := service.LoadProject(ctx, api.ProjectLoadOptions{ ConfigPaths: []string{"compose.yaml"}, ProjectName: "my-app", }) if err != nil { log.Fatalf("Failed to load project: %v", err) } err = service.Up(ctx, project, api.UpOptions{ Create: api.CreateOptions{}, Start: api.StartOptions{}, }) if err != nil { log.Fatalf("Failed to start services: %v", err) } }

其中ConfigPathsProjectName是示例值,替换为你自己的 compose 文件路径与项目名;compose.yaml需位于程序工作目录。完整示例代码见 docs/examples/sdk/main.go 与 docs/examples/sdk/options.go,这两个文件与docs/sdk.md中的代码块由测试锁定保持一致。

一个必须知道的行为:如果不传WithEventProcessor选项,事件会被静默丢弃(见 docs/sdk.md “Built-inEventProcessorimplementations” 一节)。所以“想拿到进度”时这一步是必做的,不是可选项。

EventProcessor 接口的三个回调

EventProcessor定义在github.com/docker/compose/v5/pkg/api,源码见 pkg/api/event.go。一个 Compose 操作(如updownbuild)会对 Docker 资源做一系列变更,SDK 通过三个方法通知你:

  • Start(ctx, operation)—— 操作开始时调用,operation例如up
  • On(events...)—— 针对单个资源变更的进度事件,例如容器正在启动、镜像正在拉取;
  • Done(operation, success)—— 操作结束时调用,success指示成功还是失败。

每个事件是一个api.Resource,包含资源 ID(ID)、父资源(ParentID)、状态文本(Text)、细节(Details)、状态枚举(Status),以及进度指标CurrentTotalPercent(镜像拉取这类操作会带下载进度)。Status的取值为四种:

状态含义
Working操作进行中,例如 creating、starting、pulling
Done操作成功完成
Warning完成但带有警告
Error操作失败

Text字段常见的状态文本包括CreatingCreatedStartingStartedRunningStoppingStoppedRemovingRemovedBuildingBuiltPullingPulled等,完整常量列表见 pkg/api/event.go 中的Status*定义。

选择输出渲染器:cmd/display里的四个构造函数

Docker Compose CLI 自己用的渲染器位于github.com/docker/compose/v5/cmd/display包,SDK 用户可以直接复用。对应关系如下(来源:docs/sdk.md):

构造函数输出形式适用场景
display.Full(out, info io.Writer, detached bool)带进度条和任务列表的交互式终端 UI(Docker Compose CLI 的默认输出)直接面向终端的用户界面
display.Plain(out io.Writer)简单文本进度消息非交互环境或写入日志文件
display.JSON(out io.Writer)每个事件一个 JSON 对象供程序解析的机器可读流
display.Quiet()静默丢弃事件与不传选项的默认行为相同

选择依据只有一条:你的程序输出流向哪里。写终端选Full;写日志或管道选Plain;要被下游程序逐行解析选JSON;不需要进度输出选Quiet()(或不传选项)。

Plain 渲染器的输出内容

cmd/display/plain.go 中,Plain对每个事件输出一行e.IDe.Texte.Details。它不区分操作阶段,StartDone回调为空实现,即 Plain 只反映资源级事件,不额外打印“操作开始/结束”行。

JSON 渲染器的输出结构

cmd/display/json.go 中,JSON对每个事件输出一行 JSON 对象,字段来自api.Resourceidparent_idstatus(取值为StatusText()Working/Warning/Done/Error)、textdetailscurrenttotalpercent,另带dry-runtail标记字段。序列化失败的单条事件会被跳过,不会中断整个输出。下游程序可以按行读取os.Stdout并用encoding/json反序列化来跟踪进度。

自己实现 EventProcessor(可选分支)

如果内置渲染器不满足需求(例如要把进度上报到自己的监控系统),文档明确支持自接 UI:“UsingEventProcessor, a custom UI can be plugged intodocker/compose.” 做法是实现api.EventProcessor的三个方法后传入compose.WithEventProcessor(...)

type myProcessor struct{} func (m myProcessor) Start(ctx context.Context, operation string) { log.Printf("operation %s started", operation) } func (m myProcessor) On(events ...api.Resource) { for _, e := range events { log.Printf("resource %s: %s (%s)", e.ID, e.Text, e.StatusText()) } } func (m myProcessor) Done(operation string, success bool) { log.Printf("operation %s done: %v", operation, success) }

事件里带Current/Total/Percent时(典型是镜像拉取),可以据此上报百分比进度。

验证与限制

验证方式:

  • display.JSON(os.Stdout)display.Plain(os.Stdout)运行service.Up(...)后,标准输出应有逐行的进度输出,且每行 JSON 可被encoding/json解析、status字段落在Working/Warning/Done/Error四个取值内;
  • 自定义EventProcessor的验证点是Done回调收到的success参数与service.Up返回的 error 一致地反映操作结果。

需要注意的限制:

  • 不传WithEventProcessor时事件被静默丢弃,不会有任何输出或报错提示;
  • 渲染器的构造函数签名需以源码为准:Full需要三个参数(outinfodetached bool),PlainJSON各需要一个io.WriterQuiet()无参数(见 cmd/display/tty.go 与 docs/sdk.md);
  • WithEventProcessor与其它compose.Option(如WithOutputStreamWithMaxConcurrencyWithPrompt)可自由组合,事件处理器只负责进度事件,不影响标准输出流的去向。

完成接入后的自然延伸是 docs/sdk.md “Customizing the SDK” 一节列出的其余选项:结合WithDryRun先做不落盘的演练,用WithOutputStream/WithErrorStream把日志与进度分流到不同目标。

【免费下载链接】composeDefine and run multi-container applications with Docker项目地址: https://gitcode.com/GitHub_Trending/compose/compose

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 4:39:24

2026行车记录仪选购指南:4K、夜视、停车监控怎么看才不踩坑?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/11 4:39:04

AI评估系统:技术指标与业务价值的桥梁

1. AI评估系统的行业背景与核心价值在AI技术快速渗透各行业的当下,企业面临的最大痛点已从"是否要用AI"转变为"如何用好AI"。根据Gartner 2023年技术成熟度曲线显示,超过60%的企业在AI项目落地过程中遭遇模型效果与业务需求错配的问…

作者头像 李华
网站建设 2026/9/11 4:37:36

Windows下MinGW链接OpenSSL报no OPENSSL_Applink的解决

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/11 4:35:47

基于Java+MySQL的教室信息管理系统:数据库设计到JDBC事务实战

简介:基于 JavaMysql 实现的教室信息管理系统,面向高校学生在数据库课程设计、毕业设计或大作业阶段的实践需求,重点训练数据库设计基本方法与编程实现能力,帮助学习者完成从需求分析、流程图与功能模块图设计,到 E-R …

作者头像 李华