@@ -2,76 +2,92 @@ package app
2
2
3
3
import (
4
4
"context"
5
+ "fmt"
5
6
"strings"
6
7
7
8
"github.com/spf13/cobra"
9
+ "github.com/spf13/viper"
8
10
9
11
"github.com/StacklokLabs/toolhive/pkg/container"
10
12
"github.com/StacklokLabs/toolhive/pkg/labels"
11
13
"github.com/StacklokLabs/toolhive/pkg/logger"
12
14
)
13
15
14
- func newLogsCommand () * cobra.Command {
15
- return & cobra.Command {
16
+ var (
17
+ tailFlag bool
18
+ )
19
+
20
+ func logsCommand () * cobra.Command {
21
+ logsCommand := & cobra.Command {
16
22
Use : "logs [container-name]" ,
17
23
Short : "Output the logs of an MCP server" ,
18
24
Long : `Output the logs of an MCP server managed by Vibe Tool.` ,
19
25
Args : cobra .ExactArgs (1 ),
20
- Run : func (_ * cobra.Command , args []string ) {
21
- // Get container name
22
- containerName := args [0 ]
23
-
24
- // Create context
25
- ctx , cancel := context .WithCancel (context .Background ())
26
- defer cancel ()
27
-
28
- // Create container runtime
29
- runtime , err := container .NewFactory ().Create (ctx )
30
- if err != nil {
31
- logger .Log .Errorf ("failed to create container runtime: %v" , err )
32
- return
33
- }
34
-
35
- // List containers to find the one with the given name
36
- containers , err := runtime .ListContainers (ctx )
37
- if err != nil {
38
- logger .Log .Errorf ("failed to list containers: %v" , err )
39
- return
40
- }
41
-
42
- // Find the container with the given name
43
- var containerID string
44
- for _ , c := range containers {
45
- // Check if the container is managed by Vibe Tool
46
- if ! labels .IsToolHiveContainer (c .Labels ) {
47
- continue
48
- }
49
-
50
- // Check if the container name matches
51
- name := labels .GetContainerName (c .Labels )
52
- if name == "" {
53
- name = c .Name // Fallback to container name
54
- }
55
-
56
- // Check if the name matches (exact match or prefix match)
57
- if name == containerName || strings .HasPrefix (c .ID , containerName ) {
58
- containerID = c .ID
59
- break
60
- }
61
- }
62
-
63
- if containerID == "" {
64
- logger .Log .Infof ("container %s not found" , containerName )
65
- return
66
- }
67
-
68
- logs , err := runtime .ContainerLogs (ctx , containerID )
69
- if err != nil {
70
- logger .Log .Errorf ("failed to get container logs: %v" , err )
71
- return
72
- }
73
- logger .Log .Infof (logs )
74
-
26
+ RunE : func (cmd * cobra.Command , args []string ) error {
27
+ return logsCmdFunc (cmd , args )
75
28
},
76
29
}
30
+
31
+ logsCommand .Flags ().BoolVarP (& tailFlag , "tail" , "t" , false , "Tail the logs" )
32
+ err := viper .BindPFlag ("tail" , logsCommand .Flags ().Lookup ("tail" ))
33
+ if err != nil {
34
+ logger .Log .Errorf ("failed to bind flag: %v" , err )
35
+ }
36
+
37
+ return logsCommand
38
+ }
39
+
40
+ func logsCmdFunc (_ * cobra.Command , args []string ) error {
41
+ // Get container name
42
+ containerName := args [0 ]
43
+
44
+ // Create context
45
+ ctx , cancel := context .WithCancel (context .Background ())
46
+ defer cancel ()
47
+
48
+ // Create container runtime
49
+ runtime , err := container .NewFactory ().Create (ctx )
50
+ if err != nil {
51
+ return fmt .Errorf ("failed to create container runtime: %v" , err )
52
+ }
53
+
54
+ // List containers to find the one with the given name
55
+ containers , err := runtime .ListContainers (ctx )
56
+ if err != nil {
57
+ return fmt .Errorf ("failed to list containers: %w" , err )
58
+ }
59
+
60
+ // Find the container with the given name
61
+ var containerID string
62
+ for _ , c := range containers {
63
+ // Check if the container is managed by Vibe Tool
64
+ if ! labels .IsToolHiveContainer (c .Labels ) {
65
+ continue
66
+ }
67
+
68
+ // Check if the container name matches
69
+ name := labels .GetContainerName (c .Labels )
70
+ if name == "" {
71
+ name = c .Name // Fallback to container name
72
+ }
73
+
74
+ // Check if the name matches (exact match or prefix match)
75
+ if name == containerName || strings .HasPrefix (c .ID , containerName ) {
76
+ containerID = c .ID
77
+ break
78
+ }
79
+ }
80
+
81
+ if containerID == "" {
82
+ logger .Log .Infof ("container %s not found" , containerName )
83
+ return nil
84
+ }
85
+
86
+ tail := viper .GetBool ("tail" )
87
+ logs , err := runtime .ContainerLogs (ctx , containerID , tail )
88
+ if err != nil {
89
+ return fmt .Errorf ("failed to get container logs: %v" , err )
90
+ }
91
+ fmt .Print (logs )
92
+ return nil
77
93
}
0 commit comments