mirror of
https://github.com/go-kratos/kratos.git
synced 2025-03-17 21:07:54 +02:00
commit
864a791e04
81
log/filter.go
Normal file
81
log/filter.go
Normal file
@ -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...)
|
||||
}
|
90
log/filter_test.go
Normal file
90
log/filter_test.go
Normal file
@ -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
|
||||
}
|
@ -25,7 +25,7 @@ func (h *Helper) WithContext(ctx context.Context) *Helper {
|
||||
}
|
||||
}
|
||||
|
||||
// Log .
|
||||
// Log Print log by level and keyvals.
|
||||
func (h *Helper) Log(level Level, keyvals ...interface{}) {
|
||||
h.logger.Log(level, keyvals...)
|
||||
}
|
||||
|
@ -33,8 +33,13 @@ func Value(ctx context.Context, v interface{}) interface{} {
|
||||
func Caller(depth int) Valuer {
|
||||
return func(context.Context) interface{} {
|
||||
_, file, line, _ := runtime.Caller(depth)
|
||||
if strings.LastIndex(file, "/log/filter.go") > 0 {
|
||||
depth++
|
||||
_, file, line, _ = runtime.Caller(depth)
|
||||
}
|
||||
if strings.LastIndex(file, "/log/helper.go") > 0 {
|
||||
_, file, line, _ = runtime.Caller(depth + 1)
|
||||
depth++
|
||||
_, file, line, _ = runtime.Caller(depth)
|
||||
}
|
||||
idx := strings.LastIndexByte(file, '/')
|
||||
return file[idx+1:] + ":" + strconv.Itoa(line)
|
||||
|
Loading…
x
Reference in New Issue
Block a user