forked from coop-cloud/abra
feat: pick stdout/stderr for abra app logs
This commit is contained in:
parent
6c87d501e6
commit
236d0f5892
|
@ -4,74 +4,54 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"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/v2"
|
||||
)
|
||||
|
||||
// stackLogs lists logs for all stack services
|
||||
func stackLogs(c *cli.Context, stackName string, client *dockerClient.Client) {
|
||||
filters := filters.NewArgs()
|
||||
filters.Add("name", stackName)
|
||||
serviceOpts := types.ServiceListOptions{Filters: filters}
|
||||
services, err := client.ServiceList(c.Context, serviceOpts)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for _, service := range services {
|
||||
wg.Add(1)
|
||||
go func(s string) {
|
||||
logOpts := types.ContainerLogsOptions{
|
||||
Details: false,
|
||||
Follow: true,
|
||||
ShowStderr: true,
|
||||
ShowStdout: true,
|
||||
Tail: "20",
|
||||
Timestamps: true,
|
||||
}
|
||||
logs, err := client.ServiceLogs(c.Context, s, logOpts)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
// defer after err check as any err returns a nil io.ReadCloser
|
||||
defer logs.Close()
|
||||
|
||||
_, err = io.Copy(os.Stdout, logs)
|
||||
if err != nil && err != io.EOF {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}(service.ID)
|
||||
}
|
||||
wg.Wait()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
var appLogsCommand = &cli.Command{
|
||||
Name: "logs",
|
||||
Aliases: []string{"l"},
|
||||
ArgsUsage: "[<service>]",
|
||||
Usage: "Tail app logs",
|
||||
Flags: []cli.Flag{
|
||||
internal.StderrFlag,
|
||||
internal.StdoutFlag,
|
||||
internal.HealthcheckFlag,
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
|
||||
if !internal.Stderr && !internal.Stdout && !internal.Healthcheck {
|
||||
internal.Stderr = true
|
||||
internal.Stdout = true
|
||||
internal.Healthcheck = true
|
||||
}
|
||||
|
||||
logrus.Debugf("flags parsed. --stderr: %t, --stdout: %t, --healthcheck: %t", internal.Stderr, internal.Stdout, internal.Healthcheck)
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
logOpts := types.ContainerLogsOptions{
|
||||
Details: false,
|
||||
Follow: true,
|
||||
ShowStderr: internal.Stderr,
|
||||
ShowStdout: internal.Stdout,
|
||||
Tail: "20",
|
||||
Timestamps: true,
|
||||
}
|
||||
|
||||
serviceName := c.Args().Get(1)
|
||||
if serviceName == "" {
|
||||
logrus.Debug("tailing logs for all app services")
|
||||
stackLogs(c, app.StackName(), cl)
|
||||
internal.StackLogs(c, app.StackName(), logOpts, cl)
|
||||
}
|
||||
logrus.Debugf("tailing logs for '%s'", serviceName)
|
||||
|
||||
|
@ -87,14 +67,6 @@ var appLogsCommand = &cli.Command{
|
|||
logrus.Fatalf("expected 1 service but got %v", len(services))
|
||||
}
|
||||
|
||||
logOpts := types.ContainerLogsOptions{
|
||||
Details: false,
|
||||
Follow: true,
|
||||
ShowStderr: true,
|
||||
ShowStdout: true,
|
||||
Tail: "20",
|
||||
Timestamps: true,
|
||||
}
|
||||
logs, err := cl.ServiceLogs(c.Context, services[0].ID, logOpts)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"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/v2"
|
||||
)
|
||||
|
||||
var Stderr bool
|
||||
var StderrFlag = &cli.BoolFlag{
|
||||
Name: "stderr",
|
||||
Aliases: []string{"e"},
|
||||
Value: false,
|
||||
Destination: &Stderr,
|
||||
}
|
||||
|
||||
var Stdout bool
|
||||
var StdoutFlag = &cli.BoolFlag{
|
||||
Name: "stdout",
|
||||
Aliases: []string{"o"},
|
||||
Value: false,
|
||||
Destination: &Stdout,
|
||||
}
|
||||
|
||||
var Healthcheck bool
|
||||
var HealthcheckFlag = &cli.BoolFlag{
|
||||
Name: "healthcheck",
|
||||
Aliases: []string{"c"},
|
||||
Value: false,
|
||||
Destination: &Healthcheck,
|
||||
}
|
||||
|
||||
// StackLogs lists logs for all stack services
|
||||
func StackLogs(c *cli.Context, stackName string, logOpts types.ContainerLogsOptions, client *dockerClient.Client) {
|
||||
filters := filters.NewArgs()
|
||||
filters.Add("name", stackName)
|
||||
serviceOpts := types.ServiceListOptions{Filters: filters}
|
||||
services, err := client.ServiceList(c.Context, serviceOpts)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for _, service := range services {
|
||||
wg.Add(1)
|
||||
go func(s string) {
|
||||
logs, err := client.ServiceLogs(c.Context, s, logOpts)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
// defer after err check as any err returns a nil io.ReadCloser
|
||||
defer logs.Close()
|
||||
|
||||
_, err = io.Copy(os.Stdout, logs)
|
||||
if err != nil && err != io.EOF {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}(service.ID)
|
||||
}
|
||||
wg.Wait()
|
||||
os.Exit(0)
|
||||
}
|
Loading…
Reference in New Issue