|  | 
|  | 1 | +/* | 
|  | 2 | +Copyright 2020 The Kubernetes Authors. | 
|  | 3 | +
 | 
|  | 4 | +Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | +you may not use this file except in compliance with the License. | 
|  | 6 | +You may obtain a copy of the License at | 
|  | 7 | +
 | 
|  | 8 | +    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | +
 | 
|  | 10 | +Unless required by applicable law or agreed to in writing, software | 
|  | 11 | +distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | +See the License for the specific language governing permissions and | 
|  | 14 | +limitations under the License. | 
|  | 15 | +*/ | 
|  | 16 | + | 
|  | 17 | +// Package zap contains helpers for setting up a new logr.Logger instance | 
|  | 18 | +// using the Zap logging framework. | 
|  | 19 | +package zap | 
|  | 20 | + | 
|  | 21 | +import ( | 
|  | 22 | +	"fmt" | 
|  | 23 | +	"strconv" | 
|  | 24 | +	"strings" | 
|  | 25 | + | 
|  | 26 | +	"github.com/spf13/pflag" | 
|  | 27 | +	"go.uber.org/zap" | 
|  | 28 | +	"go.uber.org/zap/zapcore" | 
|  | 29 | +) | 
|  | 30 | + | 
|  | 31 | +var levelStrings = map[string]zapcore.Level{ | 
|  | 32 | +	"debug":  zap.DebugLevel, | 
|  | 33 | +	"-1":     zap.DebugLevel, | 
|  | 34 | +	"info":   zap.InfoLevel, | 
|  | 35 | +	"0":      zap.InfoLevel, | 
|  | 36 | +	"error":  zap.ErrorLevel, | 
|  | 37 | +	"2":      zap.ErrorLevel, | 
|  | 38 | +	"dpanic": zap.DPanicLevel, | 
|  | 39 | +	"panic":  zap.PanicLevel, | 
|  | 40 | +	"warn":   zap.WarnLevel, | 
|  | 41 | +	"fatal":  zap.FatalLevel, | 
|  | 42 | +} | 
|  | 43 | + | 
|  | 44 | +type encoderFlag struct { | 
|  | 45 | +	setFunc func(zapcore.Encoder) | 
|  | 46 | +	value   string | 
|  | 47 | +} | 
|  | 48 | + | 
|  | 49 | +var _ pflag.Value = &encoderFlag{} | 
|  | 50 | + | 
|  | 51 | +func (ev *encoderFlag) String() string { | 
|  | 52 | +	return ev.value | 
|  | 53 | +} | 
|  | 54 | + | 
|  | 55 | +func (ev *encoderFlag) Type() string { | 
|  | 56 | +	return "encoder" | 
|  | 57 | +} | 
|  | 58 | + | 
|  | 59 | +func (ev *encoderFlag) Set(flagValue string) error { | 
|  | 60 | +	val := strings.ToLower(flagValue) | 
|  | 61 | +	switch val { | 
|  | 62 | +	case "json": | 
|  | 63 | +		ev.setFunc(newJSONEncoder()) | 
|  | 64 | +	case "console": | 
|  | 65 | +		ev.setFunc(newConsoleEncoder()) | 
|  | 66 | +	default: | 
|  | 67 | +		return fmt.Errorf("invalid encoder value \"%s\"", flagValue) | 
|  | 68 | +	} | 
|  | 69 | +	ev.value = flagValue | 
|  | 70 | +	return nil | 
|  | 71 | +} | 
|  | 72 | + | 
|  | 73 | +func newJSONEncoder() zapcore.Encoder { | 
|  | 74 | +	encoderConfig := zap.NewProductionEncoderConfig() | 
|  | 75 | +	return zapcore.NewJSONEncoder(encoderConfig) | 
|  | 76 | +} | 
|  | 77 | + | 
|  | 78 | +func newConsoleEncoder() zapcore.Encoder { | 
|  | 79 | +	encoderConfig := zap.NewDevelopmentEncoderConfig() | 
|  | 80 | +	return zapcore.NewConsoleEncoder(encoderConfig) | 
|  | 81 | +} | 
|  | 82 | + | 
|  | 83 | +type levelFlag struct { | 
|  | 84 | +	setFunc func(zap.AtomicLevel) | 
|  | 85 | +	value   string | 
|  | 86 | +} | 
|  | 87 | + | 
|  | 88 | +var _ pflag.Value = &levelFlag{} | 
|  | 89 | + | 
|  | 90 | +func (ev *levelFlag) Set(flagValue string) error { | 
|  | 91 | +	level, validLevel := levelStrings[strings.ToLower(flagValue)] | 
|  | 92 | +	if !validLevel { | 
|  | 93 | +		logLevel, err := strconv.Atoi(flagValue) | 
|  | 94 | +		if err != nil { | 
|  | 95 | +			return fmt.Errorf("invalid log level \"%s\"", flagValue) | 
|  | 96 | +		} | 
|  | 97 | +		if logLevel > 0 { | 
|  | 98 | +			intLevel := -1 * logLevel | 
|  | 99 | +			ev.setFunc(zap.NewAtomicLevelAt(zapcore.Level(int8(intLevel)))) | 
|  | 100 | +		} else { | 
|  | 101 | +			return fmt.Errorf("invalid log level \"%s\"", flagValue) | 
|  | 102 | +		} | 
|  | 103 | +	} | 
|  | 104 | +	ev.setFunc(zap.NewAtomicLevelAt(level)) | 
|  | 105 | +	ev.value = flagValue | 
|  | 106 | +	return nil | 
|  | 107 | +} | 
|  | 108 | + | 
|  | 109 | +func (ev *levelFlag) String() string { | 
|  | 110 | +	return ev.value | 
|  | 111 | +} | 
|  | 112 | + | 
|  | 113 | +func (ev *levelFlag) Type() string { | 
|  | 114 | +	return "level" | 
|  | 115 | +} | 
|  | 116 | + | 
|  | 117 | +type stackTraceFlag struct { | 
|  | 118 | +	setFunc func(zap.AtomicLevel) | 
|  | 119 | +	value   string | 
|  | 120 | +} | 
|  | 121 | + | 
|  | 122 | +var _ pflag.Value = &stackTraceFlag{} | 
|  | 123 | + | 
|  | 124 | +func (ev *stackTraceFlag) Set(flagValue string) error { | 
|  | 125 | +	level, validLevel := levelStrings[strings.ToLower(flagValue)] | 
|  | 126 | +	if !validLevel { | 
|  | 127 | +		return fmt.Errorf("invalid stacktrace level \"%s\"", flagValue) | 
|  | 128 | +	} | 
|  | 129 | +	ev.setFunc(zap.NewAtomicLevelAt(level)) | 
|  | 130 | +	ev.value = flagValue | 
|  | 131 | +	return nil | 
|  | 132 | +} | 
|  | 133 | + | 
|  | 134 | +func (ev *stackTraceFlag) String() string { | 
|  | 135 | +	return ev.value | 
|  | 136 | +} | 
|  | 137 | + | 
|  | 138 | +func (ev *stackTraceFlag) Type() string { | 
|  | 139 | +	return "level" | 
|  | 140 | +} | 
0 commit comments