Follow logs on ACI.

This is not ideal, the ACI API doesn't give us a stream of logs, so we
need to fake it by moving the cursor up and rewriting the logs to
stdout. This means that, on gRPC side, we will stream the whole logs
each time. This is ok for now but we need to push Azure to give us a
real streaming API for logs
This commit is contained in:
Djordje Lukic 2020-06-30 12:23:22 +02:00
parent e5e87d3357
commit 06596dcd90
2 changed files with 45 additions and 5 deletions

View File

@ -21,6 +21,7 @@ import (
"fmt"
"io"
"net/http"
"strings"
"time"
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
@ -29,6 +30,7 @@ import (
tm "github.com/buger/goterm"
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
"github.com/morikuni/aec"
"github.com/pkg/errors"
"github.com/docker/api/azure/login"
@ -234,6 +236,42 @@ func getACIContainerLogs(ctx context.Context, aciContext store.AciContext, conta
return *logs.Content, err
}
func streamLogs(ctx context.Context, aciContext store.AciContext, containerGroupName, containerName string, out io.Writer) error {
lastOutput := 0
for {
select {
case <-ctx.Done():
return nil
default:
logs, err := getACIContainerLogs(ctx, aciContext, containerGroupName, containerName, nil)
if err != nil {
return err
}
logLines := strings.Split(logs, "\n")
currentOutput := len(logLines)
b := aec.EmptyBuilder
for i := 0; i < lastOutput; i++ {
b = b.Up(1)
}
// Note: a backend should not do this normally, this breaks the log
// streaming over gRPC but this is the only thing we can do with
// the kind of logs ACI is giving us. Hopefully Azue will give us
// a real logs streaming api soon.
fmt.Fprint(out, b.Column(0).ANSI)
for i := 0; i < currentOutput-1; i++ {
fmt.Fprintln(out, logLines[i])
}
lastOutput = currentOutput - 1
time.Sleep(2 * time.Second)
}
}
}
func getContainerGroupsClient(subscriptionID string) (containerinstance.ContainerGroupsClient, error) {
containerGroupsClient := containerinstance.NewContainerGroupsClient(subscriptionID)
err := setupClient(&containerGroupsClient.Client)

View File

@ -24,12 +24,8 @@ import (
"strconv"
"strings"
"github.com/Azure/go-autorest/autorest/to"
"github.com/docker/api/context/cloud"
"github.com/docker/api/errdefs"
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
"github.com/Azure/go-autorest/autorest/to"
"github.com/compose-spec/compose-go/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -40,7 +36,9 @@ import (
"github.com/docker/api/compose"
"github.com/docker/api/containers"
apicontext "github.com/docker/api/context"
"github.com/docker/api/context/cloud"
"github.com/docker/api/context/store"
"github.com/docker/api/errdefs"
)
const singleContainerName = "single--container--aci"
@ -238,6 +236,10 @@ func (cs *aciContainerService) Logs(ctx context.Context, containerName string, r
groupName, containerAciName := getGroupAndContainerName(containerName)
var tail *int32
if req.Follow {
return streamLogs(ctx, cs.ctx, groupName, containerAciName, req.Writer)
}
if req.Tail != "all" {
reqTail, err := strconv.Atoi(req.Tail)
if err != nil {