Listen for containers starting

This commit is contained in:
lif
2025-09-14 18:49:40 +01:00
parent fcc6618370
commit c0f0ee0464

136
main.go
View File

@@ -14,6 +14,9 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
)
var containers = make(map[string]int)
@@ -26,22 +29,54 @@ type LogType struct {
func main() {
ctx := context.Background()
pp.Println("Running")
pp.Println("Running1")
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
logschan := make(chan LogType)
listContainersAndLogType(ctx, logschan)
go listContainersAndLogType(ctx, logschan)
go func() {
time.Sleep(3 * time.Second)
slog.Info("Slept")
done := ctx.Done()
test := <- done
pp.Println(test)
}()
for i := range logschan {
pp.Println(i.ContainerName + ": " + i.Log)
slog.Info(i.ContainerName + ": " + i.Log)
}
}
func eventListen(cli *client.Client, logschan chan<- LogType) {
ctx := context.Background()
options := events.ListOptions{
Filters: filters.NewArgs(
filters.Arg("type", "container"),
),
}
eventChan, errChan := cli.Events(ctx, options)
slog.Info("Waiting for events")
for {
select {
case event := <-eventChan:
switch event.Action {
case "create":
fmt.Println("Container created:", event.Actor.Attributes["image"])
case "start":
fmt.Println("Container started:", event.Actor.Attributes["image"])
streamContainerLogs(ctx, cli, event.Actor.ID, logschan)
case "die":
fmt.Println("Container stopped:", event.Actor.Attributes["image"])
case "destroy":
fmt.Println("Container destroyed:", event.Actor.Attributes["image"])
}
case err := <-errChan:
if err != nil {
fmt.Println("Error listening to Docker events:", err)
return
}
}
}
}
@@ -56,73 +91,90 @@ func listContainersAndLogType(ctx context.Context, logschan chan<- LogType) {
log.Fatalf("Error listing containers: %v", err)
}
pp.Println(len(containers))
for _, curcont := range containers {
go func() {
defer streamContainerLogs(ctx, cli, curcont, logschan)
defer streamContainerLogs(ctx, cli, curcont.ID, logschan)
}()
}
fmt.Println("Ending")
eventListen(cli, logschan)
}
func streamContainerLogs(ctx context.Context, cli *client.Client, curcont container.Summary, logschan chan<- LogType) {
inspect, err := cli.ContainerInspect(ctx, curcont.ID)
func streamContainerLogs(ctx context.Context, cli *client.Client, containerID string, logschan chan<- LogType) {
inspect, err := cli.ContainerInspect(ctx, containerID)
if err != nil {
log.Printf("Error inspecting container %s: %v", curcont.ID, err)
log.Printf("Error inspecting container %s: %v", containerID, err)
return
}
fmt.Println("Cmd: ", inspect.Config.Cmd)
fmt.Println("Entrypoint: ", inspect.Config.Entrypoint)
if len(inspect.Config.Cmd) == 0 {
slog.Info("Skipping container as cmd empty", "container-id", curcont.ID, "container-image", curcont.Image)
slog.Debug("Skipping container as cmd empty", "container-id", containerID, "container-image", inspect.Image)
return
}
if inspect.Config.Cmd[0] == "/lilog" {
slog.Info("Skipping own container logs")
if inspect.Config.Cmd[0] == "/lilog" || inspect.Config.Cmd[0] == "sh" {
slog.Debug("Skipping own container logs")
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{
if inspect.State.Status != "running" {
slog.Debug("Skipping container which isn't running", "container-id", containerID)
return
}
fmt.Printf("Container: %s (%-20s) ID: %.12s LogDriver: %s\n",
inspect.Config.Cmd[0], inspect.Image, inspect.ID, logType)
reader, err := cli.ContainerLogs(ctx, containerID, container.LogsOptions{
ShowStdout: true,
ShowStderr: true,
Follow: true,
Tail: "3",
Tail: "0",
})
if err != nil {
panic(err)
}
defer reader.Close()
stdoutPR, stdoutPW := io.Pipe()
stderrPR, stderrPW := io.Pipe()
defer stdoutPW.Close()
defer stderrPW.Close()
go func() {
scanner := bufio.NewScanner(stdoutPR)
if inspect.Config.Tty {
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
logschan <- LogType{
ContainerName: inspect.Name,
Source: "tty",
Log: scanner.Text(),
}
logschan <- LogType{ContainerName: inspect.Name, Source: "tty", Log: scanner.Text()}
}
}()
} else {
stdoutPR, stdoutPW := io.Pipe()
stderrPR, stderrPW := io.Pipe()
go func() {
scanner := bufio.NewScanner(stderrPR)
for scanner.Scan() {
logschan <- LogType{
ContainerName: inspect.Name,
Source: "tty",
Log: scanner.Text(),
defer stdoutPW.Close()
defer stderrPW.Close()
go func() {
scanner := bufio.NewScanner(stdoutPR)
for scanner.Scan() {
logschan <- LogType{
ContainerName: inspect.Name,
Source: "tty",
Log: scanner.Text(),
}
}
}
}()
}()
stdcopy.StdCopy(stdoutPW, stderrPW, reader)
go func() {
scanner := bufio.NewScanner(stderrPR)
for scanner.Scan() {
logschan <- LogType{
ContainerName: inspect.Name,
Source: "tty",
Log: scanner.Text(),
}
}
}()
_, err := stdcopy.StdCopy(stdoutPW, stderrPW, reader)
if err != nil {
panic(err)
}
}
}