151 lines
4.7 KiB
Go
151 lines
4.7 KiB
Go
/*
|
|
* Copyright (c) 2019 VMware, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
* associated documentation files (the "Software"), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is furnished to do
|
|
* so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
* portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
// Note: The implementation comes from https://www.mountedthoughts.com/golang-logger-interface/
|
|
// https://github.com/amitrai48/logger
|
|
|
|
package zap
|
|
|
|
import (
|
|
"os"
|
|
|
|
"github.com/vmware/vmware-go-kcl-v2/logger"
|
|
uzap "go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
lumberjack "gopkg.in/natefinch/lumberjack.v2"
|
|
)
|
|
|
|
type ZapLogger struct {
|
|
sugaredLogger *uzap.SugaredLogger
|
|
}
|
|
|
|
// NewZapLogger adapts existing sugared zap logger to Logger interface.
|
|
// The call is responsible for configuring sugard zap logger appropriately.
|
|
//
|
|
// Note: Sugar wraps the Logger to provide a more ergonomic, but slightly slower,
|
|
// API. Sugaring a Logger is quite inexpensive, so it's reasonable for a
|
|
// single application to use both Loggers and SugaredLoggers, converting
|
|
// between them on the boundaries of performance-sensitive code.
|
|
//
|
|
// Base zap logger can be convert to SugaredLogger by calling to add a wrapper:
|
|
// sugaredLogger := log.Sugar()
|
|
func NewZapLogger(logger *uzap.SugaredLogger) logger.Logger {
|
|
return &ZapLogger{
|
|
sugaredLogger: logger,
|
|
}
|
|
}
|
|
|
|
// NewZapLoggerWithConfig creates and configs Logger instance backed by
|
|
// zap Sugared logger.
|
|
func NewZapLoggerWithConfig(config logger.Configuration) logger.Logger {
|
|
cores := []zapcore.Core{}
|
|
|
|
if config.EnableConsole {
|
|
level := getZapLevel(config.ConsoleLevel)
|
|
writer := zapcore.Lock(os.Stdout)
|
|
core := zapcore.NewCore(getEncoder(config.ConsoleJSONFormat), writer, level)
|
|
cores = append(cores, core)
|
|
}
|
|
|
|
if config.EnableFile {
|
|
level := getZapLevel(config.FileLevel)
|
|
writer := zapcore.AddSync(&lumberjack.Logger{
|
|
Filename: config.Filename,
|
|
MaxSize: config.MaxSizeMB,
|
|
Compress: true,
|
|
MaxAge: config.MaxAgeDays,
|
|
MaxBackups: config.MaxBackups,
|
|
LocalTime: config.LocalTime,
|
|
})
|
|
core := zapcore.NewCore(getEncoder(config.FileJSONFormat), writer, level)
|
|
cores = append(cores, core)
|
|
}
|
|
|
|
combinedCore := zapcore.NewTee(cores...)
|
|
|
|
// AddCallerSkip skips 2 number of callers, this is important else the file that gets
|
|
// logged will always be the wrapped file. In our case zap.go
|
|
logger := uzap.New(combinedCore,
|
|
uzap.AddCallerSkip(2),
|
|
uzap.AddCaller(),
|
|
).Sugar()
|
|
|
|
return &ZapLogger{
|
|
sugaredLogger: logger,
|
|
}
|
|
}
|
|
|
|
func (l *ZapLogger) Debugf(format string, args ...interface{}) {
|
|
l.sugaredLogger.Debugf(format, args...)
|
|
}
|
|
|
|
func (l *ZapLogger) Infof(format string, args ...interface{}) {
|
|
l.sugaredLogger.Infof(format, args...)
|
|
}
|
|
|
|
func (l *ZapLogger) Warnf(format string, args ...interface{}) {
|
|
l.sugaredLogger.Warnf(format, args...)
|
|
}
|
|
|
|
func (l *ZapLogger) Errorf(format string, args ...interface{}) {
|
|
l.sugaredLogger.Errorf(format, args...)
|
|
}
|
|
|
|
func (l *ZapLogger) Fatalf(format string, args ...interface{}) {
|
|
l.sugaredLogger.Fatalf(format, args...)
|
|
}
|
|
|
|
func (l *ZapLogger) Panicf(format string, args ...interface{}) {
|
|
l.sugaredLogger.Fatalf(format, args...)
|
|
}
|
|
|
|
func (l *ZapLogger) WithFields(fields logger.Fields) logger.Logger {
|
|
var f = make([]interface{}, 0)
|
|
for k, v := range fields {
|
|
f = append(f, k)
|
|
f = append(f, v)
|
|
}
|
|
newLogger := l.sugaredLogger.With(f...)
|
|
return &ZapLogger{newLogger}
|
|
}
|
|
|
|
func getEncoder(isJSON bool) zapcore.Encoder {
|
|
encoderConfig := uzap.NewProductionEncoderConfig()
|
|
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
|
if isJSON {
|
|
return zapcore.NewJSONEncoder(encoderConfig)
|
|
}
|
|
return zapcore.NewConsoleEncoder(encoderConfig)
|
|
}
|
|
|
|
func getZapLevel(level string) zapcore.Level {
|
|
switch level {
|
|
case logger.Info:
|
|
return zapcore.InfoLevel
|
|
case logger.Warn:
|
|
return zapcore.WarnLevel
|
|
case logger.Debug:
|
|
return zapcore.DebugLevel
|
|
case logger.Error:
|
|
return zapcore.ErrorLevel
|
|
case logger.Fatal:
|
|
return zapcore.FatalLevel
|
|
default:
|
|
return zapcore.InfoLevel
|
|
}
|
|
}
|