package main import ( "fmt" "io" "os" "github.com/spf13/cobra" mcpv1 "git.wntrmute.dev/mc/mcp/gen/mcp/v1" "git.wntrmute.dev/mc/mcp/internal/config" ) func logsCmd() *cobra.Command { var ( tail int follow bool timestamps bool since string ) cmd := &cobra.Command{ Use: "logs [/]", Short: "Show container logs", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cfg, err := config.LoadCLIConfig(cfgPath) if err != nil { return fmt.Errorf("load config: %w", err) } serviceName, component := parseServiceArg(args[0]) def, err := loadServiceDef(cmd, cfg, serviceName) if err != nil { return err } address, err := findNodeAddress(cfg, def.Node) if err != nil { return err } client, conn, err := dialAgent(address, cfg) if err != nil { return fmt.Errorf("dial agent: %w", err) } defer func() { _ = conn.Close() }() stream, err := client.Logs(cmd.Context(), &mcpv1.LogsRequest{ Service: serviceName, Component: component, Tail: int32(tail), Follow: follow, Timestamps: timestamps, Since: since, }) if err != nil { return fmt.Errorf("logs: %w", err) } for { resp, err := stream.Recv() if err == io.EOF { return nil } if err != nil { return fmt.Errorf("recv: %w", err) } _, _ = os.Stdout.Write(resp.Data) } }, } cmd.Flags().IntVarP(&tail, "tail", "n", 0, "number of lines from end (0 = all)") cmd.Flags().BoolVarP(&follow, "follow", "f", false, "follow log output") cmd.Flags().BoolVarP(×tamps, "timestamps", "t", false, "show timestamps") cmd.Flags().StringVar(&since, "since", "", "show logs since (e.g., 2h, 2026-03-28T00:00:00Z)") return cmd }