Maison  >  Article  >  développement back-end  >  Comment obtenir les journaux de conteneurs à l'aide de Golang ? (erreur)

Comment obtenir les journaux de conteneurs à l'aide de Golang ? (erreur)

WBOY
WBOYavant
2024-02-08 21:09:28529parcourir

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

l'éditeur php Xigua vous propose un guide pratique sur la façon d'utiliser Golang pour obtenir les logs des conteneurs. Dans le développement d'applications conteneurisées, les journaux sont très importants, car ils peuvent nous aider à localiser et à résoudre rapidement les problèmes. Cet article explique comment utiliser Golang pour écrire du code, obtenir les informations de journal du conteneur via l'API Docker et gérer les erreurs courantes. Que vous soyez un débutant ou un développeur expérimenté, cet article vous fournira des conseils utiles et des exemples de code pour vous aider à mieux utiliser Golang pour obtenir les journaux de conteneurs. Commençons!

Contenu de la question


J'essaie d'écrire un logiciel de surveillance Docker en utilisant Golang.

Mon code ressemble à ceci :

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

Le problème est que l'exécution du code ci-dessus s'arrête à l'instruction fmt.println(buf.readfrom(out)). Le code fonctionnait, mais du coup il ne fonctionne plus. Soit il s'arrête sans erreur, soit il renvoie une chaîne vide.

Le client dont j'essaie de collecter les journaux est également écrit par moi-même et ressemble à ceci :

package main

import (
    "log"
    "time"
)

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

J'ai essayé de déboguer et d'inspecter les variables mais je n'arrive tout simplement pas à trouver la source du problème.


Solution de contournement


Je ne suis vraiment pas sûr car je n'ai aucun journal d'erreurs pour confirmer mon hypothèse. Cependant, lorsque containerslogs renvoie un flux (io.readcloser), est-il possible que le flux lui-même n'ait pas été fermé ?

Si possible, pourriez-vous d'abord faire un essai pour tester cette théorie en ajoutant un délai d'attente et en l'enregistrant après chaque petite durée ?

Une façon possible est

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer