mirror of https://github.com/docker/compose.git
Merge pull request #1073 from docker/logs_service
allow to collect logs for a subset of project services
This commit is contained in:
commit
76ba85fe5d
|
@ -194,7 +194,7 @@ func (cs *aciComposeService) List(ctx context.Context, project string) ([]compos
|
|||
return stacks, nil
|
||||
}
|
||||
|
||||
func (cs *aciComposeService) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer) error {
|
||||
func (cs *aciComposeService) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer, options compose.LogOptions) error {
|
||||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ func (c *composeService) Down(context.Context, string) error {
|
|||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (c *composeService) Logs(context.Context, string, compose.LogConsumer) error {
|
||||
func (c *composeService) Logs(context.Context, string, compose.LogConsumer, compose.LogOptions) error {
|
||||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ type Service interface {
|
|||
// Down executes the equivalent to a `compose down`
|
||||
Down(ctx context.Context, projectName string) error
|
||||
// Logs executes the equivalent to a `compose logs`
|
||||
Logs(ctx context.Context, projectName string, consumer LogConsumer) error
|
||||
Logs(ctx context.Context, projectName string, consumer LogConsumer, options LogOptions) error
|
||||
// Ps executes the equivalent to a `compose ps`
|
||||
Ps(ctx context.Context, projectName string) ([]ContainerSummary, error)
|
||||
// List executes the equivalent to a `docker stack ls`
|
||||
|
@ -76,6 +76,11 @@ type ServiceStatus struct {
|
|||
Publishers []PortPublisher
|
||||
}
|
||||
|
||||
// LogOptions defines optional parameters for the `Log` API
|
||||
type LogOptions struct {
|
||||
Services []string
|
||||
}
|
||||
|
||||
const (
|
||||
// STARTING indicates that stack is being deployed
|
||||
STARTING string = "Starting"
|
||||
|
|
|
@ -21,18 +21,18 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/docker/compose-cli/api/client"
|
||||
"github.com/docker/compose-cli/api/compose"
|
||||
"github.com/docker/compose-cli/formatter"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func logsCommand() *cobra.Command {
|
||||
opts := composeOptions{}
|
||||
logsCmd := &cobra.Command{
|
||||
Use: "logs",
|
||||
Use: "logs [service...]",
|
||||
Short: "View output from containers",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runLogs(cmd.Context(), opts)
|
||||
return runLogs(cmd.Context(), opts, args)
|
||||
},
|
||||
}
|
||||
logsCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name")
|
||||
|
@ -42,7 +42,7 @@ func logsCommand() *cobra.Command {
|
|||
return logsCmd
|
||||
}
|
||||
|
||||
func runLogs(ctx context.Context, opts composeOptions) error {
|
||||
func runLogs(ctx context.Context, opts composeOptions, services []string) error {
|
||||
c, err := client.NewWithDefaultLocalBackend(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -53,5 +53,7 @@ func runLogs(ctx context.Context, opts composeOptions) error {
|
|||
return err
|
||||
}
|
||||
consumer := formatter.NewLogConsumer(ctx, os.Stdout)
|
||||
return c.ComposeService().Logs(ctx, projectName, consumer)
|
||||
return c.ComposeService().Logs(ctx, projectName, consumer, compose.LogOptions{
|
||||
Services: services,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ services:
|
|||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (e ecsLocalSimulation) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer) error {
|
||||
func (e ecsLocalSimulation) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer, options compose.LogOptions) error {
|
||||
list, err := e.moby.ContainerList(ctx, types2.ContainerListOptions{
|
||||
Filters: filters.NewArgs(filters.Arg("label", "com.docker.compose.project="+projectName)),
|
||||
})
|
||||
|
|
30
ecs/logs.go
30
ecs/logs.go
|
@ -22,7 +22,35 @@ import (
|
|||
"github.com/docker/compose-cli/api/compose"
|
||||
)
|
||||
|
||||
func (b *ecsAPIService) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer) error {
|
||||
func (b *ecsAPIService) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer, options compose.LogOptions) error {
|
||||
if len(options.Services) > 0 {
|
||||
consumer = filteredLogConsumer(consumer, options.Services)
|
||||
}
|
||||
err := b.aws.GetLogs(ctx, projectName, consumer.Log)
|
||||
return err
|
||||
}
|
||||
|
||||
func filteredLogConsumer(consumer compose.LogConsumer, services []string) compose.LogConsumer {
|
||||
if len(services) == 0 {
|
||||
return consumer
|
||||
}
|
||||
allowed := map[string]bool{}
|
||||
for _, s := range services {
|
||||
allowed[s] = true
|
||||
}
|
||||
return &allowListLogConsumer{
|
||||
allowList: allowed,
|
||||
delegate: consumer,
|
||||
}
|
||||
}
|
||||
|
||||
type allowListLogConsumer struct {
|
||||
allowList map[string]bool
|
||||
delegate compose.LogConsumer
|
||||
}
|
||||
|
||||
func (a *allowListLogConsumer) Log(service, container, message string) {
|
||||
if a.allowList[service] {
|
||||
a.delegate.Log(service, container, message)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ func (cs *composeService) Ps(ctx context.Context, projectName string) ([]compose
|
|||
func (cs *composeService) List(ctx context.Context, project string) ([]compose.Stack, error) {
|
||||
return nil, errdefs.ErrNotImplemented
|
||||
}
|
||||
func (cs *composeService) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer) error {
|
||||
func (cs *composeService) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer, options compose.LogOptions) error {
|
||||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
|
|
|
@ -29,18 +29,31 @@ import (
|
|||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
func (s *composeService) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer) error {
|
||||
func (s *composeService) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer, options compose.LogOptions) error {
|
||||
list, err := s.apiClient.ContainerList(ctx, types.ContainerListOptions{
|
||||
Filters: filters.NewArgs(
|
||||
projectFilter(projectName),
|
||||
),
|
||||
})
|
||||
|
||||
ignore := func(string) bool {
|
||||
return false
|
||||
}
|
||||
if len(options.Services) > 0 {
|
||||
ignore = func(s string) bool {
|
||||
return !contains(options.Services, s)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, c := range list {
|
||||
service := c.Labels[serviceLabel]
|
||||
if ignore(service) {
|
||||
continue
|
||||
}
|
||||
container, err := s.apiClient.ContainerInspect(ctx, c.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue