Skip to content

Instantly share code, notes, and snippets.

@amsokol
Created September 16, 2018 05:43
Show Gist options
  • Save amsokol/70ed47cd4c32bc658f8c726e5f51f94e to your computer and use it in GitHub Desktop.
Save amsokol/70ed47cd4c32bc658f8c726e5f51f94e to your computer and use it in GitHub Desktop.
package logger
import (
"os"
"sync"
"time"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var (
// Log is global logger
Log *zap.Logger
// timeFormat is custom Time format
customTimeFormat string
// onceInit guarantee initialize logger only once
onceInit sync.Once
)
// customTimeEncoder encode Time to our custom format
// This example how we can customize zap default functionality
func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format(customTimeFormat))
}
// Init initializes log by input parameters
// lvl - global log level: Debug(-1), Info(0), Warn(1), Error(2), DPanic(3), Panic(4), Fatal(5)
// timeFormat - custom time format for logger of empty string to use default
func Init(lvl int, timeFormat string) error {
var err error
onceInit.Do(func() {
// First, define our level-handling logic.
globalLevel := zapcore.Level(lvl)
// High-priority output should also go to standard error, and low-priority
// output should also go to standard out.
// It is usefull for Kubernetes deployment.
// Kubernetes interprets os.Stdout log items as INFO and os.Stderr log items
// as ERROR by default.
highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= zapcore.ErrorLevel
})
lowPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= globalLevel && lvl < zapcore.ErrorLevel
})
consoleInfos := zapcore.Lock(os.Stdout)
consoleErrors := zapcore.Lock(os.Stderr)
// Configure console output.
var useCustomTimeFormat bool
ecfg := zap.NewProductionEncoderConfig()
if len(timeFormat) > 0 {
customTimeFormat = timeFormat
ecfg.EncodeTime = customTimeEncoder
useCustomTimeFormat = true
}
consoleEncoder := zapcore.NewJSONEncoder(ecfg)
// Join the outputs, encoders, and level-handling functions into
// zapcore.
core := zapcore.NewTee(
zapcore.NewCore(consoleEncoder, consoleErrors, highPriority),
zapcore.NewCore(consoleEncoder, consoleInfos, lowPriority),
)
// From a zapcore.Core, it's easy to construct a Logger.
Log = zap.New(core)
zap.RedirectStdLog(Log)
if !useCustomTimeFormat {
Log.Warn("time format for logger is not provided - use zap default")
}
})
return err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment