From b0af94be3f045a6cfaa88d2c65ec69812743827e Mon Sep 17 00:00:00 2001 From: Carl Montanari Date: Wed, 18 Oct 2023 10:38:28 -0700 Subject: [PATCH] feat: tee node logs to pod logs --- launcher/clabernetes.go | 25 +++++++++++++++--- launcher/containerlab.go | 12 ++++----- launcher/docker.go | 56 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 10 deletions(-) diff --git a/launcher/clabernetes.go b/launcher/clabernetes.go index c25ebe75..05e04ab5 100644 --- a/launcher/clabernetes.go +++ b/launcher/clabernetes.go @@ -38,6 +38,16 @@ func StartClabernetes() { ), ) + containerlabLogger := logManager.MustRegisterAndGetLogger( + "containerlab", + clabernetesconstants.Info, + ) + + nodeLogger := logManager.MustRegisterAndGetLogger( + "node", + clabernetesconstants.Info, + ) + ctx, _ := clabernetesutil.SignalHandledContext(clabernetesLogger.Criticalf) clabernetesInstance = &clabernetes{ @@ -46,7 +56,9 @@ func StartClabernetes() { clabernetesconstants.AppNameEnvVar, clabernetesconstants.AppNameDefault, ), - logger: clabernetesLogger, + logger: clabernetesLogger, + containerlabLogger: containerlabLogger, + nodeLogger: nodeLogger, } clabernetesInstance.startup() @@ -59,7 +71,9 @@ type clabernetes struct { appName string - logger claberneteslogging.Instance + logger claberneteslogging.Instance + containerlabLogger claberneteslogging.Instance + nodeLogger claberneteslogging.Instance } func (c *clabernetes) startup() { @@ -115,13 +129,16 @@ func (c *clabernetes) setup() { func (c *clabernetes) launch() { c.logger.Debug("launching containerlab...") - err := c.runClab() + err := c.runContainerlab() if err != nil { c.logger.Criticalf("failed launching containerlab, err: %s", err) clabernetesutil.Panic(err.Error()) } + containerIDs := c.getContainerIDs() + c.tailContainerLogs(containerIDs) + c.logger.Info("containerlab started, setting up any required tunnels...") tunnelBytes, err := os.ReadFile("tunnels.yaml") @@ -141,7 +158,7 @@ func (c *clabernetes) launch() { } for _, tunnel := range tunnelObj { - err = c.runClabVxlanTools( + err = c.runContainerlabVxlanTools( tunnel.LocalNodeName, tunnel.LocalLinkName, tunnel.RemoteName, diff --git a/launcher/containerlab.go b/launcher/containerlab.go index b133fc12..c0d180d2 100644 --- a/launcher/containerlab.go +++ b/launcher/containerlab.go @@ -11,13 +11,13 @@ import ( claberneteserrors "github.com/srl-labs/clabernetes/errors" ) -func (c *clabernetes) runClab() error { - clabLogFile, err := os.Create("clab.log") +func (c *clabernetes) runContainerlab() error { + containerlabLogFile, err := os.Create("containerlab.log") if err != nil { return err } - clabOutWriter := io.MultiWriter(c.logger, clabLogFile) + containerlabOutWriter := io.MultiWriter(c.containerlabLogger, containerlabLogFile) args := []string{ "deploy", @@ -31,8 +31,8 @@ func (c *clabernetes) runClab() error { cmd := exec.Command("containerlab", args...) - cmd.Stdout = clabOutWriter - cmd.Stderr = clabOutWriter + cmd.Stdout = containerlabOutWriter + cmd.Stderr = containerlabOutWriter err = cmd.Run() if err != nil { @@ -42,7 +42,7 @@ func (c *clabernetes) runClab() error { return nil } -func (c *clabernetes) runClabVxlanTools( +func (c *clabernetes) runContainerlabVxlanTools( localNodeName, cntLink, vxlanRemote string, vxlanID int, ) error { diff --git a/launcher/docker.go b/launcher/docker.go index d7a44401..a2d0dbd8 100644 --- a/launcher/docker.go +++ b/launcher/docker.go @@ -3,6 +3,7 @@ package launcher import ( "bytes" "fmt" + "io" "os" "os/exec" "strings" @@ -103,3 +104,58 @@ func (c *clabernetes) startDocker() error { attempts++ } } + +func (c *clabernetes) getContainerIDs() []string { + // return all the container ids running in the pod + psCmd := exec.Command("docker", "ps", "--quiet") + + output, err := psCmd.Output() + if err != nil { + c.logger.Warnf( + "failed determining container ids will continue but will not log container output,"+ + " err: %s", + err, + ) + + return nil + } + + containerIDs := strings.Split(strings.TrimSpace(string(output)), "\n") + + c.logger.Debugf("found container ids %q", containerIDs) + + return containerIDs +} + +func (c *clabernetes) tailContainerLogs(containerIDs []string) { + nodeLogFile, err := os.Create("node.log") + if err != nil { + c.logger.Warnf("failed creating node log file, err: %s", err) + + return + } + + nodeOutWriter := io.MultiWriter(c.nodeLogger, nodeLogFile) + + for _, containerID := range containerIDs { + go func(containerID string, nodeOutWriter io.Writer) { + args := []string{ + "logs", + "-f", + containerID, + } + + cmd := exec.Command("docker", args...) //nolint:gosec + + cmd.Stdout = nodeOutWriter + cmd.Stderr = nodeOutWriter + + err = cmd.Run() + if err != nil { + c.logger.Warnf( + "tailing node logs for container id %q failed, err: %s", containerID, err, + ) + } + }(containerID, nodeOutWriter) + } +}