diff --git a/logs/zap/core.go b/logs/zap/core.go
index 3b0c3305f685f8dfe52628dd49c1d4716fda9e91..0b54b5c38324e7ec18d1ad80497c3858ed246014 100644
--- a/logs/zap/core.go
+++ b/logs/zap/core.go
@@ -1,12 +1,7 @@
 package zap
 
 import (
-	"fmt"
-
-	oid "git.perx.ru/perxis/perxis-go/id"
 	"git.perx.ru/perxis/perxis-go/logs"
-	"git.perx.ru/perxis/perxis-go/pkg/id"
-	"go.uber.org/zap"
 	"go.uber.org/zap/zapcore"
 )
 
@@ -20,22 +15,27 @@ type WriteSyncer interface {
 type Core struct {
 	zapcore.LevelEnabler
 
-	writeSyncer WriteSyncer
-	fields      []zap.Field
+	ws  WriteSyncer
+	enc Encoder
 }
 
 func NewCore(writeSyncer WriteSyncer) *Core {
 	return &Core{
 		LevelEnabler: zapcore.InfoLevel,
-		writeSyncer:  writeSyncer,
+		ws:           writeSyncer,
+		enc:          NewEntryEncoder(),
 	}
 }
 
 func (core *Core) With(fields []zapcore.Field) zapcore.Core {
+	clone := core.enc.Clone()
+	for i := range fields {
+		fields[i].AddTo(clone)
+	}
 	return &Core{
 		LevelEnabler: core.LevelEnabler,
-		writeSyncer:  core.writeSyncer,
-		fields:       append(core.fields, fields...),
+		ws:           core.ws,
+		enc:          clone,
 	}
 }
 
@@ -47,48 +47,13 @@ func (core *Core) Check(entry zapcore.Entry, checkedEntry *zapcore.CheckedEntry)
 }
 
 func (core *Core) Write(entry zapcore.Entry, fields []zapcore.Field) error {
-	return core.writeSyncer.Write(core.getEntry(entry, fields))
+	encodeEntry, err := core.enc.EncodeEntry(entry, fields)
+	if err != nil {
+		return err
+	}
+	return core.ws.Write(encodeEntry)
 }
 
 func (core *Core) Sync() error {
-	return core.writeSyncer.Sync()
-}
-
-func (core *Core) getEntry(entry zapcore.Entry, fields []zapcore.Field) *logs.Entry {
-	if len(core.fields) > 0 {
-		fields = append(fields, core.fields...)
-	}
-
-	enc := zapcore.NewMapObjectEncoder()
-	for _, field := range fields {
-		field.AddTo(enc)
-	}
-
-	ent := &logs.Entry{
-		ID:        id.GenerateNewID(),
-		Timestamp: entry.Time,
-		LogLevel:  logs.Level(entry.Level),
-		Message:   entry.Message,
-	}
-
-	ent.Category, _ = enc.Fields["category"].(string)
-	ent.Component, _ = enc.Fields["component"].(string)
-	ent.Event, _ = enc.Fields["event"].(string)
-	ent.ObjectID, _ = enc.Fields["object"].(*oid.ObjectId)
-	ent.CallerID, _ = enc.Fields["caller"].(*oid.ObjectId)
-	ent.Attr = enc.Fields["attr"]
-
-	if err, _ := enc.Fields["error"].(error); err != nil {
-		ent.Message = fmt.Sprintf("%s. Error: %s", ent.Message, err.Error())
-	}
-
-	if tags, ok := enc.Fields["tags"].([]any); ok {
-		for _, item := range tags {
-			if tag, ok := item.(string); ok {
-				ent.Tags = append(ent.Tags, tag)
-			}
-		}
-	}
-
-	return ent
+	return core.ws.Sync()
 }
diff --git a/logs/zap/core_test.go b/logs/zap/core_test.go
index aabe9cea3da3f4eb4da1d0696c7c6fb08753cc63..b65399764cb9f7d0d48d6f00a6f231b08e1f170b 100644
--- a/logs/zap/core_test.go
+++ b/logs/zap/core_test.go
@@ -1,65 +1 @@
 package zap
-
-import (
-	"testing"
-
-	"git.perx.ru/perxis/perxis-go/id"
-	"git.perx.ru/perxis/perxis-go/logs"
-	logzap "git.perx.ru/perxis/perxis-go/zap"
-	"github.com/stretchr/testify/require"
-	"go.uber.org/zap"
-	"go.uber.org/zap/zapcore"
-)
-
-func TestCore_getEntry(t *testing.T) {
-	core := NewCore(nil)
-
-	tests := []struct {
-		name  string
-		input struct {
-			entry  zapcore.Entry
-			fields []zapcore.Field
-		}
-		want *logs.Entry
-	}{
-		{
-			name: "simple",
-			input: struct {
-				entry  zapcore.Entry
-				fields []zapcore.Field
-			}{
-				entry: zapcore.Entry{Level: zapcore.InfoLevel, Message: "создан элемент коллекции"},
-				fields: []zapcore.Field{
-					zap.String("key", "val"), // будет проигнорировано
-					logzap.Category("create"),
-					logzap.Component("Items.Service"),
-					logzap.Event("Items.Create"),
-					logzap.Object("/spaces/WPNN/envs/9VGP/cols/GxNv/items/W0fl"),
-					logzap.Caller("/users/PHVz"),
-					logzap.Attr("any"),
-					logzap.Tags("tag1", "tag2", "tag3"),
-				},
-			},
-			want: &logs.Entry{
-				LogLevel:  logs.Level(zapcore.InfoLevel),
-				Message:   "создан элемент коллекции",
-				Category:  "create",
-				Component: "Items.Service",
-				Event:     "Items.Create",
-				ObjectID:  id.MustObjectId("/spaces/WPNN/envs/9VGP/cols/GxNv/items/W0fl"),
-				CallerID:  id.MustObjectId("/users/PHVz"),
-				Attr:      "any",
-				Tags:      []string{"tag1", "tag2", "tag3"},
-			},
-		},
-	}
-
-	for _, tc := range tests {
-		t.Run(tc.name, func(t *testing.T) {
-			got := core.getEntry(tc.input.entry, tc.input.fields)
-			got.ID = tc.want.ID               // игнорируем ID
-			got.Timestamp = tc.want.Timestamp // игнорируем Timestamp
-			require.Equal(t, tc.want, got)
-		})
-	}
-}
diff --git a/logs/zap/entry_encoder.go b/logs/zap/entry_encoder.go
new file mode 100644
index 0000000000000000000000000000000000000000..0f5692852f59fbb620b476d982f61617dd476294
--- /dev/null
+++ b/logs/zap/entry_encoder.go
@@ -0,0 +1,71 @@
+package zap
+
+import (
+	"fmt"
+	"maps"
+
+	oid "git.perx.ru/perxis/perxis-go/id"
+	"git.perx.ru/perxis/perxis-go/logs"
+	"git.perx.ru/perxis/perxis-go/pkg/id"
+	"go.uber.org/zap/zapcore"
+)
+
+type Encoder interface {
+	zapcore.ObjectEncoder
+
+	Clone() Encoder
+	EncodeEntry(zapcore.Entry, []zapcore.Field) (*logs.Entry, error)
+}
+
+type entryEncoder struct {
+	*zapcore.MapObjectEncoder
+}
+
+func NewEntryEncoder() Encoder {
+	return &entryEncoder{MapObjectEncoder: zapcore.NewMapObjectEncoder()}
+}
+
+func (enc *entryEncoder) Clone() Encoder {
+	return enc.clone()
+}
+
+func (enc *entryEncoder) clone() *entryEncoder {
+	objEnc := zapcore.NewMapObjectEncoder()
+	maps.Copy(objEnc.Fields, enc.MapObjectEncoder.Fields)
+	return &entryEncoder{MapObjectEncoder: objEnc}
+}
+
+func (enc *entryEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*logs.Entry, error) {
+	clone := enc.clone()
+	for i := range fields {
+		fields[i].AddTo(clone)
+	}
+
+	ent := &logs.Entry{
+		ID:        id.GenerateNewID(),
+		Timestamp: entry.Time,
+		LogLevel:  logs.Level(entry.Level),
+		Message:   entry.Message,
+	}
+
+	ent.Category, _ = clone.Fields["category"].(string)
+	ent.Component, _ = clone.Fields["component"].(string)
+	ent.Event, _ = clone.Fields["event"].(string)
+	ent.ObjectID, _ = clone.Fields["object"].(*oid.ObjectId)
+	ent.CallerID, _ = clone.Fields["caller"].(*oid.ObjectId)
+	ent.Attr = clone.Fields["attr"]
+
+	if err, _ := clone.Fields["error"].(error); err != nil {
+		ent.Message = fmt.Sprintf("%s. Error: %s", ent.Message, err.Error())
+	}
+
+	if tags, ok := clone.Fields["tags"].([]any); ok {
+		for i := range tags {
+			if tag, ok := tags[i].(string); ok {
+				ent.Tags = append(ent.Tags, tag)
+			}
+		}
+	}
+
+	return ent, nil
+}
diff --git a/logs/zap/entry_encoder_test.go b/logs/zap/entry_encoder_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..b65399764cb9f7d0d48d6f00a6f231b08e1f170b
--- /dev/null
+++ b/logs/zap/entry_encoder_test.go
@@ -0,0 +1 @@
+package zap