Skip to content

Commit

Permalink
refactor(logs): Use native TailLogs SDK method (#1469)
Browse files Browse the repository at this point in the history
Reviewed-by: Cezar Craciunoiu <[email protected]>
Approved-by: Cezar Craciunoiu <[email protected]>
  • Loading branch information
craciunoiuc authored Apr 10, 2024
2 parents 8a1146e + b0a4997 commit 1cbcbcf
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 133 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ require (
k8s.io/apimachinery v0.29.3
k8s.io/apiserver v0.29.3
oras.land/oras-go/v2 v2.5.0
sdk.kraft.cloud v0.5.5-0.20240408130935-44faa2c974b3
sdk.kraft.cloud v0.5.5-0.20240410102038-8d0f0333b17a
sigs.k8s.io/kustomize/kyaml v0.14.3
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1677,8 +1677,8 @@ oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZH
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sdk.kraft.cloud v0.5.5-0.20240408130935-44faa2c974b3 h1:WNGjGRijO9vHa2DOVqOAJXqL+RBhsdkQAG/Jb9JmQnk=
sdk.kraft.cloud v0.5.5-0.20240408130935-44faa2c974b3/go.mod h1:u88mmv6PoEASnMLNkyYgrMCzJ4tkMGurV8ZMvXA9a2I=
sdk.kraft.cloud v0.5.5-0.20240410102038-8d0f0333b17a h1:23i4O5zQRjwqpFslVVdgcR3Kj42Qw7XGfGHPbufoqFs=
sdk.kraft.cloud v0.5.5-0.20240410102038-8d0f0333b17a/go.mod h1:u88mmv6PoEASnMLNkyYgrMCzJ4tkMGurV8ZMvXA9a2I=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I=
Expand Down
143 changes: 13 additions & 130 deletions internal/cli/kraft/cloud/instance/logs/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,18 @@ package logs

import (
"context"
"encoding/base64"
"errors"
"fmt"
"strings"
"time"

"github.com/MakeNowJust/heredoc"
"github.com/spf13/cobra"

kraftcloud "sdk.kraft.cloud"
kcinstances "sdk.kraft.cloud/instances"

"kraftkit.sh/cmdfactory"
"kraftkit.sh/config"
"kraftkit.sh/internal/cli/kraft/cloud/utils"
"kraftkit.sh/iostreams"
"kraftkit.sh/log"
)

const (
defaultPageSize = 4096
maxPageSize = defaultPageSize*4 - 1
maxPossibleBytes = 1024 * 1024 * 1024
)

type LogOptions struct {
Expand Down Expand Up @@ -91,37 +80,13 @@ func (opts *LogOptions) Pre(cmd *cobra.Command, _ []string) error {
}

if opts.Tail < -1 {
return fmt.Errorf("invalid value for --tail: %d, should be -1, or positive", opts.Tail)
}

if opts.Follow && opts.Tail == -1 {
opts.Tail = 100
return fmt.Errorf("invalid value for --tail: %d, should be -1 for all logs, or positive for length of truncated logs", opts.Tail)
}

return nil
}

func (opts *LogOptions) logsFetchDecode(ctx context.Context, client kcinstances.InstancesService, image string, offset, limit int) ([]byte, *kcinstances.LogResponseItem, error) {
logResp, err := client.WithMetro(opts.metro).Log(ctx, image, offset, limit)
if err != nil {
return nil, nil, fmt.Errorf("could not retrieve logs: %w", err)
}
log, err := logResp.FirstOrErr()
if err != nil {
return nil, nil, fmt.Errorf("could not retrieve logs: %w", err)
}

outputPart, err := base64.StdEncoding.DecodeString(log.Output)
if err != nil {
return nil, nil, fmt.Errorf("decoding base64 console output: %w", err)
}

return outputPart, log, nil
}

func (opts *LogOptions) Run(ctx context.Context, args []string) error {
var offset, limit int

auth, err := config.GetKraftCloudAuthConfig(ctx, opts.token)
if err != nil {
return fmt.Errorf("could not retrieve credentials: %w", err)
Expand All @@ -131,103 +96,21 @@ func (opts *LogOptions) Run(ctx context.Context, args []string) error {
kraftcloud.WithToken(config.GetKraftCloudTokenAuthConfig(*auth)),
)

if opts.Follow {
offset = -defaultPageSize
limit = maxPageSize

for {
output, resp, err := opts.logsFetchDecode(ctx, client, args[0], offset, limit)
if err != nil {
if errors.Is(err, context.Canceled) {
return nil
}
return err
}

// Split the output by line and print each line separately to
// be able to limit the output to the last N lines.
// Truncate the last line if it's not a full line.
if len(output) > 0 {
split := strings.Split(string(output), "\n")
linesToSkip := len(split) - opts.Tail
for i, line := range split {
if i < linesToSkip {
continue
}

if i == len(split)-1 && output[len(output)-1] != '\n' {
offset = resp.Range.End - len(line)
} else {
if i == len(split)-1 {
offset = resp.Range.End
}
fmt.Fprintf(iostreams.G(ctx).Out, "%s\n", line)
}
}
}

time.Sleep(500 * time.Millisecond)
}
logChan, errChan, err := client.TailLogs(ctx, args[0], opts.Follow, opts.Tail, 500*time.Millisecond)
if err != nil {
return fmt.Errorf("initializing log tailing: %w", err)
}

var output []byte
if opts.Tail >= 0 {
lines := 0
for i := 1; lines < opts.Tail; i++ {
offset = i * -defaultPageSize
limit = defaultPageSize

outputPart, resp, err := opts.logsFetchDecode(ctx, client, args[0], offset, limit)
if err != nil {
return err
}

outputPart = append(outputPart, output...)
output = outputPart

if resp.Range.Start == resp.Available.Start {
break
for {
select {
case <-ctx.Done():
return nil
case err := <-errChan:
return err
case line, ok := <-logChan:
if ok {
fmt.Fprintf(iostreams.G(ctx).Out, "%s\n", line)
}

lines += strings.Count(string(outputPart), "\n")
}

split := strings.Split(string(output), "\n")
start := len(split) - opts.Tail
if start < 0 {
start = 0
}
for i := start; i < len(split); i++ {
fmt.Fprintf(iostreams.G(ctx).Out, "%s\n", split[i])
}
} else {
// The same as above, but fetch the max possible amount of logs.
// Stop only when there are no more logs to fetch.
for i := 4; ; i = i + 4 {
offset = i * -defaultPageSize
limit = maxPageSize

outputPart, resp, err := opts.logsFetchDecode(ctx, client, args[0], offset, limit)
if err != nil {
return err
}

outputPart = append(outputPart, output...)
output = outputPart

if resp.Range.Start == resp.Available.Start {
break
}

if len(output) > maxPossibleBytes {
log.G(ctx).Warnf("The maximum amount of logs has been reached. Stopping.")
fmt.Fprintf(iostreams.G(ctx).Out, "%s\n", output)
break
}
}

fmt.Fprintf(iostreams.G(ctx).Out, "%s\n", output)
}

return nil
}

0 comments on commit 1cbcbcf

Please sign in to comment.