fix: Use go docker module

This commit is contained in:
lif
2025-09-10 07:48:46 +00:00
parent 417fc25db5
commit ff0af2e98b
5 changed files with 281 additions and 58 deletions

145
main.go
View File

@@ -1,84 +1,115 @@
package main
import (
"encoding/json"
"bufio"
"context"
"fmt"
"io/ioutil"
"net"
"net/http"
"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"
)
type Container struct {
ID string `json:"Id"`
}
func main() {
// Create a custom transport to use the Unix socket
transport := &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
return net.Dial("unix", "/var/run/docker.sock")
},
}
client := &http.Client{
Transport: transport,
Timeout: 10 * time.Second,
}
// Create a ticker that ticks every 10 seconds
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
}
for {
select {
case <-ticker.C:
fetchLogs(client)
}
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 fetchLogs(client *http.Client) {
// Get the list of container IDs
resp, err := client.Get("http://localhost/containers/json")
func streamContainerLogs(ctx context.Context, cli *client.Client, curcont container.Summary) {
inspect, err := cli.ContainerInspect(ctx, curcont.ID)
if err != nil {
fmt.Println("Error fetching containers:", err)
log.Printf("Error inspecting container %s: %v", curcont.ID, err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
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 {
fmt.Println("Error reading response body:", err)
return
panic(err)
}
var containers []Container
if err := json.Unmarshal(body, &containers); err != nil {
fmt.Println("Error unmarshalling JSON:", err)
return
}
defer reader.Close()
// Loop through each container ID and fetch logs
for _, container := range containers {
fmt.Printf("Fetching logs for container ID: %s\n", container.ID)
logURL := fmt.Sprintf("http://localhost/containers/%s/logs?stdout=true", container.ID)
if !inspect.Config.Tty {
// stdcopy.StdCopy(os.Stdout, os.Stderr, reader)
// Fetch logs
logResp, err := client.Get(logURL)
if err != nil {
fmt.Println("Error fetching logs:", err)
continue
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
handleLog("stdout", scanner.Text())
}
defer logResp.Body.Close()
} else {
// io.Copy(os.Stdout, reader)
logBody, err := ioutil.ReadAll(logResp.Body)
if err != nil {
fmt.Println("Error reading log response body:", err)
continue
}
// Output the logs
fmt.Println(string(logBody))
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)
}