From 1d1f3ed36aec64bfe457bdf658efd1b55f5e9e43 Mon Sep 17 00:00:00 2001 From: Amir Raminfar Date: Wed, 22 May 2024 15:59:54 -0700 Subject: [PATCH] feat: keeps the order of json keys. see fixes #2970 (#2971) --- go.mod | 1 + go.sum | 6 ++---- internal/docker/event_generator.go | 4 +++- internal/docker/event_generator_test.go | 7 ++++--- internal/docker/level_guesser.go | 13 +++++++++++++ internal/docker/level_guesser_test.go | 7 +++++++ 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index f2cb345170f..7d78c766f66 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/go-chi/jwtauth/v5 v5.3.1 github.com/go-logfmt/logfmt v0.6.0 github.com/goccy/go-json v0.10.3 + github.com/iancoleman/orderedmap v0.3.0 github.com/puzpuzpuz/xsync/v3 v3.1.0 github.com/yuin/goldmark v1.7.1 ) diff --git a/go.sum b/go.sum index 03ddbffbf99..707d2c525e6 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,6 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnN github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v26.1.2+incompatible h1:UVX5ZOrrfTGZZYEP+ZDq3Xn9PdHNXaSYMFPDumMqG2k= -github.com/docker/docker v26.1.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo= github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= @@ -47,8 +45,6 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -61,6 +57,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= +github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= diff --git a/internal/docker/event_generator.go b/internal/docker/event_generator.go index aeb870086cc..34e6207222a 100644 --- a/internal/docker/event_generator.go +++ b/internal/docker/event_generator.go @@ -15,6 +15,8 @@ import ( "github.com/goccy/go-json" + "github.com/iancoleman/orderedmap" + "github.com/go-logfmt/logfmt" log "github.com/sirupsen/logrus" ) @@ -170,7 +172,7 @@ func createEvent(message string, streamType StdType) *LogEvent { message = strings.TrimSuffix(message[index+1:], "\n") logEvent.Message = message if json.Valid([]byte(message)) { - var data map[string]interface{} + data := orderedmap.New() if err := json.Unmarshal([]byte(message), &data); err != nil { var jsonErr *json.UnmarshalTypeError if errors.As(err, &jsonErr) { diff --git a/internal/docker/event_generator_test.go b/internal/docker/event_generator_test.go index 8e247335ee3..9e60e0f8be6 100644 --- a/internal/docker/event_generator_test.go +++ b/internal/docker/event_generator_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/iancoleman/orderedmap" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -80,6 +81,8 @@ func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool { } func Test_createEvent(t *testing.T) { + data := orderedmap.New() + data.Set("key", "value") type args struct { message string } @@ -102,9 +105,7 @@ func Test_createEvent(t *testing.T) { message: "2020-05-13T18:55:37.772853839Z {\"key\": \"value\"}", }, want: &LogEvent{ - Message: map[string]interface{}{ - "key": "value", - }, + Message: data, }, }, { diff --git a/internal/docker/level_guesser.go b/internal/docker/level_guesser.go index 49b08e04a7f..f9f7fff8b8d 100644 --- a/internal/docker/level_guesser.go +++ b/internal/docker/level_guesser.go @@ -3,6 +3,9 @@ package docker import ( "regexp" "strings" + + "github.com/iancoleman/orderedmap" + log "github.com/sirupsen/logrus" ) var keyValueRegex = regexp.MustCompile(`level=(\w+)`) @@ -42,6 +45,13 @@ func guessLogLevel(logEvent *LogEvent) string { return matches[1] } + case *orderedmap.OrderedMap: + if level, ok := value.Get("level"); ok { + if level, ok := level.(string); ok { + return strings.ToLower(level) + } + } + case map[string]interface{}: if level, ok := value["level"].(string); ok { return strings.ToLower(level) @@ -51,6 +61,9 @@ func guessLogLevel(logEvent *LogEvent) string { if level, ok := value["level"]; ok { return strings.ToLower(level) } + + default: + log.Debugf("unknown type to guess level: %T", value) } return "" diff --git a/internal/docker/level_guesser_test.go b/internal/docker/level_guesser_test.go index 90a3ec7e472..70fd1a9e22f 100644 --- a/internal/docker/level_guesser_test.go +++ b/internal/docker/level_guesser_test.go @@ -2,9 +2,15 @@ package docker import ( "testing" + + "github.com/iancoleman/orderedmap" ) func TestGuessLogLevel(t *testing.T) { + ordereddata := orderedmap.New() + ordereddata.Set("key", "value") + ordereddata.Set("level", "info") + tests := []struct { input any expected string @@ -29,6 +35,7 @@ func TestGuessLogLevel(t *testing.T) { {map[string]interface{}{"level": "INFO"}, "info"}, {map[string]string{"level": "info"}, "info"}, {map[string]string{"level": "INFO"}, "info"}, + {ordereddata, "info"}, } for _, test := range tests {