commit
864a791e04
@ -0,0 +1,81 @@ |
||||
package log |
||||
|
||||
// FilterOption is filter option.
|
||||
type FilterOption func(*Filter) |
||||
|
||||
// FilterLevel with filter level.
|
||||
func FilterLevel(level Level) FilterOption { |
||||
return func(opts *Filter) { |
||||
opts.level = level |
||||
} |
||||
} |
||||
|
||||
// FilterKey with filter key.
|
||||
func FilterKey(key ...string) FilterOption { |
||||
return func(o *Filter) { |
||||
for _, v := range key { |
||||
o.key[v] = struct{}{} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// FilterValue with filter value.
|
||||
func FilterValue(value ...string) FilterOption { |
||||
return func(o *Filter) { |
||||
for _, v := range value { |
||||
o.value[v] = struct{}{} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// FilterFunc with filter func.
|
||||
func FilterFunc(f func(level Level, keyvals ...interface{}) bool) FilterOption { |
||||
return func(o *Filter) { |
||||
o.filter = f |
||||
} |
||||
} |
||||
|
||||
// Filter is a logger filter.
|
||||
type Filter struct { |
||||
logger Logger |
||||
level Level |
||||
key map[interface{}]struct{} |
||||
value map[interface{}]struct{} |
||||
filter func(level Level, keyvals ...interface{}) bool |
||||
} |
||||
|
||||
// NewFilter new a logger filter.
|
||||
func NewFilter(logger Logger, opts ...FilterOption) *Filter { |
||||
options := Filter{ |
||||
logger: logger, |
||||
key: make(map[interface{}]struct{}), |
||||
value: make(map[interface{}]struct{}), |
||||
} |
||||
for _, o := range opts { |
||||
o(&options) |
||||
} |
||||
return &options |
||||
} |
||||
|
||||
// Log Print log by level and keyvals.
|
||||
func (f *Filter) Log(level Level, keyvals ...interface{}) error { |
||||
if f.level > level { |
||||
return nil |
||||
} |
||||
if f.filter != nil && f.filter(level, keyvals...) { |
||||
return nil |
||||
} |
||||
for i := 0; i < len(keyvals); i += 2 { |
||||
if _, ok := f.key[keyvals[i]]; ok { |
||||
keyvals[i+1] = "***" |
||||
} |
||||
vi := i + 1 |
||||
if vi >= len(keyvals) { |
||||
continue |
||||
} |
||||
if _, ok := f.value[keyvals[vi]]; ok { |
||||
keyvals[i+1] = "***" |
||||
} |
||||
} |
||||
return f.logger.Log(level, keyvals...) |
||||
} |
@ -0,0 +1,90 @@ |
||||
package log |
||||
|
||||
import ( |
||||
"io/ioutil" |
||||
"testing" |
||||
) |
||||
|
||||
func TestFilterAll(t *testing.T) { |
||||
logger := With(DefaultLogger, "ts", DefaultTimestamp, "caller", DefaultCaller) |
||||
log := NewHelper(NewFilter(logger, |
||||
FilterLevel(LevelDebug), |
||||
FilterKey("username"), |
||||
FilterValue("hello"), |
||||
FilterFunc(testFilterFunc), |
||||
)) |
||||
log.Log(LevelDebug, "msg", "test debug") |
||||
log.Info("hello") |
||||
log.Infow("password", "123456") |
||||
log.Infow("username", "kratos") |
||||
log.Warn("warn log") |
||||
} |
||||
func TestFilterLevel(t *testing.T) { |
||||
logger := With(DefaultLogger, "ts", DefaultTimestamp, "caller", DefaultCaller) |
||||
log := NewHelper(NewFilter(NewFilter(logger, FilterLevel(LevelWarn)))) |
||||
log.Log(LevelDebug, "msg1", "te1st debug") |
||||
log.Debug("test debug") |
||||
log.Debugf("test %s", "debug") |
||||
log.Debugw("log", "test debug") |
||||
log.Warn("warn log") |
||||
} |
||||
|
||||
func TestFilterCaller(t *testing.T) { |
||||
logger := With(DefaultLogger, "ts", DefaultTimestamp, "caller", DefaultCaller) |
||||
log := NewFilter(logger) |
||||
log.Log(LevelDebug, "msg1", "te1st debug") |
||||
logHelper := NewHelper(NewFilter(logger)) |
||||
logHelper.Log(LevelDebug, "msg1", "te1st debug") |
||||
} |
||||
|
||||
func TestFilterKey(t *testing.T) { |
||||
logger := With(DefaultLogger, "ts", DefaultTimestamp, "caller", DefaultCaller) |
||||
log := NewHelper(NewFilter(logger, FilterKey("password"))) |
||||
log.Debugw("password", "123456") |
||||
} |
||||
|
||||
func TestFilterValue(t *testing.T) { |
||||
logger := With(DefaultLogger, "ts", DefaultTimestamp, "caller", DefaultCaller) |
||||
log := NewHelper(NewFilter(logger, FilterValue("debug"))) |
||||
log.Debugf("test %s", "debug") |
||||
} |
||||
|
||||
func TestFilterFunc(t *testing.T) { |
||||
logger := With(DefaultLogger, "ts", DefaultTimestamp, "caller", DefaultCaller) |
||||
log := NewHelper(NewFilter(logger, FilterFunc(testFilterFunc))) |
||||
log.Debug("debug level") |
||||
log.Infow("password", "123456") |
||||
} |
||||
|
||||
func BenchmarkFilterKey(b *testing.B) { |
||||
log := NewHelper(NewFilter(NewStdLogger(ioutil.Discard), FilterKey("password"))) |
||||
for i := 0; i < b.N; i++ { |
||||
log.Infow("password", "123456") |
||||
} |
||||
} |
||||
|
||||
func BenchmarkFilterValue(b *testing.B) { |
||||
log := NewHelper(NewFilter(NewStdLogger(ioutil.Discard), FilterValue("password"))) |
||||
for i := 0; i < b.N; i++ { |
||||
log.Infow("password") |
||||
} |
||||
} |
||||
|
||||
func BenchmarkFilterFunc(b *testing.B) { |
||||
log := NewHelper(NewFilter(NewStdLogger(ioutil.Discard), FilterFunc(testFilterFunc))) |
||||
for i := 0; i < b.N; i++ { |
||||
log.Info("password", "123456") |
||||
} |
||||
} |
||||
|
||||
func testFilterFunc(level Level, keyvals ...interface{}) bool { |
||||
if level == LevelWarn { |
||||
return true |
||||
} |
||||
for i := 0; i < len(keyvals); i++ { |
||||
if keyvals[i] == "password" { |
||||
keyvals[i+1] = "***" |
||||
} |
||||
} |
||||
return false |
||||
} |
Loading…
Reference in new issue