Skip to content

Commit c251cfa

Browse files
authored
Merge pull request #169 from thin-edge/feat-add-logfile-support
feat: add log plugins
2 parents 907d45c + 9452b3a commit c251cfa

File tree

22 files changed

+528
-2
lines changed

22 files changed

+528
-2
lines changed

.goreleaser.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,17 @@ nfpms:
119119
dst: /etc/tedge/sm-plugins/container-group
120120
type: symlink
121121

122+
# log plugins
123+
- src: packaging/log-plugins/container
124+
dst: /usr/share/tedge/log-plugins/container
125+
file_info:
126+
mode: 0755
127+
128+
- src: packaging/log-plugins/container-group
129+
dst: /usr/share/tedge/log-plugins/container-group
130+
file_info:
131+
mode: 0755
132+
122133
# Config
123134
- src: ./packaging/config.toml
124135
dst: /etc/tedge/plugins/tedge-container-plugin.toml

cli/container_logs/cmd.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package container_logs
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"github.com/thin-edge/tedge-container-plugin/pkg/cli"
6+
)
7+
8+
// NewContainerLogsCommand returns a cobra command for `container-logs` subcommands
9+
func NewContainerLogsCommand(cmdCli cli.Cli) *cobra.Command {
10+
cmd := &cobra.Command{
11+
Use: "container-logs",
12+
Short: "container log plugin",
13+
}
14+
cmd.AddCommand(
15+
NewListCommand(cmdCli),
16+
NewGetCommand(cmdCli),
17+
)
18+
return cmd
19+
}

cli/container_logs/get.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
Copyright © 2024 thin-edge.io <[email protected]>
3+
*/
4+
package container_logs
5+
6+
import (
7+
"context"
8+
"log/slog"
9+
10+
"github.com/spf13/cobra"
11+
"github.com/thin-edge/tedge-container-plugin/pkg/cli"
12+
"github.com/thin-edge/tedge-container-plugin/pkg/container"
13+
)
14+
15+
type ContainerLogsCommand struct {
16+
*cobra.Command
17+
18+
CommandContext cli.Cli
19+
20+
// Options
21+
Since string
22+
Until string
23+
}
24+
25+
func NewGetCommand(ctx cli.Cli) *cobra.Command {
26+
command := &ContainerLogsCommand{
27+
CommandContext: ctx,
28+
}
29+
cmd := &cobra.Command{
30+
Use: "get",
31+
Short: "Get container logs",
32+
RunE: command.RunE,
33+
Args: cobra.ExactArgs(1),
34+
SilenceUsage: true,
35+
}
36+
37+
cmd.Flags().StringVar(&command.Since, "since", "", "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)")
38+
cmd.Flags().StringVar(&command.Until, "until", "", "Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)")
39+
command.Command = cmd
40+
return cmd
41+
}
42+
43+
func (c *ContainerLogsCommand) RunE(cmd *cobra.Command, args []string) error {
44+
slog.Info("Executing", "cmd", cmd.CalledAs(), "args", args)
45+
46+
containerCli, err := container.NewContainerClient(context.TODO(), c.CommandContext.GetContainerClientOptions()...)
47+
if err != nil {
48+
return err
49+
}
50+
51+
ctx := context.Background()
52+
53+
// Write container logs (stdout and stderr) to stdout
54+
out := cmd.OutOrStdout()
55+
slog.Info("Fetching logs.", "id", args[0])
56+
err = containerCli.ContainerLogs(ctx, out, args[0], container.LogsOptions{
57+
ShowStdout: true,
58+
ShowStderr: true,
59+
Since: c.Since,
60+
Until: c.Until,
61+
Timestamps: false,
62+
Follow: false,
63+
Tail: "100000",
64+
Details: false,
65+
})
66+
if err != nil {
67+
return err
68+
}
69+
return nil
70+
}

cli/container_logs/list.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Copyright © 2024 thin-edge.io <[email protected]>
3+
*/
4+
package container_logs
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"log/slog"
10+
11+
"github.com/spf13/cobra"
12+
"github.com/thin-edge/tedge-container-plugin/pkg/cli"
13+
"github.com/thin-edge/tedge-container-plugin/pkg/container"
14+
)
15+
16+
// listCmd represents the list command
17+
func NewListCommand(cliContext cli.Cli) *cobra.Command {
18+
return &cobra.Command{
19+
Use: "list",
20+
Short: "List containers",
21+
Args: cobra.ExactArgs(0),
22+
RunE: func(cmd *cobra.Command, args []string) error {
23+
slog.Info("Executing", "cmd", cmd.CalledAs(), "args", args)
24+
ctx := context.Background()
25+
cli, err := container.NewContainerClient(ctx, cliContext.GetContainerClientOptions()...)
26+
if err != nil {
27+
return err
28+
}
29+
containers, err := cli.List(ctx, cliContext.GetFilterOptions())
30+
if err != nil {
31+
return err
32+
}
33+
stdout := cmd.OutOrStdout()
34+
for _, item := range containers {
35+
switch item.ServiceType {
36+
case container.ContainerType:
37+
fmt.Fprintf(stdout, "%s\n", item.Name)
38+
case container.ContainerGroupType:
39+
// TODO: Should container groups actually reference use <project>@<service>
40+
// so it is easier for users to see the mapping? Or just create a new container-group-logs
41+
// subcommand to handle this independently
42+
fmt.Fprintf(stdout, "%s\n", item.Container.Name)
43+
}
44+
}
45+
return nil
46+
},
47+
}
48+
}

cli/log_plugins/cmd.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package log_plugins
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"github.com/thin-edge/tedge-container-plugin/cli/log_plugins/container_group_plugin"
6+
"github.com/thin-edge/tedge-container-plugin/cli/log_plugins/container_plugin"
7+
"github.com/thin-edge/tedge-container-plugin/pkg/cli"
8+
)
9+
10+
// NewCommand returns a cobra command for `logs` subcommands
11+
func NewCommand(cmdCli cli.Cli) *cobra.Command {
12+
cmd := &cobra.Command{
13+
Use: "log-plugins",
14+
Short: "log plugins",
15+
}
16+
cmd.AddCommand(
17+
container_group_plugin.NewCommand(cmdCli),
18+
container_plugin.NewCommand(cmdCli),
19+
)
20+
return cmd
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
Copyright © 2024 thin-edge.io <[email protected]>
3+
*/
4+
package container_group_plugin
5+
6+
import (
7+
"github.com/spf13/cobra"
8+
"github.com/thin-edge/tedge-container-plugin/pkg/cli"
9+
)
10+
11+
// NewCommand returns a cobra command for `container-group` subcommands
12+
func NewCommand(cmdCli cli.Cli) *cobra.Command {
13+
cmd := &cobra.Command{
14+
Use: "container-group",
15+
Short: "container-group logs plugin",
16+
}
17+
cmd.AddCommand(
18+
NewListCommand(cmdCli),
19+
NewGetCommand(cmdCli),
20+
)
21+
return cmd
22+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
Copyright © 2024 thin-edge.io <[email protected]>
3+
*/
4+
package container_group_plugin
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"log/slog"
10+
11+
"github.com/spf13/cobra"
12+
"github.com/thin-edge/tedge-container-plugin/pkg/cli"
13+
"github.com/thin-edge/tedge-container-plugin/pkg/container"
14+
)
15+
16+
type ContainerLogsCommand struct {
17+
*cobra.Command
18+
19+
CommandContext cli.Cli
20+
21+
// Options
22+
Since string
23+
Until string
24+
}
25+
26+
func NewGetCommand(ctx cli.Cli) *cobra.Command {
27+
command := &ContainerLogsCommand{
28+
CommandContext: ctx,
29+
}
30+
cmd := &cobra.Command{
31+
Use: "get",
32+
Short: "Get container-group logs",
33+
RunE: command.RunE,
34+
Args: cobra.ExactArgs(1),
35+
SilenceUsage: true,
36+
}
37+
38+
cmd.Flags().StringVar(&command.Since, "since", "", "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)")
39+
cmd.Flags().StringVar(&command.Until, "until", "", "Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)")
40+
command.Command = cmd
41+
return cmd
42+
}
43+
44+
func (c *ContainerLogsCommand) RunE(cmd *cobra.Command, args []string) error {
45+
slog.Info("Executing", "cmd", cmd.CalledAs(), "args", args)
46+
47+
containerCli, err := container.NewContainerClient(context.TODO(), c.CommandContext.GetContainerClientOptions()...)
48+
if err != nil {
49+
return err
50+
}
51+
52+
ctx := context.Background()
53+
54+
// lookup
55+
projectName, serviceName, found := container.ParseContainerGroup(args[0])
56+
if !found {
57+
return fmt.Errorf("invalid service name. expected name in format of '<project>@<service>'")
58+
}
59+
services, err := containerCli.LookupProject(context.Background(), projectName, serviceName)
60+
if err != nil {
61+
return err
62+
}
63+
64+
if len(services) == 0 {
65+
slog.Info("No matching services found")
66+
return nil
67+
}
68+
69+
// containerCli.List(context.Background(), container.FilterOptions{})
70+
71+
// Write container logs (stdout and stderr) to stdout
72+
out := cmd.OutOrStdout()
73+
slog.Info("Fetching logs", "id", services[0].ID, "name", services[0].Names)
74+
err = containerCli.ContainerLogs(ctx, out, services[0].ID, container.LogsOptions{
75+
ShowStdout: true,
76+
ShowStderr: true,
77+
Since: c.Since,
78+
Until: c.Until,
79+
Timestamps: false,
80+
Follow: false,
81+
Tail: "100000",
82+
Details: false,
83+
})
84+
if err != nil {
85+
return err
86+
}
87+
return nil
88+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
Copyright © 2024 thin-edge.io <[email protected]>
3+
*/
4+
package container_group_plugin
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"log/slog"
10+
11+
"github.com/spf13/cobra"
12+
"github.com/thin-edge/tedge-container-plugin/pkg/cli"
13+
"github.com/thin-edge/tedge-container-plugin/pkg/container"
14+
)
15+
16+
// listCmd represents the list command
17+
func NewListCommand(cliContext cli.Cli) *cobra.Command {
18+
return &cobra.Command{
19+
Use: "list",
20+
Short: "List logs for the container-group type",
21+
Args: cobra.ExactArgs(0),
22+
RunE: func(cmd *cobra.Command, args []string) error {
23+
slog.Info("Executing", "cmd", cmd.CalledAs(), "args", args)
24+
ctx := context.Background()
25+
cli, err := container.NewContainerClient(ctx, cliContext.GetContainerClientOptions()...)
26+
if err != nil {
27+
return err
28+
}
29+
containers, err := cli.List(ctx, cliContext.GetFilterOptions())
30+
if err != nil {
31+
return err
32+
}
33+
stdout := cmd.OutOrStdout()
34+
for _, item := range containers {
35+
if item.ServiceType == container.ContainerGroupType {
36+
fmt.Fprintf(stdout, "%s\n", item.Name)
37+
}
38+
}
39+
return nil
40+
},
41+
}
42+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package container_plugin
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"github.com/thin-edge/tedge-container-plugin/pkg/cli"
6+
)
7+
8+
// NewCommand returns a cobra command for `container-logs` subcommands
9+
func NewCommand(cmdCli cli.Cli) *cobra.Command {
10+
cmd := &cobra.Command{
11+
Use: "container",
12+
Short: "container logs plugin",
13+
}
14+
cmd.AddCommand(
15+
NewListCommand(cmdCli),
16+
NewGetCommand(cmdCli),
17+
)
18+
return cmd
19+
}

0 commit comments

Comments
 (0)