dsztc99732 2018-05-22 10:20
浏览 42
已采纳

go-docker客户端每秒钟获取容器日志不返回任何内容

I'm using the docker.io/go-docker package to launch a container with GO. I'm able to get all the logs of the container once its main method returns

if err := cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil {
    panic(err)
}

statusCh, errCh = cli.ContainerWait(context.Background(), resp.ID, container.WaitConditionNotRunning)

select {
    case err := <-errCh:
        if err != nil {
            panic(err)
        }
    case <-statusCh:
}

out, err := cli.ContainerLogs(context.Background(), resp.ID, types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true})
if err != nil {
    panic(err)
}
// Do something with the logs here...

The trick is that the main method execution takes a while and I want to show the container logs to the user every seconds. My idea was to start a new goroutine to loop and make a request on cli.ContainerLogs.

So I changed my implementation to this :

nowUTC := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)

if err := cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil {
    panic(err)
}

statusCh, errCh = cli.ContainerWait(context.Background(), resp.ID, container.WaitConditionNotRunning)

exitCh := make(chan bool)

go func(since string, exit chan bool) {

Loop:

    for {
        select {
        case <-exit:
            break Loop
        default:

            sinceReq := since
            time.Sleep(time.Second)
            since = strconv.FormatInt(time.Now().UTC().UnixNano(), 10)
            out, err := cli.ContainerLogs(context.Background(), resp.ID, types.ContainerLogsOptions{Since: sinceReq, ShowStdout: true, ShowStderr: true})
            if err != nil {
                panic(err)
            }

            b, err := ioutil.ReadAll(out)
            if err != nil {
                panic(err)
            }
            log.Printf("Rolling log Contener 
%s", string(b))
            // Do something with the logs here...
        }
    }
}(nowUTC, exitCh)


select {
case err := <-errCh:
    exitCh <- true
    if err != nil {
        panic(err)
    }
case <-statusCh:
    exitCh <- true
}

Everything is fine except that ioutil.ReadAll(out) returns nothing.

I have tried to use several times or time formats like but still without any results:

  • nowUTC := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)
  • nowUTC := strconv.FormatInt(time.Now().UTC().Unix(), 10)
  • nowUTC := strconv.FormatInt(time.Now().UnixNano(), 10)
  • nowUTC := strconv.FormatInt(time.Now().Unix(), 10)
  • nowUTC := time.Now().Format(time.RFC3339)

What am I mising?

  • 写回答

1条回答 默认 最新

  • dongque8332 2018-06-19 07:20
    关注

    Finally I got it working using the nowUTC :=time.Now().UTC(), but the issue was not only on the time format used.

    The trick is that I was using "Docker Machine" on a laptop and I was closing my laptop every night. Whenever the laptop goes asleep the internal clock of the Docker Machine freeze.

    When the laptop wakes up from sleep it results into a time drift between the laptop clock and Docker Machine's clock, and my Docker Machine was x hours late.

    My Go code runs into an CLI app on my laptop and the time criteria of the request to extract the logs never matches the log content.

    Everything works fine after a docker-machine restart

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 请问这个是什么意思?
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。