High performance, structured and flexible logging. Leverage the destination of your logs using context
and handler levels setting up different ones for each handlers (i.e. write to stdout only when tracing
and to syslog only when an error occurs)
Grab it.
go get -u github.com/Tlantic/meerkats
Note: Due to the continue development of meerkats please consider using a package manager that supports semantic versioning like Glide.
Basic Usage --- ### Handlers By default meerkats won't initialize any handler and therefore won't event write to stdout, nevertheless a basic [Writer Handler](https://github.com/Tlantic/meerkats/tree/master/handlers/writer) subpackage is shipped with it that implements io.Writer allowing you to write entries to stdout or any other file.
In order to register a handler just use the Register() logger method.
handler := writer.New()
kat.Register(handler)
The Level type serves a double purpose. It is used to instruct meerkats from which level should an entry be considered and passed down to its handlers.
kat.SetLevel(kat.LevelInfo)
kat.Trace("trace entry") // Ignored even if a handler subscribed to such level
kat.Info("info entry") // Dispatched to handlers
kat.Warning("warning entry") // Dispatched to handlers
It can also be used to tell handlers what entries will they dispatch by using bitwise ops.
handler := writer.New()
handler.SetLevel(kat.LevelDebug|kat.LevelWarning|kat.LevelError)
kat.Register(handler)
kat.Debug("debug entry") // Dispatched to handler
kat.Info("info entry") // Ignored
kat.Error("error entry") // Dispatched to handler
Meerkats took inspiration from Zap using a more verbose method of adding fields to log entries delegating the efforts of field type assertions to the developer instead of using reflection methods during runtime. Face it, most of the fields type is known prior execution so theres no excuse to hurt performance.
import (
rand
kat "github.com/Tlantic/meerkats"
"github.com/Tlantic/meerkats/handlers/writer"
)
func main() {
kat.Trace("Init message", kat.String("foo", "bar"), kat.Int("random", rand.Int()) )
}
Logs written while bootstrapping are somehow different that those written within a HTTP request handler. With this in mind meerkats allows you to contextualize logger instances, inheriting fields and handlers from a parent context.
package main
import (
"io"
"net/http"
kat "github.com/Tlantic/meerkats"
"github.com/Tlantic/meerkats/handlers/writer"
)
func main() {
// initialize root
kat.Register(writer.New())
kat.EmitString("service-name", "svc-test")
err := http.ListenAndServe(":12345", func (w http.ResponseWriter, req *http.Request) {
log := kat.Child() // create new logger context
log.EmitString("Origin", req.Header.Get("Origin"))
//...
io.WriteString(w, "Ok")
}))
panic(err)
}
Some packages may not want to directly depend on meerkats to use a logger or wan't a more generic interface to interact with. To satisfy such need Meerkats can be wrapped within a StandardLogger instance.
logger := kat.New(writer.New(kat.Level(kat.LevelInfo|kat.LevelError|kat.LevelFatal|kat.LevelPanic)))
std := kat.NewStandardLogger(logger, kat.LevelInfo)
Since the logger implements the io.Writer interface meerkats can be used as the standard go log package output.
logger := kat.New()
log.SetOutput(logger)