diff --git a/ecs/cmd/commands/compose.go b/ecs/cmd/commands/compose.go index 18a5bf810..f7a07226d 100644 --- a/ecs/cmd/commands/compose.go +++ b/ecs/cmd/commands/compose.go @@ -22,6 +22,7 @@ func ComposeCommand(dockerCli command.Cli) *cobra.Command { ConvertCommand(dockerCli, opts), UpCommand(dockerCli, opts), DownCommand(dockerCli, opts), + LogsCommand(dockerCli, opts), ) return cmd } @@ -119,3 +120,28 @@ func DownCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *co cmd.Flags().BoolVar(&opts.DeleteCluster, "delete-cluster", false, "Delete cluster") return cmd } + +func LogsCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command { + cmd := &cobra.Command{ + Use: "logs [PROJECT NAME]", + RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error { + client, err := amazon.NewClient(clusteropts.Profile, clusteropts.Cluster, clusteropts.Region) + if err != nil { + return err + } + var name string + + if len(args) == 0 { + project, err := compose.ProjectFromOptions(projectOpts) + if err != nil { + return err + } + name = project.Name + } else { + name = args[0] + } + return client.ComposeLogs(context.Background(), name) + }), + } + return cmd +} diff --git a/ecs/pkg/amazon/api.go b/ecs/pkg/amazon/api.go index 493061850..4fa6ddc44 100644 --- a/ecs/pkg/amazon/api.go +++ b/ecs/pkg/amazon/api.go @@ -5,5 +5,6 @@ package amazon type API interface { downAPI upAPI + logsAPI secretsAPI } diff --git a/ecs/pkg/amazon/logs.go b/ecs/pkg/amazon/logs.go new file mode 100644 index 000000000..b515e25d3 --- /dev/null +++ b/ecs/pkg/amazon/logs.go @@ -0,0 +1,13 @@ +package amazon + +import ( + "context" +) + +func (c *client) ComposeLogs(ctx context.Context, projectName string) error { + return c.api.GetLogs(ctx, projectName) +} + +type logsAPI interface { + GetLogs(ctx context.Context, name string) error +} diff --git a/ecs/pkg/amazon/sdk.go b/ecs/pkg/amazon/sdk.go index f0fc076f5..62736d92b 100644 --- a/ecs/pkg/amazon/sdk.go +++ b/ecs/pkg/amazon/sdk.go @@ -3,6 +3,7 @@ package amazon import ( "context" "fmt" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" @@ -307,3 +308,34 @@ func (s sdk) DeleteSecret(ctx context.Context, id string, recover bool) error { _, err := s.SM.DeleteSecret(&secretsmanager.DeleteSecretInput{SecretId: &id, ForceDeleteWithoutRecovery: &force}) return err } + +func (s sdk) GetLogs(ctx context.Context, name string) error { + logGroup := fmt.Sprintf("/docker-compose/%s", name) + var startTime int64 + for { + var hasMore = true + var token *string + token = nil + for hasMore { + events, err := s.CW.FilterLogEvents(&cloudwatchlogs.FilterLogEventsInput{ + LogGroupName: aws.String(logGroup), + NextToken: token, + StartTime: aws.Int64(startTime), + }) + if err != nil { + return err + } + if events.NextToken == nil { + hasMore = false + } else { + token = events.NextToken + } + + for _, event := range events.Events { + fmt.Println(*event.Message) + startTime = *event.IngestionTime + } + } + time.Sleep(500 * time.Millisecond) + } +} diff --git a/ecs/pkg/compose/api.go b/ecs/pkg/compose/api.go index 70de9aa58..b39afe02d 100644 --- a/ecs/pkg/compose/api.go +++ b/ecs/pkg/compose/api.go @@ -11,6 +11,7 @@ type API interface { Convert(project *Project) (*cloudformation.Template, error) ComposeUp(ctx context.Context, project *Project) error ComposeDown(ctx context.Context, projectName string, deleteCluster bool) error + ComposeLogs(ctx context.Context, projectName string) error CreateSecret(ctx context.Context, secret docker.Secret) (string, error) InspectSecret(ctx context.Context, id string) (docker.Secret, error)