package main import ( "bufio" "context" "fmt" "io" "log" "log/slog" "time" "github.com/k0kubun/pp/v3" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" ) func main() { listContainersAndLogType() pp.Println("Running") ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() // for _ = range ticker.C { // fetchLogs(client) // } done := make(chan struct{}) <-done // block forever } func listContainersAndLogType() { ctx := context.Background() cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Fatalf("Error creating Docker client: %v", err) } // List running and stopped containers containers, err := cli.ContainerList(ctx, container.ListOptions{All: true}) if err != nil { log.Fatalf("Error listing containers: %v", err) } pp.Println(containers) go func() { time.Sleep(3 * time.Second) slog.Info("Slept") ctx.Done() }() for _, curcont := range containers { go func() { streamContainerLogs(ctx, cli, curcont) }() // pp.Println(logs) } } func streamContainerLogs(ctx context.Context, cli *client.Client, curcont container.Summary) { inspect, err := cli.ContainerInspect(ctx, curcont.ID) if err != nil { log.Printf("Error inspecting container %s: %v", curcont.ID, err) return } logType := inspect.HostConfig.LogConfig.Type fmt.Printf("Container: %-20s ID: %.12s LogDriver: %s\n", curcont.Image, curcont.ID, logType) reader, err := cli.ContainerLogs(ctx, curcont.ID, container.LogsOptions{ ShowStdout: true, ShowStderr: true, Follow: true, }) if err != nil { panic(err) } defer reader.Close() if !inspect.Config.Tty { // stdcopy.StdCopy(os.Stdout, os.Stderr, reader) scanner := bufio.NewScanner(reader) for scanner.Scan() { handleLog("stdout", scanner.Text()) } } else { // io.Copy(os.Stdout, reader) stdout := newLogWriter("stdout", handleLog) stderr := newLogWriter("stderr", handleLog) stdcopy.StdCopy(stdout, stderr, reader) } } func newLogWriter(stream string, handle func(string, string)) io.Writer { pr, pw := io.Pipe() go func() { scanner := bufio.NewScanner(pr) for scanner.Scan() { handle(stream, scanner.Text()) } }() return pw } func handleLog(t string, b string) { fmt.Println("handleLog", t, ":", b) }