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
Documentation ¶
Index ¶
- Constants
- func Debug(args ...interface{})
- func DebugWithFields(msg string, fields KV)
- func Debugf(format string, v ...interface{})
- func Debugln(args ...interface{})
- func Debugw(msg string, keyValues KV)
- func Error(args ...interface{})
- func ErrorWithFields(msg string, fields KV)
- func Errorf(format string, v ...interface{})
- func Errorln(args ...interface{})
- func Errors(err error)
- func Errorw(msg string, keyValues KV)
- func Fatal(args ...interface{})
- func FatalWithFields(msg string, fields KV)
- func Fatalf(format string, v ...interface{})
- func Fatalln(args ...interface{})
- func Fatalw(msg string, keyValues KV)
- func GetCtxID(ctx context.Context) string
- func GetCtxRequestID(ctx context.Context) string
- func Info(args ...interface{})
- func InfoWithFields(msg string, fields KV)
- func Infof(format string, v ...interface{})
- func Infoln(args ...interface{})
- func Infow(msg string, keyValues KV)
- func InitLogContext(ctx context.Context) context.Context
- func Print(v ...interface{})
- func Printf(format string, v ...interface{})
- func Println(v ...interface{})
- func SetConfig(config *Config) error
- func SetCtxID(ctx context.Context, contextID string) context.Context
- func SetCtxRequestID(ctx context.Context, uuid string) context.Context
- func SetLevel(level Level)
- func SetLevelString(level string)
- func SetLogger(level logger.Level, lgr logger.Logger) error
- func SetStdLog(config *Config) error
- func StdDebug(ctx context.Context, metadata interface{}, err error, message string)
- func StdDebugf(ctx context.Context, metadata interface{}, err error, format string, ...)
- func StdError(ctx context.Context, metadata interface{}, err error, message string)
- func StdErrorf(ctx context.Context, metadata interface{}, err error, format string, ...)
- func StdFatal(ctx context.Context, metadata interface{}, err error, message string)
- func StdFatalf(ctx context.Context, metadata interface{}, err error, format string, ...)
- func StdInfo(ctx context.Context, metadata interface{}, err error, message string)
- func StdInfof(ctx context.Context, metadata interface{}, err error, format string, ...)
- func StdTrace(ctx context.Context, metadata interface{}, err error, message string)
- func StdTracef(ctx context.Context, metadata interface{}, err error, format string, ...)
- func StdWarn(ctx context.Context, metadata interface{}, err error, message string)
- func StdWarnf(ctx context.Context, metadata interface{}, err error, format string, ...)
- func Warn(args ...interface{})
- func WarnWithFields(msg string, fields KV)
- func Warnf(format string, v ...interface{})
- func Warnln(args ...interface{})
- func Warnw(msg string, keyValues KV)
- type Config
- type Engine
- type KV
- type Level
- type Logger
Constants ¶
const ( TraceLevel = logger.TraceLevel DebugLevel = logger.DebugLevel InfoLevel = logger.InfoLevel WarnLevel = logger.WarnLevel ErrorLevel = logger.ErrorLevel FatalLevel = logger.FatalLevel )
Level option
const (
RFC3339Milli = "2006-01-02T15:04:05.999Z07:00"
)
RFC3339Milli We agree that we want a millisecond precisstion, sadly in golang it's not there. https://github.com/golang/go/issues/13291
Variables ¶
This section is empty.
Functions ¶
func DebugWithFields ¶
DebugWithFields prints debug level log with additional fields. useful when output is in json format
func Debugf ¶
func Debugf(format string, v ...interface{})
Debugf prints debug level log like log.Printf
func ErrorWithFields ¶
ErrorWithFields prints error level log with additional fields. useful when output is in json format
func Errorf ¶
func Errorf(format string, v ...interface{})
Errorf prints error level log like log.Printf
func FatalWithFields ¶
FatalWithFields prints fatal level log with additional fields. useful when output is in json format
func Fatalf ¶
func Fatalf(format string, v ...interface{})
Fatalf prints fatal level log like log.Printf
func GetCtxRequestID ¶
GetCtxRequestID get request id from context
func InfoWithFields ¶
InfoWithFields prints info level log with additional fields. useful when output is in json format
func Infof ¶
func Infof(format string, v ...interface{})
Infof prints info level log like log.Printf
func InitLogContext ¶
InitLogContext will initialize context with some informations Currently it will inject request id using xid Ideally InitLogContext will be wrap around middleware, either grpc or http For Request ID will currently set it with xid if empty. Can be explored with trace id
func SetCtxRequestID ¶
SetCtxRequestID set context with request id
func SetLevel ¶
func SetLevel(level Level)
SetLevel adjusts log level threshold. Only log with level higher or equal with this level will be printed
func SetLevelString ¶
func SetLevelString(level string)
SetLevelString adjusts log level threshold using string
func SetStdLog ¶
SetStdLog will be the entry point for tdk logging library to make sure all Tokopedia services have the same log structures. The general specification will be JSON, request id, context id, metadata, error and message. For more specifications please go to https://tokopedia.atlassian.net/wiki/spaces/EN/pages/694817819/Logging+Format+Standardization
func StdDebugf ¶
func StdDebugf(ctx context.Context, metadata interface{}, err error, format string, args ...interface{})
StdDebugf print trace level log with standardized parameters with formatter.
func StdErrorf ¶
func StdErrorf(ctx context.Context, metadata interface{}, err error, format string, args ...interface{})
StdErrorf print trace level log with standardized parameters with formatter.
func StdFatalf ¶
func StdFatalf(ctx context.Context, metadata interface{}, err error, format string, args ...interface{})
StdFatalf print trace level log with standardized parameters with formatter.
func StdInfof ¶
func StdInfof(ctx context.Context, metadata interface{}, err error, format string, args ...interface{})
StdInfof print trace level log with standardized parameters with formatter.
func StdTracef ¶
func StdTracef(ctx context.Context, metadata interface{}, err error, format string, args ...interface{})
StdTracef print trace level log with standardized parameters with formatter.
func StdWarnf ¶
func StdWarnf(ctx context.Context, metadata interface{}, err error, format string, args ...interface{})
StdWarnf print trace level log with standardized parameters with formatter.
func WarnWithFields ¶
WarnWithFields prints warn level log with additional fields. useful when output is in json format
Types ¶
type Config ¶
type Config struct { // log level, default: debug Level string // Format of the log's time field // default RFC3339="2006-01-02T15:04:05Z07:00" TimeFormat string // AppName is the application name this log belong to AppName string // Caller, option to print caller line numbers. // make sure you understand the overhead when use this Caller bool // LogFile is output file for log other than debug log // this is not needed by default, // application is expected to run in containerized environment LogFile string // DebugFile is output file for debug log // this is not needed by default, // application is expected to run in containerized environment DebugFile string // Deprecated, this field will have no effect // keeping it for backward compatibility Engine Engine // UseColor, option to colorize log in console. // Deprecated true if and only if TKPENV=development UseColor bool // UseJSON, option to print in json format. UseJSON bool // StdLog, option to use standardized Log StdLog bool // CallerSkip, option to skip caller frame CallerSkip int }
Config of log