首頁>技術>

本文主要研究一下klog的LogFilter

LogFilter

k8s.io/klog/[email protected]/klog.go

// LogFilter is a collection of functions that can filter all logging calls,// e.g. for sanitization of arguments and prevent accidental leaking of secrets.type LogFilter interface {    Filter(args []interface{}) []interface{}    FilterF(format string, args []interface{}) (string, []interface{})    FilterS(msg string, keysAndValues []interface{}) (string, []interface{})}func SetLogFilter(filter LogFilter) {    logging.mu.Lock()    defer logging.mu.Unlock()    logging.filter = filter}

LogFilter介面定義了Filter、FilterF、FilterS方法用於過濾log

filter.Filter

k8s.io/klog/[email protected]/klog.go

func (l *loggingT) println(s severity, logr logr.Logger, filter LogFilter, args ...interface{}) {    buf, file, line := l.header(s, 0)    // if logr is set, we clear the generated header as we rely on the backing    // logr implementation to print headers    if logr != nil {        l.putBuffer(buf)        buf = l.getBuffer()    }    if filter != nil {        args = filter.Filter(args)    }    fmt.Fprintln(buf, args...)    l.output(s, logr, buf, file, line, false)}func (l *loggingT) printDepth(s severity, logr logr.Logger, filter LogFilter, depth int, args ...interface{}) {    buf, file, line := l.header(s, depth)    // if logr is set, we clear the generated header as we rely on the backing    // logr implementation to print headers    if logr != nil {        l.putBuffer(buf)        buf = l.getBuffer()    }    if filter != nil {        args = filter.Filter(args)    }    fmt.Fprint(buf, args...)    if buf.Bytes()[buf.Len()-1] != '\n' {        buf.WriteByte('\n')    }    l.output(s, logr, buf, file, line, false)}func (l *loggingT) printWithFileLine(s severity, logr logr.Logger, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) {    buf := l.formatHeader(s, file, line)    // if logr is set, we clear the generated header as we rely on the backing    // logr implementation to print headers    if logr != nil {        l.putBuffer(buf)        buf = l.getBuffer()    }    if filter != nil {        args = filter.Filter(args)    }    fmt.Fprint(buf, args...)    if buf.Bytes()[buf.Len()-1] != '\n' {        buf.WriteByte('\n')    }    l.output(s, logr, buf, file, line, alsoToStderr)}

println、printDepth、printWithFileLine會透過filter.Filter(args)來過濾args

filter.FilterF

k8s.io/klog/[email protected]/klog.go

func (l *loggingT) printf(s severity, logr logr.Logger, filter LogFilter, format string, args ...interface{}) {    buf, file, line := l.header(s, 0)    // if logr is set, we clear the generated header as we rely on the backing    // logr implementation to print headers    if logr != nil {        l.putBuffer(buf)        buf = l.getBuffer()    }    if filter != nil {        format, args = filter.FilterF(format, args)    }    fmt.Fprintf(buf, format, args...)    if buf.Bytes()[buf.Len()-1] != '\n' {        buf.WriteByte('\n')    }    l.output(s, logr, buf, file, line, false)}

printf方法使用filter.FilterF(format, args)返回的format及args進行格式化

filter.FilterS

k8s.io/klog/[email protected]/klog.go

func (l *loggingT) infoS(loggr logr.Logger, filter LogFilter, msg string, keysAndValues ...interface{}) {    if filter != nil {        msg, keysAndValues = filter.FilterS(msg, keysAndValues)    }    if loggr != nil {        loggr.Info(msg, keysAndValues...)        return    }    l.printS(nil, msg, keysAndValues...)}func (l *loggingT) errorS(err error, loggr logr.Logger, filter LogFilter, msg string, keysAndValues ...interface{}) {    if filter != nil {        msg, keysAndValues = filter.FilterS(msg, keysAndValues)    }    if loggr != nil {        loggr.Error(err, msg, keysAndValues...)        return    }    l.printS(err, msg, keysAndValues...)}

infoS及errorS方法會使用filter.FilterS(msg, keysAndValues)返回的msg及keysAndValues進行列印

例項
type sampleLogFilter struct{}func (f *sampleLogFilter) Filter(args []interface{}) []interface{} {    for i, arg := range args {        v, ok := arg.(string)        if ok && strings.Contains(v, "filter me") {            args[i] = "[FILTERED]"        }    }    return args}func (f *sampleLogFilter) FilterF(format string, args []interface{}) (string, []interface{}) {    return strings.Replace(format, "filter me", "[FILTERED]", 1), f.Filter(args)}func (f *sampleLogFilter) FilterS(msg string, keysAndValues []interface{}) (string, []interface{}) {    return strings.Replace(msg, "filter me", "[FILTERED]", 1), f.Filter(keysAndValues)}func TestLogFilter(t *testing.T) {    setFlags()    defer logging.swap(logging.newBuffers())    SetLogFilter(&sampleLogFilter{})    defer SetLogFilter(nil)    funcs := []struct {        name     string        logFunc  func(args ...interface{})        severity severity    }{{        name:     "Info",        logFunc:  Info,        severity: infoLog,    }, {        name: "InfoDepth",        logFunc: func(args ...interface{}) {            InfoDepth(1, args...)        },        severity: infoLog,    }, {        name:     "Infoln",        logFunc:  Infoln,        severity: infoLog,    }, {        name: "Infof",        logFunc: func(args ...interface{}) {            Infof(args[0].(string), args[1:]...)        },        severity: infoLog,    }, {        name: "InfoS",        logFunc: func(args ...interface{}) {            InfoS(args[0].(string), args[1:]...)        },        severity: infoLog,    }, {        name:     "Warning",        logFunc:  Warning,        severity: warningLog,    }, {        name: "WarningDepth",        logFunc: func(args ...interface{}) {            WarningDepth(1, args...)        },        severity: warningLog,    }, {        name:     "Warningln",        logFunc:  Warningln,        severity: warningLog,    }, {        name: "Warningf",        logFunc: func(args ...interface{}) {            Warningf(args[0].(string), args[1:]...)        },        severity: warningLog,    }, {        name:     "Error",        logFunc:  Error,        severity: errorLog,    }, {        name: "ErrorDepth",        logFunc: func(args ...interface{}) {            ErrorDepth(1, args...)        },        severity: errorLog,    }, {        name:     "Errorln",        logFunc:  Errorln,        severity: errorLog,    }, {        name: "Errorf",        logFunc: func(args ...interface{}) {            Errorf(args[0].(string), args[1:]...)        },        severity: errorLog,    }, {        name: "ErrorS",        logFunc: func(args ...interface{}) {            ErrorS(errors.New("testerror"), args[0].(string), args[1:]...)        },        severity: errorLog,    }, {        name: "V().Info",        logFunc: func(args ...interface{}) {            V(0).Info(args...)        },        severity: infoLog,    }, {        name: "V().Infoln",        logFunc: func(args ...interface{}) {            V(0).Infoln(args...)        },        severity: infoLog,    }, {        name: "V().Infof",        logFunc: func(args ...interface{}) {            V(0).Infof(args[0].(string), args[1:]...)        },        severity: infoLog,    }, {        name: "V().InfoS",        logFunc: func(args ...interface{}) {            V(0).InfoS(args[0].(string), args[1:]...)        },        severity: infoLog,    }, {        name: "V().Error",        logFunc: func(args ...interface{}) {            V(0).Error(errors.New("test error"), args[0].(string), args[1:]...)        },        severity: errorLog,    }, {        name: "V().ErrorS",        logFunc: func(args ...interface{}) {            V(0).ErrorS(errors.New("test error"), args[0].(string), args[1:]...)        },        severity: errorLog,    }}    testcases := []struct {        name           string        args           []interface{}        expectFiltered bool    }{{        args:           []interface{}{"%s:%s", "foo", "bar"},        expectFiltered: false,    }, {        args:           []interface{}{"%s:%s", "foo", "filter me"},        expectFiltered: true,    }, {        args:           []interface{}{"filter me %s:%s", "foo", "bar"},        expectFiltered: true,    }}    for _, f := range funcs {        for _, tc := range testcases {            logging.newBuffers()            f.logFunc(tc.args...)            got := contains(f.severity, "[FILTERED]", t)            if got != tc.expectFiltered {                t.Errorf("%s filter application failed, got %v, want %v", f.name, got, tc.expectFiltered)            }        }    }}
小結

klog的LogFilter介面定義了Filter、FilterF、FilterS方法用於過濾log;println、printDepth、printWithFileLine會透過filter.Filter(args)來過濾args;printf方法使用filter.FilterF(format, args)返回的format及args進行格式化;infoS及errorS方法會使用filter.FilterS(msg, keysAndValues)返回的msg及keysAndValues進行列印。

docklog

10
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 想吃程式這塊蛋糕,就看誰的資料結構與演算法運用的好