Implement `docker logs --tal <N>`

This commit is contained in:
Djordje Lukic 2020-05-04 16:38:02 +02:00
parent 1c7270b697
commit e964a3af2e
4 changed files with 40 additions and 9 deletions

View File

@ -4,6 +4,8 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"strconv"
"strings"
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
"github.com/Azure/go-autorest/autorest/azure/auth" "github.com/Azure/go-autorest/autorest/azure/auth"
@ -139,11 +141,24 @@ func (cs *containerService) Exec(ctx context.Context, name string, command strin
) )
} }
func (cs *containerService) Logs(ctx context.Context, name string, writer io.Writer, follow bool) error { func (cs *containerService) Logs(ctx context.Context, containerName string, req containers.LogsRequest) error {
logs, err := getACIContainerLogs(ctx, cs.ctx, name, name) logs, err := getACIContainerLogs(ctx, cs.ctx, containerName, containerName)
if err != nil { if err != nil {
return err return err
} }
_, err = fmt.Fprint(writer, logs) if req.Tail != "all" {
tail, err := strconv.Atoi(req.Tail)
if err != nil {
return err
}
lines := strings.Split(logs, "\n")
// If asked for less lines than exist, take only those lines
if tail <= len(lines) {
logs = strings.Join(lines[len(lines)-tail:], "\n")
}
}
_, err = fmt.Fprint(req.Writer, logs)
return err return err
} }

View File

@ -4,13 +4,16 @@ import (
"context" "context"
"os" "os"
"github.com/docker/api/client"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/docker/api/client"
"github.com/docker/api/containers"
) )
type logsOpts struct { type logsOpts struct {
Follow bool Follow bool
Tail string
} }
func LogsCommand() *cobra.Command { func LogsCommand() *cobra.Command {
@ -25,15 +28,22 @@ func LogsCommand() *cobra.Command {
} }
cmd.Flags().BoolVarP(&opts.Follow, "follow", "f", false, "Follow log outut") cmd.Flags().BoolVarP(&opts.Follow, "follow", "f", false, "Follow log outut")
cmd.Flags().StringVar(&opts.Tail, "tail", "all", "Number of lines to show from the end of the logs")
return cmd return cmd
} }
func runLogs(ctx context.Context, name string, opts logsOpts) error { func runLogs(ctx context.Context, containerName string, opts logsOpts) error {
c, err := client.New(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return errors.Wrap(err, "cannot connect to backend") return errors.Wrap(err, "cannot connect to backend")
} }
return c.ContainerService().Logs(ctx, name, os.Stdout, opts.Follow) req := containers.LogsRequest{
Follow: opts.Follow,
Tail: opts.Tail,
Writer: os.Stdout,
}
return c.ContainerService().Logs(ctx, containerName, req)
} }

View File

@ -37,6 +37,12 @@ type ContainerConfig struct {
Ports []Port Ports []Port
} }
type LogsRequest struct {
Follow bool
Tail string
Writer io.Writer
}
// ContainerService interacts with the underlying container backend // ContainerService interacts with the underlying container backend
type ContainerService interface { type ContainerService interface {
// List returns all the containers // List returns all the containers
@ -46,5 +52,5 @@ type ContainerService interface {
// Exec executes a command inside a running container // Exec executes a command inside a running container
Exec(ctx context.Context, containerName string, command string, reader io.Reader, writer io.Writer) error Exec(ctx context.Context, containerName string, command string, reader io.Reader, writer io.Writer) error
// Logs returns all the logs of a container // Logs returns all the logs of a container
Logs(ctx context.Context, name string, writer io.Writer, follow bool) error Logs(ctx context.Context, containerName string, request LogsRequest) error
} }

View File

@ -44,7 +44,7 @@ func (cs *containerService) Exec(ctx context.Context, name string, command strin
return nil return nil
} }
func (cs *containerService) Logs(ctx context.Context, name string, writer io.Writer, follow bool) error { func (cs *containerService) Logs(ctx context.Context, containerName string, request containers.LogsRequest) error {
fmt.Fprintf(writer, "Following logs for container %q", name) fmt.Fprintf(request.Writer, "Following logs for container %q", containerName)
return nil return nil
} }