How to get container logs using Golang? (mistake)

WBOY
Release: 2024-02-08 21:09:28
forward
528 people have browsed it

如何使用 Golang 获取容器日志? (错误)

php editor Xigua brings you a practical guide on how to use Golang to obtain container logs. In containerized application development, logs are very important, as they can help us quickly locate and solve problems. This article will introduce how to use Golang to write code, obtain the log information of the container through the Docker API, and handle common errors. Whether you are a newbie or an experienced developer, this article will provide you with useful tips and sample code to help you better utilize Golang to obtain container logs. Let’s get started!

Question content


I am trying to use golang to write docker monitoring software.

My code looks like this:

package main

import (
    "bytes"
    "context"
    "fmt"
    "time"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

func main() {
    ctx := context.background()

    cli, err := client.newclientwithopts(client.fromenv)
    if err != nil {
        panic(err)
    }

    containers, err := cli.containerlist(ctx, types.containerlistoptions{})
    if err != nil {
        panic(err)
    }

    for _, container := range containers {
        out, err := cli.containerlogs(ctx, container.id, types.containerlogsoptions{
            showstderr: true,
            showstdout: true,
            timestamps: false,
            follow:     true,
            tail:       "40"})

        if err != nil {
            panic(err)
        }

        fmt.println("the \"" + container.image + "\" container, with the id \"" + container.id + "\" logged: ")
        fmt.println()

        buf := new(bytes.buffer)

        fmt.println(buf.readfrom(out))

        fmt.println(buf.string())
    }
    time.sleep(time.second * 3)
}
Copy after login

The problem is that the execution of the above code stops at the fmt.println(buf.readfrom(out)) statement. The code used to work, but suddenly it doesn't work anymore. It either stops without error or returns an empty string.

The client I am trying to collect logs is also written by myself and looks like this:

package main

import (
    "log"
    "time"
)

func main() {
    for i := 0; i > -1; i++ {
        log.Output(1, "Hello World logged!")
        time.Sleep(time.Minute)
    }
}
Copy after login

I've tried debugging and inspecting variables, but I just can't find the source of the problem.


Solution


I'm really not sure as I don't have any error logs to confirm my assumption. However, when containerlogs returns a stream (io.readcloser), is it possible that the stream itself has not been closed?

If possible, could you do a trial run first to test this theory by adding a timeout and logging it after each small duration?

One possible approach is

select {
case <-time.After(5 * time.Second):
    fmt.Println("Timeout exceeded while reading container logs")
case <-ctx.Done():
    fmt.Println("Context cancelled while reading container logs")
case b := <-out:
    if b != nil {
        buf.Write(b)
    }
}
Copy after login

The above is the detailed content of How to get container logs using Golang? (mistake). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!