✒️ logx
logx is a zero-dependency simple, fast and easy-to-use level-based logger written in Go Programming Language.
🚀 Installation
The only requirement is the Go Programming Language*.
Go modules
$ go get gitee.com/menciis/logx@latest
Or edit your project's go.mod file and execute $ go build.
module your_project_name
go 1.19
require (
gitee.com/menciis/logx v0.1.8
)
$ go build
$ go get gitee.com/menciis/logx@latest
package main
import (
"gitee.com/menciis/logx"
)
func main() {
logx.SetLevel("debug")
logx.Println("This is a raw message, no levels, no colors.")
logx.Info("This is an info message, with colors (if the output is terminal)")
logx.Warn("This is a warning message")
logx.Error("This is an error message")
logx.Debug("This is a debug message")
logx.Fatal(`Fatal will exit no matter what,
but it will also print the log message if logger's Level is >=FatalLevel`)
}
Log Levels
Name | Method | Text | Color |
---|
"fatal" | Fatal, Fatalf | [FTAL] | Red background |
"error" | Error, Errorf | [ERRO] | Red foreground |
"warn" | Warn, Warnf, Warningf | [WARN] | Magenta foreground |
"info" | Info, Infof | [INFO] | Cyan foreground |
"debug" | Debug, Debugf | [DBUG] | Yellow foreground |
On debug level the logger will store stacktrace information to the log instance, which is not printed but can be accessed through a Handler
(see below).
Helpers
fatalRichText := logx.GetTextForLevel(logx.FatalLevel, true)
level := logx.ParseLevel("debug")
Customization
You can customize the log level attributes.
func init() {
errorAttrs := logx.Levels[logx.ErrorLevel]
customColorCode := 156
errorAttrs.SetText("custom text", customColorCode)
enableColors := true
errorRichText := errorAttrs.Text(enableColors)
}
Alternatively, to change a specific text on a known log level, you can just call:
logx.ErrorText("custom text", 156)
Integration
The logx.Logger
is using common, expected log methods, therefore you can integrate it with ease.
Take for example the badger database. You want to add a prefix of [badger]
in your logs when badger wants to print something.
- Create a child logger with a prefix text using the
Child
function, - disable new lines (because they are managed by badger itself) and you are ready to GO:
opts := badger.DefaultOptions("./data")
opts.Logger = logx.Child("[badger]").DisableNewLine()
db, err := badger.Open(opts)
Level-based and standard Loggers
You can put logx
in front of your existing loggers using the Install and InstallStd methods.
Any level-based Logger that implements the ExternalLogger can be adapted.
E.g. sirupsen/logrus:
logrus.SetLevel(logrus.InfoLevel)
logrus.SetFormatter(&logrus.JSONFormatter{})
logx.Install(logrus.StandardLogger())
logx.Debug(`this debug message will not be shown,
because the logrus level is InfoLevel`)
logx.Error(`this error message will be visible as JSON,
because of logrus.JSONFormatter`)
Any standard logger (without level capabilities) that implements the StdLogger can be adapted using the InstallStd method.
E.g. log
standard package:
myLogger := log.New(os.Stdout, "", 0)
logx.SetLevel("error")
logx.InstallStd(myLogger)
logx.Error("error message")
Output Format
Any value that completes the Formatter interface can be used to write to the (leveled) output writer. By default the "json"
formatter is available.
JSON
import "gitee.com/menciis/logx"
func main() {
logx.SetLevel("debug")
logx.SetFormat("json", " ")
logx.Debugf("This is a %s with data (debug prints the stacktrace too)", "message", logx.Fields{
"username": "kataras",
})
}
Output
{
"timestamp": 1591423477,
"level": "debug",
"message": "This is a message with data (debug prints the stacktrace too)",
"fields": {
"username": "kataras"
},
"stacktrace": [
{
"function": "main.main",
"source": "C:/example/main.go:29"
}
]
}
Register custom Formatter
logx.RegisterFormatter(new(myFormatter))
logx.SetFormat("myformat", options...)
The Formatter
interface looks like this:
type Formatter interface {
String() string
Options(opts ...interface{}) Formatter
Format(dest io.Writer, log *Log) bool
}
Custom Format using Handler
The Logger can accept functions to handle (and print) each Log through its Handle method. The Handle method accepts a Handler.
type Handler func(value *Log) (handled bool)
This method can be used to alter Log's fields based on custom logic or to change the output destination and its output format.
Create a JSON handler
import "encoding/json"
func jsonOutput(l *logx.Log) bool {
enc := json.NewEncoder(l.Logger.GetLevelOutput(l.Level.String()))
enc.SetIndent("", " ")
err := enc.Encode(l)
return err == nil
}
Register the handler and log something
import "gitee.com/menciis/logx"
func main() {
logx.SetLevel("debug")
logx.Handle(jsonOutput)
logx.Debugf("This is a %s with data (debug prints the stacktrace too)", "message", logx.Fields{
"username": "kataras",
})
}
Examples
🔥 Benchmarks
test | times ran (large is better) | ns/op (small is better) | B/op (small is better) | allocs/op (small is better) |
---|
BenchmarklogxPrint | 10000000 | 3749 ns/op | 890 B/op | 28 allocs/op |
BenchmarkLogrusPrint | 3000000 | 9609 ns/op | 1611 B/op | 64 allocs/op |
Click here for details.
👥 Contributing
If you find that something is not working as expected please open an issue.