繁体   English   中英

如何通过Go SDK流式传输Docker容器日志

[英]How to stream Docker container logs via the Go SDK

我在Go中为某些游戏服务器软件编写了一个名为sampctl的工具 ,其主要功能是为服务器实例启动一个Docker容器,然后捕获从容器中出来的日志,对其进行清理,然后将其发送到用户选择的位置,例如Elasticsearch或管理面板,以供以后分析。

我已经完成了所有其他工作,似乎无法工作的唯一一件事就是日志。 如果容器中的应用程序崩溃,我可以获取日志,但是我想实时传输日志。

我试过使用带有ContainerLogs返回的ReadCloser的扫描仪,但是它只是挂在终端上。

https://github.com/Southclaws/sampctl/blob/9c76b4dd1b3dbb9e18927da10028d5beeb94f728/run_container.go#L64-L67

ContainerLogs是否甚至支持流传输? 还是我需要找出另一个解决方案...

抱歉,如果这不是Go问题而不是Docker问题,我不太确定是否要在此处发布或在GoLangBridge上发布...

你看过文档吗? 流中嵌入了元数据,因此您不能仅将其通过管道传输到控制台。

我在监视应用程序中具有以下代码:

    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))
    }

只要我保持运行它就会流。 还有一个帮助程序包可以为您完成大多数操作,但就我而言,由于其他原因,我需要像这样单独处理消息。

好的,我设法解决了这个问题,我不确定为什么captncraig的答案不起作用,我仍然对此感到好奇,但是,这是我的解决方案:

我必须在ContainerCreate调用中设置其他一些选项:

        Tty:          true,
        AttachStdout: true,
        AttachStderr: true,

然后, scanner.Scan()方法运行良好!

这是更新的代码: https : //github.com/Southclaws/sampctl/blob/1ad7971d817031bd5a5b3acfad3bf2ea69232c98/run_container.go#L56-L70

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM