douwen7905 2017-09-26 14:09
浏览 145

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

I'm writing a tool for some game server software in Go called sampctl and the primary function is to spin up a Docker container for a server instance and then capture the logs coming out of the container, clean them up a bit and send them to a location of the users choice such as Elasticsearch or an administration panel for later analysis.

I've got everything else working, the only thing I can't seem to get to work is streaming logs. I can get logs if the application in the container crashes but I want to stream the logs in realtime.

I've tried using a scanner with the ContainerLogs returned ReadCloser but that just hung at the terminal.

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

Does ContainerLogs even support streaming? Or will I need to figure out another solution...

Apologies if this is more of a Go question than a Docker question, I wasn't too sure whether or not to post here or on GoLangBridge...

  • 写回答

2条回答 默认 最新

  • dsfb20227 2017-09-26 14:15
    关注

    Have you read the docs? The stream has metadata embedded, so you can't quite just pipe it to the console.

    I have the following code in a monitoring application:

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

    It streams as long as I keep it running. There is also this helper package to do most of that for you, but in my case I need to handle the messages individually like this for other reasons.

    评论

报告相同问题?

悬赏问题

  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应