package
1.10.1
Repository: https://github.com/kodekoding/phastos.git
Documentation: pkg.go.dev

# Packages

No description provided by the author

# 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

FieldTypeDescription
AppNamestringapplication name, needed by log server for easy filtering
Levelstringspecify log level (default:debug)
LogFilestringspecify output file for infoLevel - fatalLevel log (default: no file)
DebugFilestringspecify output file for debugLevel log (default: no file)
TimeFormatstringspecify time format (default:RFC3339="2006-01-02T15:04:05Z07:00")
Callerboolprint caller position or not (default=false)
UseJSONboolprint 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