如何通过Go SDKstream式处理Docker容器日志
我正在为Go中的一些游戏服务器软件编写一个名为sampctl的工具,主要function是为服务器实例启动一个Docker容器,然后捕获从容器中出来的日志,将其清理一些并发送给用户select的位置,例如Elasticsearch或pipe理面板,供以后分析。
我有一切工作,唯一我似乎无法工作的是stream日志。 如果容器中的应用程序崩溃,我可以获取日志,但是我想实时传输日志。
我试过使用一个扫描仪与ContainerLogs
返回ReadCloser
但只是挂在terminal。
https://github.com/Southclaws/sampctl/blob/9c76b4dd1b3dbb9e18927da10028d5beeb94f728/run_container.go#L64-L67
ContainerLogs
是否支持stream式传输? 或者我需要找出另一个解决scheme…
道歉,如果这是更多的问题比Docker的问题,我不太确定是否在这里或在GoLangBridge张贴…
你读过文档吗? 该stream具有embedded的元数据,因此您不能完全将其传送到控制台。
我在监视应用程序中有以下代码:
i, err := cli.ContainerLogs(context.Background(), cid, types.ContainerLogsOptions{ ShowStderr: true, ShowStdout: true, Timestamps: false, Follow: true, Tail: "40", }) if err != nil { log.Fatal(err) } hdr := make([]byte, 8) for { _, err := i.Read(hdr) if err != nil { log.Fatal(err) } var w io.Writer switch hdr[0] { case 1: w = os.Stdout default: w = os.Stderr } count := binary.BigEndian.Uint32(hdr[4:]) dat := make([]byte, count) _, err = i.Read(dat) fmt.Fprint(w, string(dat)) }
只要我保持运行,它就会stream。 也有这个帮助程序包为你做大部分,但在我的情况下,我需要处理这样的消息个别这样的其他原因。
好吧,我设法解决这个问题,我不知道为什么captncraig的答案没有工作,我仍然好奇,但嘿,这是我的解决scheme:
我不得不在我的ContainerCreate
调用中设置一些其他选项:
Tty: true, AttachStdout: true, AttachStderr: true,
然后scanner.Scan()
方法工作完美!
这是更新后的代码: https : //github.com/Southclaws/sampctl/blob/1ad7971d817031bd5a5b3acfad3bf2ea69232c98/run_container.go#L56-L70