fix: Use go docker module
This commit is contained in:
145
main.go
145
main.go
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user