diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..e4d024d --- /dev/null +++ b/.air.toml @@ -0,0 +1,9 @@ +root = "." +tmp_dir = "tmp" + +[build] +cmd = "go build -buildvcs=false -o ./tmp/main ." +bin = "tmp/main" +delay = 1000 +exclude_dir = ["tmp", "vendor"] + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3fec32c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +tmp/ diff --git a/Dockerfile b/Dockerfile index 9c1aa19..71f552c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,4 @@ FROM scratch COPY --from=prep-image /lilog /lilog -CMD ["/lilog"] +ENTRYPOINT ["/lilog"] diff --git a/Makefile b/Makefile index 57e8c73..e639a06 100644 --- a/Makefile +++ b/Makefile @@ -2,3 +2,13 @@ docker-build: docker build -t liffsh/lilog:latest --progress=plain ./ docker-run: docker run -v /var/run/docker.sock:/var/run/docker.sock liffsh/lilog:latest +ship: + docker build -t liffsh/lilog:latest . && docker push liffsh/lilog:latest +dev: + docker run --rm -it \ + -v $$(pwd):/app \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -w /app \ + -p 8080:8080 \ + golang:latest \ + sh -c "go install github.com/air-verse/air@latest && air" diff --git a/main.go b/main.go index 8530ba4..3c055d6 100644 --- a/main.go +++ b/main.go @@ -16,58 +16,71 @@ import ( "github.com/docker/docker/pkg/stdcopy" ) +var containers = make(map[string]int) + +type LogType struct { + Log string + Source string + ContainerName string +} + func main() { - listContainersAndLogType() + ctx := context.Background() 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 + logschan := make(chan LogType) + 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) + } } -func listContainersAndLogType() { - ctx := context.Background() - +func listContainersAndLogType(ctx context.Context, logschan chan<- LogType) { 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) + defer streamContainerLogs(ctx, cli, curcont, logschan) }() - // pp.Println(logs) } } -func streamContainerLogs(ctx context.Context, cli *client.Client, curcont container.Summary) { - +func streamContainerLogs(ctx context.Context, cli *client.Client, curcont container.Summary, logschan chan<- LogType) { inspect, err := cli.ContainerInspect(ctx, curcont.ID) if err != nil { log.Printf("Error inspecting container %s: %v", curcont.ID, 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) + return + } + if inspect.Config.Cmd[0] == "/lilog" { + slog.Info("Skipping own container logs") + return + } + logType := inspect.HostConfig.LogConfig.Type fmt.Printf("Container: %-20s ID: %.12s LogDriver: %s\n", curcont.Image, curcont.ID, logType) @@ -76,40 +89,40 @@ func streamContainerLogs(ctx context.Context, cli *client.Client, curcont contai ShowStdout: true, ShowStderr: true, Follow: true, + Tail: "3", }) if err != nil { panic(err) } defer reader.Close() + stdoutPR, stdoutPW := io.Pipe() + stderrPR, stderrPW := io.Pipe() - if !inspect.Config.Tty { - // stdcopy.StdCopy(os.Stdout, os.Stderr, reader) + defer stdoutPW.Close() + defer stderrPW.Close() - 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) + scanner := bufio.NewScanner(stdoutPR) for scanner.Scan() { - handle(stream, scanner.Text()) + logschan <- LogType{ + ContainerName: inspect.Name, + Source: "tty", + Log: scanner.Text(), + } } }() - return pw -} -func handleLog(t string, b string) { - fmt.Println("handleLog", t, ":", b) + go func() { + scanner := bufio.NewScanner(stderrPR) + for scanner.Scan() { + logschan <- LogType{ + ContainerName: inspect.Name, + Source: "tty", + Log: scanner.Text(), + } + } + }() + + stdcopy.StdCopy(stdoutPW, stderrPW, reader) }