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"
"fmt"
"io"
"strconv"
"strings"
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
"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 {
logs, err := getACIContainerLogs(ctx, cs.ctx, name, name)
func (cs *containerService) Logs(ctx context.Context, containerName string, req containers.LogsRequest) error {
logs, err := getACIContainerLogs(ctx, cs.ctx, containerName, containerName)
if err != nil {
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
}

View File

@ -4,13 +4,16 @@ import (
"context"
"os"
"github.com/docker/api/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/api/client"
"github.com/docker/api/containers"
)
type logsOpts struct {
Follow bool
Tail string
}
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().StringVar(&opts.Tail, "tail", "all", "Number of lines to show from the end of the logs")
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)
if err != nil {
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
}
type LogsRequest struct {
Follow bool
Tail string
Writer io.Writer
}
// ContainerService interacts with the underlying container backend
type ContainerService interface {
// List returns all the containers
@ -46,5 +52,5 @@ type ContainerService interface {
// Exec executes a command inside a running container
Exec(ctx context.Context, containerName string, command string, reader io.Reader, writer io.Writer) error
// 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
}
func (cs *containerService) Logs(ctx context.Context, name string, writer io.Writer, follow bool) error {
fmt.Fprintf(writer, "Following logs for container %q", name)
func (cs *containerService) Logs(ctx context.Context, containerName string, request containers.LogsRequest) error {
fmt.Fprintf(request.Writer, "Following logs for container %q", containerName)
return nil
}