如何在 Go 程序中用 Compose SDK 的 EventProcessor 捕获操作进度并选择输出渲染器【免费下载链接】composeDefine and run multi-container applications with Docker项目地址: https://gitcode.com/GitHub_Trending/compose/compose当你在自己的 Go 程序里嵌入 Compose SDKgithub.com/docker/compose/v5来执行up、down、build这类操作时SDK 对 Docker 资源镜像、容器、卷、网络的每一次改动默认只发生在后台程序拿不到中间进度。要捕获这些进度并决定“打印成文本”还是“输出成 JSON 供下游解析”做法是在NewComposeService时传入compose.WithEventProcessor(...)选项再从cmd/display包中选择一个内置渲染器或自己实现api.EventProcessor接口。前提先按标准方式创建 Compose SDK 服务事件处理是挂在 Compose service 实例上的所以先要有可用的 service。按 docs/sdk.md 的示例初始化顺序是创建 Docker CLI、初始化、创建 servicepackage 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) } }其中ConfigPaths和ProjectName是示例值替换为你自己的 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 操作如up、down、build会对 Docker 资源做一系列变更SDK 通过三个方法通知你Start(ctx, operation)—— 操作开始时调用operation例如upOn(events...)—— 针对单个资源变更的进度事件例如容器正在启动、镜像正在拉取Done(operation, success)—— 操作结束时调用success指示成功还是失败。每个事件是一个api.Resource包含资源 IDID、父资源ParentID、状态文本Text、细节Details、状态枚举Status以及进度指标Current、Total、Percent镜像拉取这类操作会带下载进度。Status的取值为四种状态含义Working操作进行中例如 creating、starting、pullingDone操作成功完成Warning完成但带有警告Error操作失败Text字段常见的状态文本包括Creating、Created、Starting、Started、Running、Stopping、Stopped、Removing、Removed、Building、Built、Pulling、Pulled等完整常量列表见 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)带进度条和任务列表的交互式终端 UIDocker 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.ID、e.Text、e.Details。它不区分操作阶段Start和Done回调为空实现即 Plain 只反映资源级事件不额外打印“操作开始/结束”行。JSON 渲染器的输出结构cmd/display/json.go 中JSON对每个事件输出一行 JSON 对象字段来自api.Resourceid、parent_id、status取值为StatusText()的Working/Warning/Done/Error、text、details、current、total、percent另带dry-run和tail标记字段。序列化失败的单条事件会被跳过不会中断整个输出。下游程序可以按行读取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需要三个参数out、info、detached boolPlain与JSON各需要一个io.WriterQuiet()无参数见 cmd/display/tty.go 与 docs/sdk.mdWithEventProcessor与其它compose.Option如WithOutputStream、WithMaxConcurrency、WithPrompt可自由组合事件处理器只负责进度事件不影响标准输出流的去向。完成接入后的自然延伸是 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),仅供参考