From 37d313519b69d83d97560a5c09722cec959596a9 Mon Sep 17 00:00:00 2001
From: Semyon Krestyaninov <ensiouel@gmail.com>
Date: Thu, 15 Feb 2024 11:33:59 +0300
Subject: [PATCH] feature: add filter_core.go

---
 log/zap/filter_core.go      | 51 +++++++++++++++++++++++++++++++++++++
 log/zap/filter_core_test.go | 34 +++++++++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 log/zap/filter_core.go
 create mode 100644 log/zap/filter_core_test.go

diff --git a/log/zap/filter_core.go b/log/zap/filter_core.go
new file mode 100644
index 00000000..e1049447
--- /dev/null
+++ b/log/zap/filter_core.go
@@ -0,0 +1,51 @@
+package zap
+
+import (
+	"go.uber.org/zap"
+	"go.uber.org/zap/zapcore"
+)
+
+type FilterFunc func(entry zapcore.Entry, fields []zapcore.Field) bool
+
+type filterCore struct {
+	zapcore.Core
+
+	filters []FilterFunc
+	fields  []zap.Field
+}
+
+func NewFilterCore(core zapcore.Core, filters ...FilterFunc) zapcore.Core {
+	return &filterCore{
+		Core:    core,
+		filters: filters,
+	}
+}
+
+func (core *filterCore) With(fields []zapcore.Field) zapcore.Core {
+	return &filterCore{
+		Core:    core.Core.With(fields),
+		filters: core.filters,
+		fields:  append(core.fields, fields...),
+	}
+}
+
+func (core *filterCore) Check(entry zapcore.Entry, checkedEntry *zapcore.CheckedEntry) *zapcore.CheckedEntry {
+	if core.Core.Enabled(entry.Level) {
+		return checkedEntry.AddCore(entry, core)
+	}
+	return checkedEntry
+}
+
+func (core *filterCore) Write(entry zapcore.Entry, fields []zapcore.Field) error {
+	if len(core.filters) > 0 {
+		fields = append(core.fields, fields...)
+	}
+
+	for _, filter := range core.filters {
+		if !filter(entry, fields) {
+			return nil
+		}
+	}
+
+	return core.Core.Write(entry, fields)
+}
diff --git a/log/zap/filter_core_test.go b/log/zap/filter_core_test.go
new file mode 100644
index 00000000..0b9f33a6
--- /dev/null
+++ b/log/zap/filter_core_test.go
@@ -0,0 +1,34 @@
+package zap
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+	"go.uber.org/zap"
+	"go.uber.org/zap/zapcore"
+	"go.uber.org/zap/zaptest/observer"
+)
+
+func TestFilterCore_Write(t *testing.T) {
+	core, logs := observer.New(zapcore.InfoLevel)
+	core = NewFilterCore(core, func(entry zapcore.Entry, fields []zapcore.Field) bool {
+		enc := zapcore.NewMapObjectEncoder()
+		for _, field := range fields {
+			field.AddTo(enc)
+		}
+		check, _ := enc.Fields["check"].(bool)
+		return check
+	})
+
+	logger := zap.New(core)
+	{
+		logger := logger.With(zap.Bool("check", true))
+		logger.Info("check true 1")
+		logger.Info("check true 2")
+	}
+
+	logger.Info("check false 1")
+	logger.Info("check false 2")
+
+	require.Equal(t, 2, logs.Len())
+}
-- 
GitLab