From 79d8eefc88b4b7c26b855df1492506131184f1a9 Mon Sep 17 00:00:00 2001 From: Semyon Krestyaninov <ensiouel@gmail.com> Date: Wed, 28 Feb 2024 11:54:47 +0300 Subject: [PATCH] feature: add unused v2 entry encoder --- logs/zap/entry_encoder_test.go | 74 ++++++++++++++++++++++++++++++++++ logs/zap/entry_encoder_v2.go | 69 +++++++++++++++++++++++++++++++ zap/channels.go | 2 +- zap/field.go | 8 ++-- zap/field_test.go | 4 +- 5 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 logs/zap/entry_encoder_v2.go diff --git a/logs/zap/entry_encoder_test.go b/logs/zap/entry_encoder_test.go index b6539976..052b13f7 100644 --- a/logs/zap/entry_encoder_test.go +++ b/logs/zap/entry_encoder_test.go @@ -1 +1,75 @@ package zap + +import ( + "fmt" + "testing" + + "git.perx.ru/perxis/perxis-go/pkg/items" + logzap "git.perx.ru/perxis/perxis-go/zap" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func BenchmarkEntryEncoderSimple(b *testing.B) { + fields := []zapcore.Field{ + logzap.Event(items.EventCreateItem), + logzap.Object(items.NewItem("WPNN", "9VGP", "GxNv", "W0fl", nil, nil)), + logzap.Caller("/system"), + logzap.Tags("tag1", "tag2", "tag3"), + } + + enc := NewEntryEncoder() + for i := 0; i < b.N; i++ { + _, _ = enc.EncodeEntry(zapcore.Entry{Message: fmt.Sprintf("Msg: %d", i)}, fields) + } +} + +func BenchmarkEntryEncoderUnknownFields(b *testing.B) { + fields := []zapcore.Field{ + logzap.Event(items.EventCreateItem), + logzap.Object(items.NewItem("WPNN", "9VGP", "GxNv", "W0fl", nil, nil)), + logzap.Caller("/system"), + logzap.Tags("tag1", "tag2", "tag3"), + } + + for i := 0; i < 1000; i++ { + fields = append(fields, zap.String(fmt.Sprintf("Key: %d", i), fmt.Sprintf("Value: %d", i))) + } + + enc := NewEntryEncoder() + for i := 0; i < b.N; i++ { + _, _ = enc.EncodeEntry(zapcore.Entry{Message: fmt.Sprintf("Msg: %d", i)}, fields) + } +} + +func BenchmarkEntryEncoderV2Simple(b *testing.B) { + fields := []zapcore.Field{ + logzap.Event(items.EventCreateItem), + logzap.Object(items.NewItem("WPNN", "9VGP", "GxNv", "W0fl", nil, nil)), + logzap.Caller("/system"), + logzap.Tags("tag1", "tag2", "tag3"), + } + + enc := NewEntryEncoderV2() + for i := 0; i < b.N; i++ { + _, _ = enc.EncodeEntry(zapcore.Entry{Message: fmt.Sprintf("Msg: %d", i)}, fields) + } +} + +func BenchmarkEntryEncoderV2UnknownFields(b *testing.B) { + fields := []zapcore.Field{ + logzap.Event(items.EventCreateItem), + logzap.Object(items.NewItem("WPNN", "9VGP", "GxNv", "W0fl", nil, nil)), + logzap.Caller("/system"), + logzap.Tags("tag1", "tag2", "tag3"), + } + + for i := 0; i < 1000; i++ { + fields = append(fields, zap.String(fmt.Sprintf("Key: %d", i), fmt.Sprintf("Value: %d", i))) + } + + enc := NewEntryEncoderV2() + for i := 0; i < b.N; i++ { + _, _ = enc.EncodeEntry(zapcore.Entry{Message: fmt.Sprintf("Msg: %d", i)}, fields) + } +} diff --git a/logs/zap/entry_encoder_v2.go b/logs/zap/entry_encoder_v2.go new file mode 100644 index 00000000..a73be093 --- /dev/null +++ b/logs/zap/entry_encoder_v2.go @@ -0,0 +1,69 @@ +package zap + +import ( + "fmt" + "slices" + + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/logs" + "git.perx.ru/perxis/perxis-go/pkg/id" + "git.perx.ru/perxis/perxis-go/zap" + "go.uber.org/zap/zapcore" +) + +type EncoderV2 interface { + With([]zapcore.Field) EncoderV2 + EncodeEntry(zapcore.Entry, []zapcore.Field) (*logs.Entry, error) +} + +type entryEncoderV2 struct { + fields []zapcore.Field +} + +func NewEntryEncoderV2() EncoderV2 { + return &entryEncoderV2{} +} + +func (enc *entryEncoderV2) With(fields []zapcore.Field) EncoderV2 { + return enc.with(fields) +} + +func (enc *entryEncoderV2) with(fields []zapcore.Field) *entryEncoderV2 { + return &entryEncoderV2{fields: slices.Concat(enc.fields, fields)} +} + +func (enc *entryEncoderV2) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*logs.Entry, error) { + ent := &logs.Entry{ + ID: id.GenerateNewID(), + Timestamp: entry.Time, + LogLevel: logs.Level(entry.Level), + Message: entry.Message, + } + + clone := enc.with(fields) + + for i := range clone.fields { + switch clone.fields[i].Key { + case "category": + ent.Category = clone.fields[i].String + case "component": + ent.Component = clone.fields[i].String + case "event": + ent.Event = clone.fields[i].String + case "object": + ent.ObjectID, _ = clone.fields[i].Interface.(*oid.ObjectId) + case "caller": + ent.CallerID, _ = clone.fields[i].Interface.(*oid.ObjectId) + case "attr": + ent.Attr = clone.fields[i].Interface + case "error": + if err, _ := clone.fields[i].Interface.(error); err != nil { + ent.Message = fmt.Sprintf("%s. Error: %s", ent.Message, err.Error()) + } + case "tags": + ent.Tags, _ = clone.fields[i].Interface.(zap.StringArray) + } + } + + return ent, nil +} diff --git a/zap/channels.go b/zap/channels.go index 57531635..8726cc54 100644 --- a/zap/channels.go +++ b/zap/channels.go @@ -17,7 +17,7 @@ func ContainsChannels(channels ...string) FilterFunc { return func(entry zapcore.Entry, fields []zapcore.Field) bool { for _, f := range fields { if f.Key == channelKey && f.Type == zapcore.SkipType { - for _, v := range f.Interface.(stringArray) { + for _, v := range f.Interface.(StringArray) { if data.Contains(v, channels) { return true } diff --git a/zap/field.go b/zap/field.go index 308c21d6..bccee934 100644 --- a/zap/field.go +++ b/zap/field.go @@ -10,9 +10,9 @@ import ( "go.uber.org/zap/zapcore" ) -type stringArray []string +type StringArray []string -func (ss stringArray) MarshalLogArray(arr zapcore.ArrayEncoder) error { +func (ss StringArray) MarshalLogArray(arr zapcore.ArrayEncoder) error { for i := range ss { arr.AppendString(ss[i]) } @@ -24,7 +24,7 @@ func Channels(channels ...string) zap.Field { return zap.Field{ Key: channelKey, Type: zapcore.SkipType, // используем тип zapcore.SkipType, чтобы при кодировании поле игнорировалось - Interface: stringArray(channels), + Interface: StringArray(channels), } } @@ -64,5 +64,5 @@ func Attr(attr any) zap.Field { } func Tags(tags ...string) zap.Field { - return zap.Strings("tags", tags) + return zap.Array("tags", StringArray(tags)) } diff --git a/zap/field_test.go b/zap/field_test.go index 84efa584..8e81ce28 100644 --- a/zap/field_test.go +++ b/zap/field_test.go @@ -19,8 +19,8 @@ func TestChannels(t *testing.T) { field zap.Field want zap.Field }{ - {name: "ok", field: Channels("master"), want: zap.Field{Key: channelKey, Type: zapcore.SkipType, Interface: stringArray{"master"}}}, - {name: "invalid", field: Channels(), want: zap.Field{Key: channelKey, Type: zapcore.SkipType, Interface: stringArray(nil)}}, + {name: "ok", field: Channels("master"), want: zap.Field{Key: channelKey, Type: zapcore.SkipType, Interface: StringArray{"master"}}}, + {name: "invalid", field: Channels(), want: zap.Field{Key: channelKey, Type: zapcore.SkipType, Interface: StringArray(nil)}}, } for _, tc := range tests { -- GitLab