我在Go中为一些游戏服务器软件编写了一个名为sampctl的工具,主要功能是为服务器实例启动Docker容器,然后捕获容器中的日志,将它们清理干净并将它们发送到用户选择的位置,例如Elasticsearch或管理面板,以供日后分析。
我已经完成了其他所有工作,我唯一能够开始工作的是流式日志。如果容器中的应用程序崩溃但我想实时流式传输日志,我可以获取日志。
我尝试使用ContainerLogs
返回ReadCloser
的扫描仪,但只是挂在终端上。
ContainerLogs
是否支持流媒体?或者我需要找出另一种解决方案......
如果这更像是一个Go问题而不是Docker问题,我很抱歉,我不太确定是否要在这里或在GoLangBridge上发布...
答案 0 :(得分:5)
您是否阅读过the docs?该流已嵌入元数据,因此您无法将其传输到控制台。
我在监控应用程序中有以下代码:
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))
}
只要我保持运行它就会流动。还有this helper package为你做大部分工作,但在我的情况下,我需要像其他原因单独处理这些消息。
答案 1 :(得分:0)
好的,我设法解决了这个问题,我不确定为什么captncraig的答案不起作用我仍然很好奇但是嘿,这是我的解决方案:
我必须在ContainerCreate
电话中设置一些其他选项:
Tty: true,
AttachStdout: true,
AttachStderr: true,
然后scanner.Scan()
方法完美无缺!