Documentation
¶
Overview ¶
message from the author:
+--------------------------------------------------------------+ | * * * ░░░░░░░░░░░░░░░░░░░░ Hello ░░░░░░░░░░░░░░░░░░░░░░░░░░| +--------------------------------------------------------------+ | | | ++ ______________________________________ | | ++++ / \ | | ++++ | | | | ++++++++++ | Feel free to contribute to this | | | +++ | | project or contact me on | | | ++ | | manfred.life if you like this | | | + -== ==| | project! | | | ( <*> <*> | | | | | | /| :) | | | | _) / | | | | | +++ / \______________________________________/ | | \ =+ / | | \ + | | |\++++++ | | | ++++ ||// | | ___| |___ _||/__ __| | / --- \ \| ||| __ _ ___ __ __/ /| |/ | | \ \ / / ' \/ _ \/ // / / | || | | | | | /_/_/_/\___/\_,_/_/ | +--------------------------------------------------------------+
Example (Check) ¶
package main import ( "fmt" "go.uber.org/zap" "moul.io/zapfilter" ) func main() { c := zap.NewExample().Core() logger := zap.New(zapfilter.NewFilteringCore(c, zapfilter.MustParseRules("debug:* info:demo*"))) if ce := logger.Check(zap.DebugLevel, "AAA"); ce != nil { // here you can make expensive computing fmt.Println("BBB") ce.Write() } if ce := logger.Check(zap.InfoLevel, "CCC"); ce != nil { // here you can make expensive computing fmt.Println("DDD") ce.Write() } if ce := logger.Named("demo").Check(zap.InfoLevel, "EEE"); ce != nil { // here you can make expensive computing fmt.Println("FFF") ce.Write() } if ce := logger.Check(zap.WarnLevel, "GGG"); ce != nil { // here you can make expensive computing fmt.Println("HHH") ce.Write() } }
Output: BBB {"level":"debug","msg":"AAA"} FFF {"level":"info","logger":"demo","msg":"EEE"}
Example (With) ¶
package main import ( "go.uber.org/zap" "moul.io/zapfilter" ) func main() { core := zap.NewExample().Core() logger := zap.New(zapfilter.NewFilteringCore(core, zapfilter.ByNamespaces("demo1.*,demo3.*"))) defer logger.Sync() logger.With(zap.String("lorem", "ipsum")).Debug("hello city!") logger.With(zap.String("lorem", "ipsum")).Named("demo1.frontend").Debug("hello region!") logger.With(zap.String("lorem", "ipsum")).Named("demo2.frontend").Debug("hello planet!") logger.With(zap.String("lorem", "ipsum")).Named("demo3.frontend").Debug("hello solar system!") }
Output: {"level":"debug","logger":"demo1.frontend","msg":"hello region!","lorem":"ipsum"} {"level":"debug","logger":"demo3.frontend","msg":"hello solar system!","lorem":"ipsum"}
Index ¶
- func CheckAnyLevel(logger *zap.Logger) bool
- func CheckLevel(logger *zap.Logger, level zapcore.Level) bool
- func NewFilteringCore(next zapcore.Core, filter FilterFunc) zapcore.Core
- type FilterFunc
- func All(filters ...FilterFunc) FilterFunc
- func Any(filters ...FilterFunc) FilterFunc
- func ByLevels(pattern string) (FilterFunc, error)
- func ByNamespaces(input string) FilterFunc
- func ExactLevel(level zapcore.Level) FilterFunc
- func MinimumLevel(level zapcore.Level) FilterFunc
- func MustParseRules(pattern string) FilterFunc
- func ParseRules(pattern string) (FilterFunc, error)
- func Reverse(filter FilterFunc) FilterFunc
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckAnyLevel ¶
CheckAnyLevel determines whether at least one log level isn't filtered-out by the logger.
Example ¶
package main import ( "fmt" "go.uber.org/zap" "moul.io/zapfilter" ) func main() { c := zap.NewExample().Core() logger := zap.New(zapfilter.NewFilteringCore(c, zapfilter.MustParseRules("debug:*.* info:demo*"))) fmt.Println(zapfilter.CheckAnyLevel(logger)) fmt.Println(zapfilter.CheckAnyLevel(logger.Named("demo"))) fmt.Println(zapfilter.CheckAnyLevel(logger.Named("blahdemo"))) fmt.Println(zapfilter.CheckAnyLevel(logger.Named("demoblah"))) fmt.Println(zapfilter.CheckAnyLevel(logger.Named("blah"))) fmt.Println(zapfilter.CheckAnyLevel(logger.Named("blah.blah"))) }
Output: false true false true false true
func CheckLevel ¶ added in v1.7.0
CheckLevel determines whether a specific log level would produce log or not.
Example ¶
package main import ( "fmt" "go.uber.org/zap" "moul.io/zapfilter" ) func main() { c := zap.NewExample().Core() logger := zap.New(zapfilter.NewFilteringCore(c, zapfilter.MustParseRules("debug:*.* info:demo*"))) fmt.Println(zapfilter.CheckLevel(logger, zap.DebugLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("demo"), zap.DebugLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("blahdemo"), zap.DebugLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("demoblah"), zap.DebugLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("blah"), zap.DebugLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("blah.blah"), zap.DebugLevel)) fmt.Println(zapfilter.CheckLevel(logger, zap.InfoLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("demo"), zap.InfoLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("blahdemo"), zap.InfoLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("demoblah"), zap.InfoLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("blah"), zap.InfoLevel)) fmt.Println(zapfilter.CheckLevel(logger.Named("blah.blah"), zap.InfoLevel)) }
Output: false false false false false true false true false true false false
func NewFilteringCore ¶
func NewFilteringCore(next zapcore.Core, filter FilterFunc) zapcore.Core
NewFilteringCore returns a core middleware that uses the given filter function to determine whether to actually call Write on the next core in the chain.
Example (Newlogger) ¶
package main import ( "go.uber.org/zap" "moul.io/zapfilter" ) func main() { c := zap.NewExample().Core() logger := zap.New(zapfilter.NewFilteringCore(c, zapfilter.MustParseRules("demo*"))) defer logger.Sync() logger.Debug("hello world!") logger.Named("demo").Debug("hello earth!") logger.Named("other").Debug("hello universe!") }
Output: {"level":"debug","logger":"demo","msg":"hello earth!"}
Example (Wrap) ¶
package main import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "moul.io/zapfilter" ) func main() { filtered := zap.WrapCore(func(c zapcore.Core) zapcore.Core { return zapfilter.NewFilteringCore(c, zapfilter.MustParseRules("demo*")) }) logger := zap.NewExample() defer logger.Sync() logger.WithOptions(filtered).Debug("hello world!") logger.WithOptions(filtered).Named("demo").Debug("hello earth!") logger.WithOptions(filtered).Named("other").Debug("hello universe!") }
Output: {"level":"debug","logger":"demo","msg":"hello earth!"}
Types ¶
type FilterFunc ¶
FilterFunc is used to check whether to filter the given entry and filters out.
Example (Custom) ¶
package main import ( "math/rand" "go.uber.org/zap" "go.uber.org/zap/zapcore" "moul.io/zapfilter" ) func main() { rand.Seed(42) core := zap.NewExample().Core() filterFunc := func(entry zapcore.Entry, fields []zapcore.Field) bool { return rand.Intn(2) == 1 } logger := zap.New(zapfilter.NewFilteringCore(core, filterFunc)) defer logger.Sync() logger.Debug("hello city!") logger.Debug("hello region!") logger.Debug("hello planet!") logger.Debug("hello solar system!") logger.Debug("hello universe!") logger.Debug("hello multiverse!") }
Output: {"level":"debug","msg":"hello city!"} {"level":"debug","msg":"hello solar system!"}
func ByLevels ¶ added in v1.6.1
func ByLevels(pattern string) (FilterFunc, error)
ByLevels creates a FilterFunc based on a pattern.
Level Patterns
| Pattern | Debug | Info | Warn | Error | DPanic | Panic | Fatal | | ------- | ----- | ---- | ---- | ----- | ------ | ----- | ----- | | <empty> | X | X | X | X | X | X | X | | * | X | X | X | X | x | X | X | | debug | X | | | | | | | | info | | X | | | | | | | warn | | | X | | | | | | error | | | | X | | | | | dpanic | | | | | X | | | | panic | | | | | | X | | | fatal | | | | | | | X | | debug+ | X | X | x | X | X | X | X | | info+ | | X | X | X | X | X | X | | warn+ | | | X | X | X | X | X | | error+ | | | | X | X | X | X | | dpanic+ | | | | | X | X | X | | panic+ | | | | | | X | X | | fatal+ | | | | | | | X |
func ByNamespaces ¶
func ByNamespaces(input string) FilterFunc
ByNamespaces takes a list of patterns to filter out logs based on their namespaces. Patterns are checked using path.Match.
Example ¶
package main import ( "go.uber.org/zap" "moul.io/zapfilter" ) func main() { core := zap.NewExample().Core() logger := zap.New(zapfilter.NewFilteringCore(core, zapfilter.ByNamespaces("demo1.*,demo3.*"))) defer logger.Sync() logger.Debug("hello city!") logger.Named("demo1.frontend").Debug("hello region!") logger.Named("demo2.frontend").Debug("hello planet!") logger.Named("demo3.frontend").Debug("hello solar system!") }
Output: {"level":"debug","logger":"demo1.frontend","msg":"hello region!"} {"level":"debug","logger":"demo3.frontend","msg":"hello solar system!"}
func ExactLevel ¶
func ExactLevel(level zapcore.Level) FilterFunc
ExactLevel filters out entries with an invalid level.
func MinimumLevel ¶
func MinimumLevel(level zapcore.Level) FilterFunc
MinimumLevel filters out entries with a too low level.
func MustParseRules ¶
func MustParseRules(pattern string) FilterFunc
MustParseRules calls ParseRules and panics if initialization failed.
func ParseRules ¶
func ParseRules(pattern string) (FilterFunc, error)
ParseRules takes a CLI-friendly set of rules to construct a filter.
Syntax
pattern: RULE [RULE...] RULE: one of: - LEVELS:NAMESPACES - NAMESPACES LEVELS: LEVEL,[,LEVEL] LEVEL: see `Level Patterns` NAMESPACES: NAMESPACE[,NAMESPACE] NAMESPACE: one of: - namespace // should be exactly this namespace - *mat*ch* // should match - -NAMESPACE // should not match
Examples
- everything *:* everything info:* level info; any namespace info+:* levels info, warn, error, dpanic, panic, and fatal; any namespace info,warn:* levels info, warn; any namespace ns1 any level; namespace 'ns1' *:ns1 any level; namespace 'ns1' ns1* any level; namespaces matching 'ns1*' *:ns1* any level; namespaces matching 'ns1*' *:ns1,ns2 any level; namespaces 'ns1' and 'ns2' *:ns*,-ns3* any level; namespaces matching 'ns*' but not matching 'ns3*' info:ns1 level info; namespace 'ns1' info,warn:ns1,ns2 levels info and warn; namespaces 'ns1' and 'ns2' info:ns1 warn:n2 level info + namespace 'ns1' OR level warn and namespace 'ns2' info,warn:myns* error+:* levels info or warn and namespaces matching 'myns*' OR levels error, dpanic, panic or fatal for any namespace
Example ¶
package main import ( "go.uber.org/zap" "moul.io/zapfilter" ) func main() { core := zap.NewExample().Core() // *=myns => any level, myns namespace // info,warn:myns.* => info or warn level, any namespace matching myns.* // error=* => everything with error level logger := zap.New(zapfilter.NewFilteringCore(core, zapfilter.MustParseRules("*:myns info,warn:myns.* error:*"))) defer logger.Sync() logger.Debug("top debug") // no match logger.Named("myns").Debug("myns debug") // matches *:myns logger.Named("bar").Debug("bar debug") // no match logger.Named("myns").Named("foo").Debug("myns.foo debug") // no match logger.Info("top info") // no match logger.Named("myns").Info("myns info") // matches *:myns logger.Named("bar").Info("bar info") // no match logger.Named("myns").Named("foo").Info("myns.foo info") // matches info,warn:myns.* logger.Warn("top warn") // no match logger.Named("myns").Warn("myns warn") // matches *:myns logger.Named("bar").Warn("bar warn") // no match logger.Named("myns").Named("foo").Warn("myns.foo warn") // matches info,warn:myns.* logger.Error("top error") // matches error:* logger.Named("myns").Error("myns error") // matches *:myns and error:* logger.Named("bar").Error("bar error") // matches error:* logger.Named("myns").Named("foo").Error("myns.foo error") // matches error:* }
Output: {"level":"debug","logger":"myns","msg":"myns debug"} {"level":"info","logger":"myns","msg":"myns info"} {"level":"info","logger":"myns.foo","msg":"myns.foo info"} {"level":"warn","logger":"myns","msg":"myns warn"} {"level":"warn","logger":"myns.foo","msg":"myns.foo warn"} {"level":"error","msg":"top error"} {"level":"error","logger":"myns","msg":"myns error"} {"level":"error","logger":"bar","msg":"bar error"} {"level":"error","logger":"myns.foo","msg":"myns.foo error"}
func Reverse ¶
func Reverse(filter FilterFunc) FilterFunc
Reverse checks is the passed filter returns false.