Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions cmd/logs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package main

import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"strings"

"github.com/fatih/color"
"github.com/spf13/cobra"
)

var (
followLogs bool
)

func newLogsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "logs",
Short: "View logs for ACS components",
Long: `View logs for various ACS components.`,
}

cmd.AddCommand(newLogsOperatorCmd())

return cmd
}

func newLogsOperatorCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "operator",
Short: "View logs for the RHACS operator",
Long: `View logs for the RHACS operator running in the rhacs-operator-system namespace.`,
RunE: runLogsOperator,
}

cmd.Flags().BoolVarP(&followLogs, "follow", "f", false, "Follow log output (stream logs)")

return cmd
}

func runLogsOperator(cmd *cobra.Command, args []string) error {
// Build kubectl command
kubectlArgs := []string{
"-n", "rhacs-operator-system",
"logs",
"-l", "app=rhacs-operator",
}

if followLogs {
kubectlArgs = append(kubectlArgs, "-f")
}

// Create kubectl command
kubectlCmd := exec.Command("kubectl", kubectlArgs...)

// Get stdout pipe for streaming
stdout, err := kubectlCmd.StdoutPipe()
if err != nil {
return fmt.Errorf("failed to create stdout pipe: %w", err)
}

// Pass through stderr directly
kubectlCmd.Stderr = os.Stderr

// Start the command
if err := kubectlCmd.Start(); err != nil {
return fmt.Errorf("failed to start kubectl: %w", err)
}

// Process stdout with color coding
processLogStream(stdout)

// Wait for command to complete
if err := kubectlCmd.Wait(); err != nil {
// Don't return error if kubectl was interrupted (e.g., Ctrl+C)
if _, ok := err.(*exec.ExitError); ok {
return nil
}
return fmt.Errorf("kubectl command failed: %w", err)
}

return nil
}

func processLogStream(reader io.Reader) {
scanner := bufio.NewScanner(reader)

// Define colors for different log levels
infoColor := color.New(color.FgWhite)
debugColor := color.New(color.Faint)
errorColor := color.New(color.FgRed, color.Bold)
warnColor := color.New(color.FgYellow)

for scanner.Scan() {
line := scanner.Text()

// Determine log level and apply appropriate color
switch {
case strings.Contains(line, "ERROR"):
errorColor.Println(line)
case strings.Contains(line, "WARN"):
warnColor.Println(line)
case strings.Contains(line, "DEBUG"):
debugColor.Println(line)
case strings.Contains(line, "INFO"):
infoColor.Println(line)
default:
// Default to info color for unrecognized lines
infoColor.Println(line)
}
}

if err := scanner.Err(); err != nil {
fmt.Fprintf(os.Stderr, "Error reading logs: %v\n", err)
}
}
1 change: 1 addition & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ func init() {
rootCmd.AddCommand(newTeardownCmd())
rootCmd.AddCommand(newVersionCmd())
rootCmd.AddCommand(newEnvCmd())
rootCmd.AddCommand(newLogsCmd())
}