91 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
package logging
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"strconv"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/go-logr/logr"
 | 
						|
	zaplib "go.uber.org/zap"
 | 
						|
	"go.uber.org/zap/zapcore"
 | 
						|
	"sigs.k8s.io/controller-runtime/pkg/log/zap"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	LogLevelDebug = "debug"
 | 
						|
	LogLevelInfo  = "info"
 | 
						|
	LogLevelWarn  = "warn"
 | 
						|
	LogLevelError = "error"
 | 
						|
	LogFormatText = "text"
 | 
						|
	LogFormatJSON = "json"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	LogOpts = zap.Options{
 | 
						|
		TimeEncoder: zapcore.TimeEncoderOfLayout(time.RFC3339),
 | 
						|
		Development: true,
 | 
						|
		EncoderConfigOptions: []zap.EncoderConfigOption{
 | 
						|
			func(ec *zapcore.EncoderConfig) {
 | 
						|
				ec.LevelKey = "severity"
 | 
						|
				ec.MessageKey = "message"
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
func NewLogger(logLevel string, logFormat string) (logr.Logger, error) {
 | 
						|
 | 
						|
	if !validLogFormat(logFormat) {
 | 
						|
		return logr.Logger{}, errors.New("invalid log format specified")
 | 
						|
	}
 | 
						|
 | 
						|
	o := LogOpts
 | 
						|
	o.EncoderConfigOptions = make([]zap.EncoderConfigOption, len(LogOpts.EncoderConfigOptions))
 | 
						|
	copy(o.EncoderConfigOptions, LogOpts.EncoderConfigOptions)
 | 
						|
 | 
						|
	if logFormat == "json" {
 | 
						|
		o.Development = false
 | 
						|
		o.TimeEncoder = nil
 | 
						|
	}
 | 
						|
 | 
						|
	switch logLevel {
 | 
						|
	case LogLevelDebug:
 | 
						|
		lvl := zaplib.NewAtomicLevelAt(zaplib.DebugLevel) // maps to logr's V(1)
 | 
						|
		o.Level = &lvl
 | 
						|
	case LogLevelInfo:
 | 
						|
		lvl := zaplib.NewAtomicLevelAt(zaplib.InfoLevel)
 | 
						|
		o.Level = &lvl
 | 
						|
	case LogLevelWarn:
 | 
						|
		lvl := zaplib.NewAtomicLevelAt(zaplib.WarnLevel)
 | 
						|
		o.Level = &lvl
 | 
						|
	case LogLevelError:
 | 
						|
		lvl := zaplib.NewAtomicLevelAt(zaplib.ErrorLevel)
 | 
						|
		o.Level = &lvl
 | 
						|
	default:
 | 
						|
		// We use bitsize of 8 as zapcore.Level is a type alias to int8
 | 
						|
		levelInt, err := strconv.ParseInt(logLevel, 10, 8)
 | 
						|
		if err != nil {
 | 
						|
			fmt.Fprintf(os.Stderr, "Failed to parse --log-level=%s: %v", logLevel, err)
 | 
						|
			os.Exit(1)
 | 
						|
		}
 | 
						|
		// For example, --log-level=debug a.k.a --log-level=-1 maps to zaplib.DebugLevel, which is associated to logr's V(1)
 | 
						|
		// --log-level=-2 maps the specific custom log level that is associated to logr's V(2).
 | 
						|
		level := zapcore.Level(levelInt)
 | 
						|
		atomicLevel := zaplib.NewAtomicLevelAt(level)
 | 
						|
		o.Level = &atomicLevel
 | 
						|
	}
 | 
						|
	return zap.New(zap.UseFlagOptions(&o)), nil
 | 
						|
}
 | 
						|
 | 
						|
func validLogFormat(logFormat string) bool {
 | 
						|
	validFormat := []string{"text", "json"}
 | 
						|
	for _, v := range validFormat {
 | 
						|
		if v == logFormat {
 | 
						|
			return true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 |