zl

package module
v1.4.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 24, 2024 License: MIT Imports: 19 Imported by: 2

README ¶

zl 🧑💻

Go Reference test Go Report Card codecov Mentioned in Awesome Go

zl is a logger based on zap. It provides advanced logging features.

zl is a logging package designed with the developer experience in mind. You can choose the most suitable output format according to your purpose, such as emphasizing easy-to-read console output during development in a local environment and outputting structured detailed logs in a production environment. It offers rich functionality but is easy to configure.

This is useful when developing systems that perform complex processing.

Features

Selectable output format

PrettyOutput (Default) 🧑💻
  • High Developer Experience.
  • The optimal setting for a development environment.
  • Output colored simple logs to the console.
  • Output detail JSON logs to the logfile.
  • Easy-to-read error reports and stack trace.
  • It can jumps directly to the line of the file that is output to the console log (when using Goland or VSCode).

image

Log messages do not have to be written in upper snake case, but if messages are written in a uniform manner, it is easy to extract specific logs using tools such as Google Cloud Logging or the jq command. It is recommended that log messages be written in a consistent manner. By writing log messages succinctly and placing detailed information in separate fields, the overall clarity of the logs is improved, making it easier to understand the flow of processes.

ConsoleOutput âš¡
  • High Performance.
  • The optimal setting for a production environment.
  • Output detail JSON logs to the console.
  • Especially suitable for cloud environments such as Google Cloud Logging or Datadog.
  • It is fast because it uses only the functions provided by zap (not sugared) and does not perform any extra processing.
FileOutput
  • The optimal setting for a production environment.
  • It is especially suitable for command line tool or on-premises environments.
  • Support logfile rotation.
ConsoleAndFileOutput
  • It is a setting for the development environment.
  • Output detail JSON logs to console and logfile.
  • It is recommended to use with jq command to avoid drowning in a sea of information.
  • It is recommended to set PrettyOutput instead.

Installation

go get -u github.com/nkmr-jp/zl

Quick Start

code: examples/basic/main.go

package main

import (
	"encoding/json"
	"os"
	"strconv"

	"github.com/nkmr-jp/zl"
	"go.uber.org/zap"
)

func main() {
	// Set Options
	zl.SetLevel(zl.DebugLevel)
	zl.SetOmitKeys(zl.HostnameKey)

	// Initialize
	zl.Init()
	defer zl.Sync() // flush log buffer

	// Write logs
	zl.Info("USER_INFO", zap.String("user_name", "Alice"), zap.Int("user_age", 20)) // can use zap fields.
	zl.Info("DISPLAY_TO_CONSOLE", zl.Console("The message you want to display to console"))
	zl.Warn("WARN_MESSAGE")
	zl.Debug("DEBUG_MESSAGE")
	_, err := os.ReadFile("test")
	zl.Err("READ_FILE_ERROR", err)
	
	// if the same error occurs multiple times in the same location, the error report will show them all together.
	for i := 0; i < 2; i++ {
		_, err = strconv.Atoi("one")
		zl.Err("A_TO_I_ERROR", err)
	}
	for i := 0; i < 3; i++ {
		v := ""
		err = json.Unmarshal([]byte("test"), &v)
		zl.Err("JSON_UNMARSHAL_ERROR", err)
	}
}

Console output.
The console displays minimal information. Displays a stack trace when an error occurs. image

File output.
Detailed information is available in the log file. You can also use jq to extract only the information you need.

$ cat log/app.jsonl | jq 'select(.message | startswith("USER_")) | select(.pid==921)'
{
  "severity": "INFO",
  "timestamp": "2022-08-22T10:30:39.154575+09:00",
  "caller": "basic/main.go:22",
  "function": "main.main",
  "message": "USER_INFO",
  "version": "fc43f68",
  "pid": 921,
  "user_name": "Alice",
  "user_age": 20
}
   

Examples

Documentation ¶

Overview ¶

Package zl is a logger based on zap. It provides advanced logging features. It is designed with the developer's experience in mind and allows the user to choose the best output format for their purposes.

Example ¶
package main

import (
	"fmt"
	"github.com/nkmr-jp/zl"
	"go.uber.org/zap"
	"log"
	"os"
)

func setupForExampleTest() {
	if err := os.RemoveAll("./log"); err != nil {
		log.Fatal(err)
	}
	zl.ResetGlobalLoggerSettings()
	zl.SetIsTest()
}

func main() {
	setupForExampleTest()

	// Set options
	fileName := "./log/example.jsonl"
	zl.SetLevel(zl.DebugLevel)
	// zl.SetOutput(zl.PrettyOutput)
	zl.SetOmitKeys(zl.TimeKey, zl.CallerKey, zl.VersionKey, zl.HostnameKey, zl.StacktraceKey, zl.PIDKey)
	zl.SetRotateFileName(fileName)

	// Initialize
	zl.Init()
	defer zl.Sync() // flush log buffer

	// Write logs
	zl.Info("USER_INFO", zap.String("user_name", "Alice"), zap.Int("user_age", 20)) // can use zap fields.

	console := "display to console when output type is pretty"
	zl.Info("DISPLAY_TO_CONSOLE", zl.Console(console))
	zl.Info("DISPLAY_TO_CONSOLE", zl.Consolep(&console))
	zl.Info("DISPLAY_TO_CONSOLE", zl.Consolef("message: %s", console))

	// write error to error field.
	_, err := os.ReadFile("test")
	zl.Info("READ_FILE_ERROR", zap.Error(err))
	zl.InfoErr("READ_FILE_ERROR", err) // same to above.
	zl.Debug("READ_FILE_ERROR", zap.Error(err))
	zl.DebugErr("READ_FILE_ERROR", err) // same to above.
	zl.Warn("READ_FILE_ERROR", zap.Error(err))
	zl.WarnErr("READ_FILE_ERROR", err) // same to above.
	zl.Error("READ_FILE_ERROR", zap.Error(err))
	zl.ErrorErr("READ_FILE_ERROR", err) // same to above.
	zl.Err("READ_FILE_ERROR", err)      // same to above.
	zl.ErrRet("READ_FILE_ERROR", err)   // write error to log and return same error.
	zl.Fatal("READ_FILE_ERROR", zap.Error(err))
	zl.FatalErr("READ_FILE_ERROR", err) // same to above.

	fmt.Println("\nlog file output:")
	bytes, _ := os.ReadFile(fileName)
	fmt.Println(string(bytes))

	// Output to stderr with colored:
	// zl.go:82: DEBUG INIT_LOGGER:Severity: DEBUG, Output: Pretty, File: ./log/example.jsonl
	// example_test.go:40: INFO USER_INFO
	// example_test.go:43: INFO DISPLAY_TO_CONSOLE:display to console when output type is pretty
	// example_test.go:44: INFO DISPLAY_TO_CONSOLE:display to console when output type is pretty
	// example_test.go:45: INFO DISPLAY_TO_CONSOLE:message: display to console when output type is pretty
	// example_test.go:49: INFO READ_FILE_ERROR
	// example_test.go:50: INFO READ_FILE_ERROR:open test: no such file or directory
	// example_test.go:51: DEBUG READ_FILE_ERROR
	// example_test.go:52: DEBUG READ_FILE_ERROR:open test: no such file or directory
	// example_test.go:53: WARN READ_FILE_ERROR
	// example_test.go:54: WARN READ_FILE_ERROR:open test: no such file or directory
	// example_test.go:55: ERROR READ_FILE_ERROR
	// example_test.go:56: ERROR READ_FILE_ERROR:open test: no such file or directory
	// example_test.go:57: ERROR READ_FILE_ERROR:open test: no such file or directory
	// example_test.go:58: ERROR READ_FILE_ERROR:open test: no such file or directory
	// example_test.go:59: FATAL READ_FILE_ERROR
	// example_test.go:60: FATAL READ_FILE_ERROR:open test: no such file or directory

}
Output:

os.Exit(1) called.
os.Exit(1) called.

log file output:
{"severity":"DEBUG","function":"github.com/nkmr-jp/zl.Init.func1","message":"INIT_LOGGER","console":"Severity: DEBUG, Output: Pretty, File: ./log/example.jsonl"}
{"severity":"INFO","function":"github.com/nkmr-jp/zl_test.Example","message":"USER_INFO","user_name":"Alice","user_age":20}
{"severity":"INFO","function":"github.com/nkmr-jp/zl_test.Example","message":"DISPLAY_TO_CONSOLE","console":"display to console when output type is pretty"}
{"severity":"INFO","function":"github.com/nkmr-jp/zl_test.Example","message":"DISPLAY_TO_CONSOLE","console":"display to console when output type is pretty"}
{"severity":"INFO","function":"github.com/nkmr-jp/zl_test.Example","message":"DISPLAY_TO_CONSOLE","console":"message: display to console when output type is pretty"}
{"severity":"INFO","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"INFO","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"DEBUG","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"DEBUG","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"WARN","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"WARN","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"ERROR","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"ERROR","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"ERROR","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"ERROR","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"FATAL","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}
{"severity":"FATAL","function":"github.com/nkmr-jp/zl_test.Example","message":"READ_FILE_ERROR","error":"open test: no such file or directory"}

Index ¶

Examples ¶

Constants ¶

View Source
const (
	DebugLevel = zapcore.DebugLevel
	InfoLevel  = zapcore.InfoLevel
	WarnLevel  = zapcore.WarnLevel
	ErrorLevel = zapcore.ErrorLevel
	FatalLevel = zapcore.FatalLevel
)
View Source
const (
	FileNameDefault   = "./log/app.jsonl"
	MaxSizeDefault    = 100 // megabytes
	MaxBackupsDefault = 3
	MaxAgeDefault     = 7 // days
)

Variables ¶

This section is empty.

Functions ¶

func Cleanup ¶

func Cleanup()

Cleanup Deprecated: Use ResetGlobalLoggerSettings instead. # codecov ignore

func Console ¶

func Console(val string) zap.Field

Console is display to console when output type is pretty.

func Consolef ¶

func Consolef(format string, a ...interface{}) zap.Field

Consolef formats according to a format specifier and display to console when output type is pretty.

func Consolep ¶

func Consolep(val *string) zap.Field

Consolep is display to console when output type is pretty.

func Debug ¶

func Debug(message string, fields ...zap.Field)

Debug is wrapper of Zap's Debug.

func DebugErr ¶

func DebugErr(message string, err error, fields ...zap.Field)

DebugErr is Outputs a DEBUG log with error field.

func Dump ¶

func Dump(a ...interface{})

Dump is a deep pretty printer for Go data structures to aid in debugging. It is only works with PrettyOutput settings.

It is wrapper of go-spew. See: https://github.com/davecgh/go-spew

Example ¶
package main

import (
	"github.com/nkmr-jp/zl"
	"log"
	"os"
)

func setupForExampleTest() {
	if err := os.RemoveAll("./log"); err != nil {
		log.Fatal(err)
	}
	zl.ResetGlobalLoggerSettings()
	zl.SetIsTest()
}

func main() {
	setupForExampleTest()

	zl.SetLevel(zl.DebugLevel)
	zl.SetRotateFileName("./log/example-Dump.jsonl")
	zl.Init()
	defer zl.Sync() // flush log buffer
	zl.Dump("test")
}
Output:

func Err ¶ added in v1.1.0

func Err(message string, err error, fields ...zap.Field)

Err is alias of ErrorErr.

func ErrRet ¶ added in v1.2.0

func ErrRet(message string, err error, fields ...zap.Field) error

ErrRet write error log and return error. A typical usage would be something like.

if err != nil {
  return zl.ErrRet("SOME_ERROR", fmt.Error("some message err: %w",err))
}

func Error ¶

func Error(message string, fields ...zap.Field)

Error is wrapper of Zap's Error.

Example ¶
package main

import (
	"encoding/json"
	"fmt"
	"github.com/nkmr-jp/zl"
	"log"
	"os"
)

func setupForExampleTest() {
	if err := os.RemoveAll("./log"); err != nil {
		log.Fatal(err)
	}
	zl.ResetGlobalLoggerSettings()
	zl.SetIsTest()
}

func main() {
	setupForExampleTest()

	zl.SetOmitKeys(zl.TimeKey, zl.VersionKey, zl.HostnameKey)

	// Initialize
	zl.Init()
	defer zl.Sync() // flush log buffer

	_, err := os.ReadFile("test")
	zl.Err("READ_FILE_ERROR", err)
	zl.Info("INFO")
	zl.InfoErr("INFO_ERR", fmt.Errorf("error"))
	v := ""
	err = json.Unmarshal([]byte("test"), &v)
	zl.Err("JSON_UNMARSHAL_ERROR", err)

	for i := 0; i < 3; i++ {
		err = fmt.Errorf("if the same error occurs multiple times in the same location, the error report will show them all together")
		zl.Err("ERRORS_IN_LOOPS", err)
	}
}
Output:

func ErrorErr ¶ added in v1.1.0

func ErrorErr(message string, err error, fields ...zap.Field)

ErrorErr is Outputs ERROR log with error field.

func Fatal ¶

func Fatal(message string, fields ...zap.Field)

Fatal is wrapper of Zap's Fatal.

func FatalErr ¶ added in v1.1.0

func FatalErr(message string, err error, fields ...zap.Field)

FatalErr is Outputs ERROR log with error field.

func GetVersion ¶

func GetVersion() string

GetVersion return version when version is set. or return git commit hash when version is not set.

func Info ¶

func Info(message string, fields ...zap.Field)

Info is wrapper of Zap's Info.

func InfoErr ¶

func InfoErr(message string, err error, fields ...zap.Field)

InfoErr is Outputs INFO log with error field.

func Init ¶

func Init()

Init initializes the logger.

func ResetGlobalLoggerSettings ¶ added in v1.3.0

func ResetGlobalLoggerSettings()

ResetGlobalLoggerSettings resets global logger settings. This is convenient for use in tests, etc.

func SetConsoleFields ¶

func SetConsoleFields(fieldKey ...string)

SetConsoleFields add the fields to be displayed in the console when PrettyOutput is used.

func SetFieldKey ¶ added in v1.4.0

func SetFieldKey(key Key, val string)

SetFieldKey is changes the key of the default field.

Example ¶
package main

import (
	"github.com/nkmr-jp/zl"
	"log"
	"os"
)

func setupForExampleTest() {
	if err := os.RemoveAll("./log"); err != nil {
		log.Fatal(err)
	}
	zl.ResetGlobalLoggerSettings()
	zl.SetIsTest()
}

func main() {
	setupForExampleTest()

	zl.SetOutputByString("Console")
	zl.SetStdout()
	zl.SetOmitKeys(
		zl.LevelKey, zl.LoggerKey, zl.TimeKey,
		zl.CallerKey, zl.VersionKey, zl.HostnameKey, zl.StacktraceKey, zl.PIDKey,
	)
	zl.SetFieldKey(zl.MessageKey, "msg")
	zl.SetFieldKey(zl.FunctionKey, "fn")
	zl.Init()
	zl.Info("INFO_MESSAGE")

}
Output:

{"fn":"github.com/nkmr-jp/zl_test.ExampleSetFieldKey","msg":"INFO_MESSAGE"}

func SetIsTest ¶ added in v1.2.1

func SetIsTest()

SetIsTest sets isTest flag to true.

func SetLevel ¶

func SetLevel(level zapcore.Level)

SetLevel is set log. level can use (DebugLevel, InfoLevel, WarnLevel, ErrorLevel, FatalLevel).

func SetLevelByString ¶

func SetLevelByString(levelStr string)

SetLevelByString is set log level. levelStr can use (DEBUG, INFO, WARN, ERROR, FATAL).

Example ¶
package main

import (
	"github.com/nkmr-jp/zl"
	"log"
	"os"
)

func setupForExampleTest() {
	if err := os.RemoveAll("./log"); err != nil {
		log.Fatal(err)
	}
	zl.ResetGlobalLoggerSettings()
	zl.SetIsTest()
}

func main() {
	setupForExampleTest()

	zl.SetLevelByString("DEBUG")
	zl.SetOutputByString("Console")
	zl.SetStdout()
	zl.SetOmitKeys(zl.TimeKey, zl.CallerKey, zl.FunctionKey, zl.VersionKey, zl.HostnameKey, zl.StacktraceKey, zl.PIDKey)

	zl.Init()
	zl.Debug("DEBUG_MESSAGE")
	zl.Info("INFO_MESSAGE")

}
Output:

{"severity":"DEBUG","message":"INIT_LOGGER","console":"Severity: DEBUG, Output: Console"}
{"severity":"DEBUG","message":"DEBUG_MESSAGE"}
{"severity":"INFO","message":"INFO_MESSAGE"}

func SetOmitKeys ¶

func SetOmitKeys(key ...Key)

SetOmitKeys set fields to omit from default fields that used in each log.

Example ¶
package main

import (
	"github.com/nkmr-jp/zl"
	"log"
	"os"
)

func setupForExampleTest() {
	if err := os.RemoveAll("./log"); err != nil {
		log.Fatal(err)
	}
	zl.ResetGlobalLoggerSettings()
	zl.SetIsTest()
}

func main() {
	setupForExampleTest()

	zl.SetOutputByString("Console")
	zl.SetStdout()
	zl.SetOmitKeys(
		zl.MessageKey, zl.LevelKey, zl.LoggerKey, zl.TimeKey,
		zl.CallerKey, zl.VersionKey, zl.HostnameKey, zl.StacktraceKey, zl.PIDKey,
	)
	zl.Init()
	zl.Info("INFO_MESSAGE")

}
Output:

{"function":"github.com/nkmr-jp/zl_test.ExampleSetOmitKeys"}

func SetOutput ¶

func SetOutput(option Output)

SetOutput is set Output type. option can use (PrettyOutput, ConsoleAndFileOutput, ConsoleOutput, FileOutput).

func SetOutputByString ¶

func SetOutputByString(outputTypeStr string)

SetOutputByString is set Output type by string. outputTypeStr can use (Pretty, ConsoleAndFile, Console, File).

func SetRepositoryCallerEncoder ¶

func SetRepositoryCallerEncoder(urlFormat, revisionOrTag, srcRootDir string)

SetRepositoryCallerEncoder is set CallerEncoder. It set caller's source code's URL of the Repository that called. It is used in the log output CallerKey field.

func SetRotateCompress ¶

func SetRotateCompress(val bool)

SetRotateCompress determines if the rotated log files should be compressed using gzip. See: https://github.com/natefinch/lumberjack#type-logger

func SetRotateFileName ¶

func SetRotateFileName(val string)

SetRotateFileName set the file to write logs to. See: https://github.com/natefinch/lumberjack#type-logger

func SetRotateLocalTime ¶

func SetRotateLocalTime(val bool)

SetRotateLocalTime determines if the time used for formatting the timestamps in backup files is the computer's local time. See: https://github.com/natefinch/lumberjack#type-logger

func SetRotateMaxAge ¶

func SetRotateMaxAge(val int)

SetRotateMaxAge set the maximum number of days to retain. See: https://github.com/natefinch/lumberjack#type-logger

func SetRotateMaxBackups ¶

func SetRotateMaxBackups(val int)

SetRotateMaxBackups set the maximum number of old log files to retain. See: https://github.com/natefinch/lumberjack#type-logger

func SetRotateMaxSize ¶

func SetRotateMaxSize(val int)

SetRotateMaxSize set the maximum size in megabytes of the log file before it gets rotated. See: https://github.com/natefinch/lumberjack#type-logger

func SetSeparator ¶

func SetSeparator(val string)

SetSeparator is changes the console log output separator when PrettyOutput is used.

func SetStdout ¶

func SetStdout()

SetStdout is changes the console log output from stderr to stdout.

func SetVersion ¶

func SetVersion(revisionOrTag string)

SetVersion `revisionOrTag` should be a git revision or a tag. ex. `e86b9a7` or `v1.0.0`. It set version of the application. It is used in the log output VersionKey field.

Example ¶
package main

import (
	"fmt"
	"github.com/nkmr-jp/zl"
	"go.uber.org/zap"
	"log"
	"os"
)

var (
	version    string
	srcRootDir string
)

func setupForExampleTest() {
	if err := os.RemoveAll("./log"); err != nil {
		log.Fatal(err)
	}
	zl.ResetGlobalLoggerSettings()
	zl.SetIsTest()
}

func main() {
	setupForExampleTest()

	urlFormat := "https://github.com/nkmr-jp/zl/blob/%s"

	// Actually, it is recommended to pass the value from the command line of go.
	// ex. `go run -ldflags "-X main.version=v1.0.0 -X main.srcRootDir=$PWD" main.go`.
	version = "v1.0.0"
	srcRootDir, _ = os.Getwd()

	// Set Options
	zl.SetLevel(zl.DebugLevel)
	zl.SetVersion(version)
	fileName := fmt.Sprintf("./log/example-set-version_%s.jsonl", zl.GetVersion())
	zl.SetRotateFileName(fileName)
	zl.SetRepositoryCallerEncoder(urlFormat, version, srcRootDir)
	zl.SetOmitKeys(zl.TimeKey, zl.FunctionKey, zl.HostnameKey, zl.PIDKey)
	zl.SetOutput(zl.ConsoleAndFileOutput)

	// Initialize
	zl.Init()
	defer zl.Sync() // flush log buffer

	// Write logs
	zl.Info("INFO_MESSAGE", zap.String("detail", "detail info xxxxxxxxxxxxxxxxx"))
	zl.Warn("WARN_MESSAGE", zap.String("detail", "detail info xxxxxxxxxxxxxxxxx"))

	bytes, _ := os.ReadFile(fileName)
	fmt.Println(string(bytes))

}
Output:

{"severity":"DEBUG","caller":"zl/zl.go:86","message":"INIT_LOGGER","version":"v1.0.0","console":"Severity: DEBUG, Output: ConsoleAndFile, File: ./log/example-set-version_v1.0.0.jsonl"}
{"severity":"INFO","caller":"https://github.com/nkmr-jp/zl/blob/v1.0.0/example_test.go#L135","message":"INFO_MESSAGE","version":"v1.0.0","detail":"detail info xxxxxxxxxxxxxxxxx"}
{"severity":"WARN","caller":"https://github.com/nkmr-jp/zl/blob/v1.0.0/example_test.go#L136","message":"WARN_MESSAGE","version":"v1.0.0","detail":"detail info xxxxxxxxxxxxxxxxx"}

func Sync ¶

func Sync()

Sync is wrapper of Zap's Sync.

Flushes any buffered log entries.(See: https://pkg.go.dev/go.uber.org/zap#Logger.Sync) Applications should take care to call Sync before exiting.

Also displays an error report with a formatted stack trace if the outputType is PrettyOutput. This is useful for finding the source of errors during development.

An error will occur if zap's Sync is executed when the output destination is console. (See: https://github.com/uber-go/zap/issues/880 ) Therefore, Sync is executed only when console is not included in the zap output destination.

func SyncWhenStop ¶

func SyncWhenStop()

SyncWhenStop flush log buffer. when interrupt or terminated.

Example ¶
package main

import (
	"fmt"
	"github.com/nkmr-jp/zl"
	"log"
	"os"
	"syscall"
	"time"
)

func setupForExampleTest() {
	if err := os.RemoveAll("./log"); err != nil {
		log.Fatal(err)
	}
	zl.ResetGlobalLoggerSettings()
	zl.SetIsTest()
}

func main() {
	// syscall.SIGINT
	setupForExampleTest()
	zl.SetLevel(zl.DebugLevel)
	zl.SetRotateFileName("./log/example-SyncWhenStop.jsonl")
	zl.Init()
	zl.SyncWhenStop()

	go func() {
		time.Sleep(time.Millisecond * 50)
		syscall.Kill(os.Getpid(), syscall.SIGINT)
	}()
	time.Sleep(time.Millisecond * 100)

	// syscall.SIGTERM
	fmt.Println()
	setupForExampleTest()
	zl.SetLevel(zl.DebugLevel)
	zl.SetRotateFileName("./log/example-SyncWhenStop.jsonl")
	zl.Init()
	zl.SyncWhenStop()

	go func() {
		time.Sleep(time.Millisecond * 50)
		syscall.Kill(os.Getpid(), syscall.SIGTERM)
	}()
	time.Sleep(time.Millisecond * 100)

}
Output:

os.Exit(130) called.
os.Exit(143) called.

func Warn ¶

func Warn(message string, fields ...zap.Field)

Warn is wrapper of Zap's Warn.

func WarnErr ¶

func WarnErr(message string, err error, fields ...zap.Field)

WarnErr is Outputs WARN log with error field.

Types ¶

type ErrorGroup ¶ added in v1.1.0

type ErrorGroup struct {
	ErrorLogs []*ErrorLog
	Key       string
}

ErrorGroup is a group of ErrorLog. It is used in prettyLogger's error report.

type ErrorLog ¶ added in v1.1.0

type ErrorLog struct {
	Severity   zapcore.Level `json:"severity"`
	Timestamp  string        `json:"timestamp"`
	Caller     string        `json:"caller"`
	Message    string        `json:"message"`
	Error      string        `json:"error"`
	Stacktrace string        `json:"stacktrace"`
	Pid        int           `json:"pid"`
	Line       int
}

ErrorLog is a log that contains error information. It is used in prettyLogger's error report.

type Key ¶

type Key string

Key defines a commonly used field name for each log entry. Each field defined in Key is output to all logs by default. Unnecessary fields can also be excluded using SetOmitKeys.

Field names such as LevelKey and TimeKey are defined with reference to Google Cloud Logging. See: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry

const (

	// MessageKey is set to zapcore.EncoderConfig.MessageKey
	MessageKey Key = "message"
	// LevelKey is set to zapcore.EncoderConfig.LevelKey
	LevelKey Key = "severity"
	// TimeKey is set to zapcore.EncoderConfig.TimeKey
	TimeKey Key = "timestamp"
	// LoggerKey is set to zapcore.EncoderConfig.NameKey
	LoggerKey Key = "logger"
	// CallerKey is set to zapcore.EncoderConfig.CallerKey
	CallerKey Key = "caller"
	// FunctionKey is set to zapcore.EncoderConfig.FunctionKey
	FunctionKey Key = "function"
	// StacktraceKey is set to zapcore.EncoderConfig.StacktraceKey
	StacktraceKey Key = "stacktrace"

	// VersionKey is the name of the field that outputs the version of the application.
	VersionKey Key = "version"
	// HostnameKey is the name of the field that outputs the hostname of the machine.
	HostnameKey Key = "hostname"
	// PIDKey is the name of the field that outputs the process ID of the application.
	PIDKey Key = "pid"
)

type Logger ¶ added in v1.2.0

type Logger struct {
	// contains filtered or unexported fields
}

Logger is a wrapper of Zap's Logger.

func New ¶

func New(fields ...zap.Field) *Logger

New can add additional default fields. e.g. Use this when you want to add a common value in the scope of a context, such as an API request.

Example ¶
package main

import (
	"fmt"
	"github.com/nkmr-jp/zl"
	"go.uber.org/zap"
	"log"
	"os"
)

func setupForExampleTest() {
	if err := os.RemoveAll("./log"); err != nil {
		log.Fatal(err)
	}
	zl.ResetGlobalLoggerSettings()
	zl.SetIsTest()
}

func main() {
	setupForExampleTest()

	// Set options
	traceIDField := "trace"
	fileName := "./log/example-new.jsonl"
	zl.SetConsoleFields(traceIDField)
	zl.SetLevel(zl.DebugLevel)
	zl.SetOmitKeys(zl.TimeKey, zl.CallerKey, zl.FunctionKey, zl.VersionKey, zl.HostnameKey, zl.StacktraceKey, zl.PIDKey)
	zl.SetOutput(zl.PrettyOutput)
	zl.SetRotateFileName(fileName)
	traceID := "c7mg6hnr2g4l6vvuao50" // xid.New().String()

	// Initialize
	zl.Init()
	defer zl.Sync() // flush log buffer

	// New
	// e.g. Use this when you want to add a common value in the scope of a context, such as an API request.
	log := zl.New(
		zap.Int("user_id", 1),
		zap.String(traceIDField, traceID),
	)
	emptyName := log.Named("")
	named1 := log.Named("named1")
	named2 := log.Named("named2")
	named3 := named1.Named("named3") // named1.named3

	// Write logs
	err := fmt.Errorf("error")
	zl.Info("GLOBAL_INFO")
	log.Info("CONTEXT_SCOPE_INFO", zl.Consolef("some message to console: %s", "test"))
	emptyName.Err("CONTEXT_SCOPE_ERROR", fmt.Errorf("context scope error message"))
	named1.Info("CONTEXT_SCOPE_INFO2", zl.Consolef("some message to console: %s", "test"))
	named2.Debug("TEST")
	named3.Warn("TEST")
	log.Error("TEST")
	named1.Err("TEST", err)
	named2.ErrorErr("TEST", err)
	named3.ErrRet("TEST", err) // write error to log and return same error.
	log.InfoErr("TEST", err)
	named1.DebugErr("TEST", err)
	named2.WarnErr("TEST", err)
	named3.Fatal("TEST")
	log.FatalErr("TEST", err)

	fmt.Println("\nlog file output:")
	bytes, _ := os.ReadFile(fileName)
	fmt.Println(string(bytes))

	// Output to stderr with colored:
	// zl.go:82: DEBUG INIT_LOGGER Severity: DEBUG, Output: Pretty, File: ./log/example-new.jsonl
	// example_test.go:176: INFO GLOBAL_INFO
	// example_test.go:177: INFO CONTEXT_SCOPE_INFO some message to console: test c7mg6hnr2g4l6vvuao50
	// example_test.go:178: ERROR CONTEXT_SCOPE_ERROR context scope error message c7mg6hnr2g4l6vvuao50
	// named1 | example_test.go:179: INFO CONTEXT_SCOPE_INFO2 some message to console: test c7mg6hnr2g4l6vvuao50
	// named2 | example_test.go:180: DEBUG TEST c7mg6hnr2g4l6vvuao50
	// named1.named3 | example_test.go:181: WARN TEST c7mg6hnr2g4l6vvuao50
	// example_test.go:182: ERROR TEST c7mg6hnr2g4l6vvuao50
	// named1 | example_test.go:183: ERROR TEST error c7mg6hnr2g4l6vvuao50
	// named2 | example_test.go:184: ERROR TEST error c7mg6hnr2g4l6vvuao50
	// named1.named3 | example_test.go:185: ERROR TEST error c7mg6hnr2g4l6vvuao50
	// example_test.go:186: INFO TEST error c7mg6hnr2g4l6vvuao50
	// named1 | example_test.go:187: DEBUG TEST error c7mg6hnr2g4l6vvuao50
	// named2 | example_test.go:188: WARN TEST error c7mg6hnr2g4l6vvuao50
	// named1.named3 | example_test.go:189: FATAL TEST c7mg6hnr2g4l6vvuao50
	// example_test.go:190: FATAL TEST error c7mg6hnr2g4l6vvuao50

}
Output:

os.Exit(1) called.
os.Exit(1) called.

log file output:
{"severity":"DEBUG","message":"INIT_LOGGER","console":"Severity: DEBUG, Output: Pretty, File: ./log/example-new.jsonl"}
{"severity":"INFO","message":"GLOBAL_INFO"}
{"severity":"INFO","message":"CONTEXT_SCOPE_INFO","console":"some message to console: test","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"ERROR","message":"CONTEXT_SCOPE_ERROR","error":"context scope error message","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"INFO","logger":"named1","message":"CONTEXT_SCOPE_INFO2","console":"some message to console: test","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"DEBUG","logger":"named2","message":"TEST","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"WARN","logger":"named1.named3","message":"TEST","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"ERROR","message":"TEST","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"ERROR","logger":"named1","message":"TEST","error":"error","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"ERROR","logger":"named2","message":"TEST","error":"error","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"ERROR","logger":"named1.named3","message":"TEST","error":"error","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"INFO","message":"TEST","error":"error","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"DEBUG","logger":"named1","message":"TEST","error":"error","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"WARN","logger":"named2","message":"TEST","error":"error","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"FATAL","logger":"named1.named3","message":"TEST","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}
{"severity":"FATAL","message":"TEST","error":"error","user_id":1,"trace":"c7mg6hnr2g4l6vvuao50"}

func (*Logger) Debug ¶ added in v1.2.0

func (l *Logger) Debug(message string, fields ...zap.Field)

Debug is wrapper of Zap's Debug.

func (*Logger) DebugErr ¶ added in v1.2.0

func (l *Logger) DebugErr(message string, err error, fields ...zap.Field)

DebugErr is Outputs a DEBUG log with error field.

func (*Logger) Err ¶ added in v1.2.0

func (l *Logger) Err(message string, err error, fields ...zap.Field)

Err is alias of ErrorErr.

func (*Logger) ErrRet ¶ added in v1.2.0

func (l *Logger) ErrRet(message string, err error, fields ...zap.Field) error

ErrRet write error log and return error. A typical usage would be something like.

if err != nil {
  return zl.ErrRet("SOME_ERROR", fmt.Error("some message err: %w",err))
}

func (*Logger) Error ¶ added in v1.2.0

func (l *Logger) Error(message string, fields ...zap.Field)

Error is wrapper of Zap's Error.

func (*Logger) ErrorErr ¶ added in v1.2.0

func (l *Logger) ErrorErr(message string, err error, fields ...zap.Field)

ErrorErr is Outputs ERROR log with error field.

func (*Logger) Fatal ¶ added in v1.2.0

func (l *Logger) Fatal(message string, fields ...zap.Field)

Fatal is wrapper of Zap's Fatal.

func (*Logger) FatalErr ¶ added in v1.2.0

func (l *Logger) FatalErr(message string, err error, fields ...zap.Field)

FatalErr is Outputs ERROR log with error field.

func (*Logger) Info ¶ added in v1.2.0

func (l *Logger) Info(message string, fields ...zap.Field)

Info is wrapper of Zap's Info.

func (*Logger) InfoErr ¶ added in v1.2.0

func (l *Logger) InfoErr(message string, err error, fields ...zap.Field)

InfoErr is Outputs INFO log with error field.

func (*Logger) Named ¶ added in v1.2.0

func (l *Logger) Named(loggerName string) *Logger

Named is wrapper of Zap's Named. Returns a new Logger without overwriting the existing logger.

Named adds a new path segment to the logger's name. Segments are joined by periods. By default, Loggers are unnamed. e.g. logger.Named("foo").Named("bar") returns a logger named "foo.bar".

func (*Logger) Warn ¶ added in v1.2.0

func (l *Logger) Warn(message string, fields ...zap.Field)

Warn is wrapper of Zap's Warn.

func (*Logger) WarnErr ¶ added in v1.2.0

func (l *Logger) WarnErr(message string, err error, fields ...zap.Field)

WarnErr is Outputs WARN log with error field.

type Output ¶

type Output int

Output is log output type.

const (
	// PrettyOutput writes the colored simple log to console,
	// and writes json structured detail log to file.
	// It is Default setting.
	// Recommended for Develop Environment.
	PrettyOutput Output = iota

	// ConsoleAndFileOutput writes json structured log to console and file.
	// Recommended for Develop Environment.
	ConsoleAndFileOutput

	// ConsoleOutput writes json structured log to console.
	// Recommended for Develop and Production Environment.
	ConsoleOutput

	// FileOutput writes json structured log to file.
	// Recommended for Develop and Production Environment.
	FileOutput
)

func (Output) String ¶

func (o Output) String() string

String is return Output type string.

Directories ¶

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL