abra/cli/app/logs.go

130 lines
2.8 KiB
Go
Raw Normal View History

package app
2021-08-29 12:13:35 +00:00
import (
"context"
2021-08-29 12:13:35 +00:00
"fmt"
"io"
"os"
"sync"
"coopcloud.tech/abra/cli/internal"
2021-12-11 23:17:39 +00:00
"coopcloud.tech/abra/pkg/autocomplete"
2021-09-05 19:37:03 +00:00
"coopcloud.tech/abra/pkg/client"
2021-12-22 00:02:36 +00:00
"coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/service"
2021-08-29 12:13:35 +00:00
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
dockerClient "github.com/docker/docker/client"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
2021-08-29 12:13:35 +00:00
)
2021-12-22 00:02:36 +00:00
var logOpts = types.ContainerLogsOptions{
Details: false,
Follow: true,
ShowStderr: true,
ShowStdout: true,
Tail: "20",
Timestamps: true,
}
2021-08-29 12:13:35 +00:00
// stackLogs lists logs for all stack services
func stackLogs(c *cli.Context, app config.App, client *dockerClient.Client) {
filters, err := app.Filters(true, false)
if err != nil {
logrus.Fatal(err)
}
2021-08-29 12:13:35 +00:00
serviceOpts := types.ServiceListOptions{Filters: filters}
services, err := client.ServiceList(context.Background(), serviceOpts)
2021-08-29 12:13:35 +00:00
if err != nil {
logrus.Fatal(err)
}
var wg sync.WaitGroup
for _, service := range services {
wg.Add(1)
go func(s string) {
2021-12-22 00:02:36 +00:00
if internal.StdErrOnly {
logOpts.ShowStdout = false
2021-08-29 12:13:35 +00:00
}
2021-12-22 00:02:36 +00:00
logs, err := client.ServiceLogs(context.Background(), s, logOpts)
2021-08-31 15:47:38 +00:00
if err != nil {
logrus.Fatal(err)
}
2021-08-29 12:13:35 +00:00
defer logs.Close()
_, err = io.Copy(os.Stdout, logs)
if err != nil && err != io.EOF {
logrus.Fatal(err)
}
}(service.ID)
}
2021-08-29 12:13:35 +00:00
wg.Wait()
2021-08-29 12:13:35 +00:00
os.Exit(0)
}
var appLogsCommand = cli.Command{
Name: "logs",
2021-09-04 23:34:56 +00:00
Aliases: []string{"l"},
2022-01-25 12:48:04 +00:00
ArgsUsage: "<domain> [<service>]",
2021-09-04 23:34:56 +00:00
Usage: "Tail app logs",
2021-12-22 00:02:36 +00:00
Flags: []cli.Flag{
internal.StdErrOnlyFlag,
internal.DebugFlag,
2021-12-22 00:02:36 +00:00
},
Before: internal.SubCommandBefore,
2021-12-22 00:02:36 +00:00
BashComplete: autocomplete.AppNameComplete,
2021-08-29 12:13:35 +00:00
Action: func(c *cli.Context) error {
app := internal.ValidateApp(c)
2021-08-29 12:13:35 +00:00
cl, err := client.New(app.Server)
2021-08-29 12:13:35 +00:00
if err != nil {
logrus.Fatal(err)
}
serviceName := c.Args().Get(1)
if serviceName == "" {
2022-01-25 11:37:13 +00:00
logrus.Debugf("tailing logs for all %s services", app.Recipe)
stackLogs(c, app, cl)
2021-12-22 00:02:36 +00:00
} else {
logrus.Debugf("tailing logs for %s", serviceName)
2021-12-22 00:03:36 +00:00
if err := tailServiceLogs(c, cl, app, serviceName); err != nil {
2021-12-22 00:02:36 +00:00
logrus.Fatal(err)
}
2021-08-29 12:13:35 +00:00
}
2021-12-22 00:02:36 +00:00
return nil
},
}
2021-08-29 12:13:35 +00:00
2021-12-22 00:02:36 +00:00
func tailServiceLogs(c *cli.Context, cl *dockerClient.Client, app config.App, serviceName string) error {
filters := filters.NewArgs()
filters.Add("name", fmt.Sprintf("^%s_%s", app.StackName(), serviceName))
chosenService, err := service.GetService(context.Background(), cl, filters, internal.NoInput)
2021-12-22 00:02:36 +00:00
if err != nil {
logrus.Fatal(err)
}
2021-08-29 12:13:35 +00:00
2021-12-22 00:02:36 +00:00
if internal.StdErrOnly {
logOpts.ShowStdout = false
}
2021-08-29 12:13:35 +00:00
logs, err := cl.ServiceLogs(context.Background(), chosenService.ID, logOpts)
2021-12-22 00:02:36 +00:00
if err != nil {
logrus.Fatal(err)
}
defer logs.Close()
_, err = io.Copy(os.Stdout, logs)
if err != nil && err != io.EOF {
logrus.Fatal(err)
}
return nil
}