# README
TDK Log
TDK Log is based on Zerolog log package. The logger is fully compatible with tokopedia log platform.
Log Configuration
The logger package can be used directly without needing of any configuration. But we still provide configuration mechanism for flexibility
Configuration
Field | Type | Description |
---|---|---|
AppName | string | application name, needed by log server for easy filtering |
Level | string | specify log level (default:debug) |
LogFile | string | specify output file for infoLevel - fatalLevel log (default: no file) |
DebugFile | string | specify output file for debugLevel log (default: no file) |
TimeFormat | string | specify time format (default:RFC3339="2006-01-02T15:04:05Z07:00") |
Caller | bool | print caller position or not (default=false) |
UseJSON | bool | print log in json format (default=false) |
We only need SetConfig
func to configure the log.
The func is not thread safe, only call it when initializing the app.
import "github.com/kodekoding/phastos/go/log"
func main() {
err := log.SetConfig(&log.Config{
Level: "info", // default is info
AppName: "my_cool_app",
LogFile: "logfile.log",
DebugFile: "debugfile.log",
})
if err != nil {
log.Fatal(err)
}
log.Info("this is a log")
}
Deprecated behaviours
Below are other behaviours which previously configurable
- Colored console format if TKPENV=development
That config field still exists, but won't take effect. It still exists to not break current code.
Log level
Log level is supported in the logger, available log level is:
- debug
- info
- warning
- error
- fatal
The log is disabled if LogLevel
< CurrentLogLevel
. For example, the Debug
log is disabled when the current level is Info
.
Log of Old TDK app (generated by tkp command)
If your app is generated using tkp
, the default is slightly different because tdk/app
overrides this. Check it in here
Advanced Customization (deprecated)
You won't need below funcs most of the time. It is provided for flexibility.
IMPORTANT NOTE: the functions in this section are not thread safe, call them when initializing the application.
1. Change Log Level
You can set log level using SetLevel
or SetLevelString
.
Example of SetLevel
:
import "github.com/kodekoding/phastos/go/log"
func main() {
log.SetLevel(log.InfoLevel)
log.Info("this is a log")
}
Example of SetLevelString
(use lowercase)
import "github.com/kodekoding/phastos/go/log"
func main() {
log.SetLevelString("info")
log.Info("this is a log")
}
2. Change logger
If you want even more flexible configuration, you can set the logger per level by yourself using SetLogger
Note: your custom logger will be replaced if you call SetConfig
after SetLogger
example: set separate output file for errorLevel
and fatalLevel
log
import "github.com/kodekoding/phastos/go/log"
import "github.com/kodekoding/phastos/go/log/logger"
func main() {
errLogger, err := log.NewLogger(log.Zerolog, &logger.Config{
Level: log.DebugLevel,
LogFile: "error.log",
})
if err != nil {
panic(err)
}
err = log.SetLogger(log.ErrorLevel, errLogger)
if err != nil {
panic(err)
}
err = log.SetLogger(log.FatalLevel, errLogger)
if err != nil {
panic(err)
}
log.Error("this is a log")
}
Available function
Each level has 3 function:
- unformatted -> like Println in standard log
- formatted -> like Printf in standard log
- with map[string]interface{} (or log.KV)
We also add several functions to ease the migration to tdk log. Function list and example:
arg1 := "hello"
arg2 := "world"
log.Debug(arg1, arg2)
log.Debugln(arg1, arg2)
log.Debugf("message %v %v", arg1, arg2)
log.DebugWithFields("message", log.KV{"arg1":arg1, "arg2":arg2})
log.Info(arg1, arg2)
log.Infoln(arg1, arg2)
log.Infof("message %v %v", arg1, arg2)
log.InfoWithFields("message", log.KV{"arg1":arg1, "arg2":arg2})
// alias for Info
log.Print(arg1, arg2)
// alias for Infoln
log.Println(arg1, arg2)
// alias for Infof
log.Printf("message %v %v", arg1, arg2)
log.Warn(arg1, arg2)
log.Warnln(arg1, arg2)
log.Warnf("message %v %v", arg1, arg2)
log.WarnWithFields("message", log.KV{"arg1":arg1, "arg2":arg2})
log.Error(arg1, arg2)
log.Errorln(arg1, arg2)
log.Errorf("message %v %v", arg1, arg2)
log.ErrorWithFields("message", log.KV{"arg1":arg1, "arg2":arg2})
log.Fatal(arg1, arg2)
log.Fatalln(arg1, arg2)
log.Fatalf("message %v %v", arg1, arg2)
log.FatalWithFields("message", log.KV{"arg1":arg1, "arg2":arg2})
Output example:
2019-03-08 17:16:48+07:00 DBG log_test.go:35 > helloworld
2019-03-08 17:16:48+07:00 DBG log_test.go:35 > hello world
2019-03-08 17:16:48+07:00 DBG log_test.go:36 > message hello world
2019-03-08 17:16:48+07:00 DBG log_test.go:37 > message arg1=hello arg2=world
2019-03-08 17:16:48+07:00 INF log_test.go:39 > helloworld
2019-03-08 17:16:48+07:00 INF log_test.go:39 > hello world
2019-03-08 17:16:48+07:00 INF log_test.go:40 > message hello world
2019-03-08 17:16:48+07:00 INF log_test.go:41 > message arg1=hello arg2=world
2019-03-08 17:16:48+07:00 INF log_test.go:44 > helloworld
2019-03-08 17:16:48+07:00 INF log_test.go:45 > hello world
2019-03-08 17:16:48+07:00 INF log_test.go:47 > message hello world
2019-03-08 17:16:48+07:00 WRN log_test.go:49 > helloworld
2019-03-08 17:16:48+07:00 WRN log_test.go:49 > hello world
2019-03-08 17:16:48+07:00 WRN log_test.go:50 > message hello world
2019-03-08 17:16:48+07:00 WRN log_test.go:51 > message arg1=hello arg2=world
2019-03-08 17:16:48+07:00 ERR log_test.go:53 > helloworld
2019-03-08 17:16:48+07:00 ERR log_test.go:53 > hello world
2019-03-08 17:16:48+07:00 ERR log_test.go:54 > message hello world
2019-03-08 17:16:48+07:00 ERR log_test.go:55 > message arg1=hello arg2=world
2019-03-08 17:16:48+07:00 FTL log_test.go:57 > helloworld
2019-03-08 17:16:48+07:00 FTL log_test.go:57 > hello world
2019-03-08 17:16:48+07:00 FTL log_test.go:57 > message hello world
2019-03-08 17:16:48+07:00 FTL log_test.go:57 > message arg1=hello arg2=world
Integration with TDK Error package
TDK error package has a features called errors.Fields
. This fields can be used to add more context into the error, and then we can print the fields when needed. TDK log will automatically print the fields if error = tdkerrors.Error
by using log.Errors
. For example:
import "github.com/kodekoding/phastos/go/log"
import "github.com/tokopedia/tdk/x/go/errors"
func main() {
err := errors.E("this is an error", errors.Fields{"field1":"value1"})
log.Errors(err)
}
// result is
// message=this is an error field1=value1