Skip to content
This repository has been archived by the owner on Mar 2, 2024. It is now read-only.

KM225: Truncate client log #444

Merged
merged 5 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions pkg/client/core/api/rest/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"net/http"
"strings"

"github.com/oslokommune/okctl/pkg/truncate"

validation "github.com/go-ozzo/ozzo-validation/v4"

"github.com/mishudark/errors"
Expand Down Expand Up @@ -84,9 +86,13 @@ func (c *HTTPClient) Do(method, endpoint string, body interface{}, into interfac
err = resp.Body.Close()
}()

const logLineMaxlength = 5000

if into != nil {
if c.Debug {
_, err = fmt.Fprintf(c.Progress, "client (method: %s, endpoint: %s) received data: %s", method, endpoint, out)
truncatedOut := truncate.Bytes(out, logLineMaxlength)

_, err = fmt.Fprintf(c.Progress, "client (method: %s, endpoint: %s) received data: %s", method, endpoint, truncatedOut)
if err != nil {
return fmt.Errorf("failed to write debug output: %w", err)
}
Expand All @@ -99,7 +105,9 @@ func (c *HTTPClient) Do(method, endpoint string, body interface{}, into interfac
}

if c.Debug {
_, err = io.Copy(c.Progress, strings.NewReader(string(out)))
truncatedOut := truncate.Bytes(out, logLineMaxlength)

_, err = io.Copy(c.Progress, strings.NewReader(string(truncatedOut)))
if err != nil {
return fmt.Errorf("%s: %w", pretty("failed to write progress for", method, endpoint), err)
}
Expand Down
20 changes: 3 additions & 17 deletions pkg/middleware/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"strings"
"time"

"github.com/oslokommune/okctl/pkg/truncate"

"github.com/go-kit/kit/endpoint"
"github.com/sanity-io/litter"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -79,25 +81,9 @@ func (l *logging) ProcessResponse(err error, response interface{}, begin time.Ti
d = litter.Sdump(response)
}

truncatedDump := Truncate(&d, 5000)
truncatedDump := truncate.String(&d, 5000)
l.log.Trace("response: ", truncatedDump)
}

l.log.Debug("request completed in: ", time.Since(begin).String())
}

// Truncate truncates a string to the minimum of its length and the given max length
func Truncate(s *string, maxLength int) string {
// This way of doing substrings assumes ASCII and doesn't support UTF-8.
// See https://stackoverflow.com/a/56129336
truncateLength := min(maxLength, len(*s))
return (*s)[:truncateLength]
}

func min(x, y int) int {
if x < y {
return x
}

return y
}
34 changes: 0 additions & 34 deletions pkg/middleware/logger/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,37 +76,3 @@ func TestLogging(t *testing.T) {
})
}
}

func TestTruncate(t *testing.T) {
testCases := []struct {
name string
input string
maxLength int
expected string
}{
{
name: "Should truncate string",
input: "1234567890",
maxLength: 5,
expected: "12345",
},
{
name: "Should keep string if it's equal to maxLength",
input: "1234567890",
maxLength: 10,
expected: "1234567890",
},
{
name: "Should keep string if it's over maxLength",
input: "1234567890",
maxLength: 11,
expected: "1234567890",
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.expected, logger.Truncate(&tc.input, tc.maxLength))
})
}
}
42 changes: 42 additions & 0 deletions pkg/truncate/truncate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Package truncate implements truncating variables
package truncate

import "fmt"

// String truncates a string to the minimum of its length and the given max length
func String(s *string, maxLength int) string {
// This way of doing substrings assumes ASCII and doesn't support UTF-8.
// See https://stackoverflow.com/a/56129336
truncateLength := min(maxLength, len(*s))
truncated := (*s)[:truncateLength]

if len(*s) > truncateLength {
bytesTruncated := len(*s) - truncateLength
truncated += fmt.Sprintf(" [truncated %d bytes]", bytesTruncated)
}

return truncated
}

// Bytes truncates a byte array to the minimum of its length and the given max length
func Bytes(b []byte, maxLength int) []byte {
truncateLength := min(maxLength, len(b))

truncated := b[:truncateLength]

if len(b) > truncateLength {
bytesTruncated := len(b) - truncateLength
truncateInfo := fmt.Sprintf(" [truncated %d bytes]", bytesTruncated)
truncated = append(truncated, truncateInfo...)
}

return truncated
}

func min(x, y int) int {
if x < y {
return x
}

return y
}
57 changes: 57 additions & 0 deletions pkg/truncate/truncate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package truncate_test

import (
"testing"

"github.com/oslokommune/okctl/pkg/truncate"
"github.com/stretchr/testify/assert"
)

func TestTruncate(t *testing.T) {
testCases := []struct {
name string
input string
maxLength int
expected string
}{
{
name: "Should truncate string",
input: "1234567890",
maxLength: 5,
expected: "12345 [truncated 5 bytes]",
},
{
name: "Should truncate some other string",
input: "1234567890",
maxLength: 7,
expected: "1234567 [truncated 3 bytes]",
},
{
name: "Should keep string if it's equal to maxLength",
input: "1234567890",
maxLength: 10,
expected: "1234567890",
},
{
name: "Should keep string if it's over maxLength",
input: "1234567890",
maxLength: 11,
expected: "1234567890",
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
// Test String string
truncatedString := truncate.String(&tc.input, tc.maxLength)
assert.Equal(t, tc.expected, truncatedString)

// Test String bytes
inputBytes := []byte(tc.input)
truncatedBytes := truncate.Bytes(inputBytes, tc.maxLength)

expectedBytes := []byte(tc.expected)
assert.Equal(t, expectedBytes, truncatedBytes)
})
}
}