Skip to content

Commit 1f5144e

Browse files
committed
Add service logs command to faasd ce from faasd-pro
A more limited version is added, for continuity. Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
1 parent 6dcdab8 commit 1f5144e

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

cmd/root.go

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func init() {
1717
rootCommand.AddCommand(installCmd)
1818
rootCommand.AddCommand(makeProviderCmd())
1919
rootCommand.AddCommand(collectCmd)
20+
rootCommand.AddCommand(makeServiceCmd())
2021
}
2122

2223
func RootCommand() *cobra.Command {

cmd/service.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package cmd
2+
3+
import "github.com/spf13/cobra"
4+
5+
func makeServiceCmd() *cobra.Command {
6+
var command = &cobra.Command{
7+
Use: "service",
8+
Short: "Manage services",
9+
Long: `Manage services created by faasd from the docker-compose.yml file`,
10+
}
11+
12+
command.RunE = runServiceE
13+
14+
command.AddCommand(makeServiceLogsCmd())
15+
return command
16+
}
17+
18+
func runServiceE(cmd *cobra.Command, args []string) error {
19+
20+
return cmd.Help()
21+
22+
}

cmd/service_logs.go

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"os"
8+
"time"
9+
10+
goexecute "github.com/alexellis/go-execute/v2"
11+
"github.com/spf13/cobra"
12+
)
13+
14+
func makeServiceLogsCmd() *cobra.Command {
15+
var command = &cobra.Command{
16+
Use: "logs",
17+
Short: "View logs for a service",
18+
Long: `View logs for a service created by faasd from the docker-compose.yml file.`,
19+
Example: ` ## View logs for the gateway for the last hour
20+
faasd service logs gateway --since 1h
21+
22+
## View logs for the cron-connector, and tail them
23+
faasd service logs cron-connector -f
24+
`,
25+
}
26+
27+
command.Flags().Duration("since", 10*time.Minute, "How far back in time to include logs")
28+
command.Flags().BoolP("follow", "f", false, "Follow the logs")
29+
30+
command.RunE = runServiceLogsE
31+
command.PreRunE = preRunServiceLogsE
32+
33+
return command
34+
}
35+
36+
func runServiceLogsE(cmd *cobra.Command, args []string) error {
37+
name := args[0]
38+
39+
namespace, _ := cmd.Flags().GetString("namespace")
40+
follow, _ := cmd.Flags().GetBool("follow")
41+
since, _ := cmd.Flags().GetDuration("since")
42+
sinceTime, _ := cmd.Flags().GetString("since-time")
43+
lines, _ := cmd.Flags().GetInt("lines")
44+
linesChanged := cmd.Flags().Changed("lines")
45+
46+
journalTask := goexecute.ExecTask{
47+
Command: "journalctl",
48+
Args: []string{"-o", "cat", "-t", fmt.Sprintf("%s:%s", namespace, name)},
49+
StreamStdio: true,
50+
}
51+
52+
if follow {
53+
journalTask.Args = append(journalTask.Args, "-f")
54+
}
55+
56+
if since != 0 {
57+
// Calculate the timestamp that is 'age' duration ago
58+
sinceTime := time.Now().Add(-since)
59+
// Format according to journalctl's expected format: "2012-10-30 18:17:16"
60+
formattedTime := sinceTime.Format("2006-01-02 15:04:05")
61+
journalTask.Args = append(journalTask.Args, fmt.Sprintf("--since=%s", formattedTime))
62+
}
63+
64+
res, err := journalTask.Execute(context.Background())
65+
if err != nil {
66+
return err
67+
}
68+
69+
if res.ExitCode != 0 {
70+
return fmt.Errorf("failed to get logs for service %s: %s", name, res.Stderr)
71+
}
72+
73+
return nil
74+
}
75+
76+
func preRunServiceLogsE(cmd *cobra.Command, args []string) error {
77+
78+
if os.Geteuid() != 0 {
79+
return errors.New("this command must be run as root")
80+
}
81+
82+
if len(args) == 0 {
83+
return errors.New("service name is required as an argument")
84+
}
85+
86+
namespace, _ := cmd.Flags().GetString("namespace")
87+
if namespace == "" {
88+
return errors.New("namespace is required")
89+
}
90+
91+
return nil
92+
}

0 commit comments

Comments
 (0)