func (log *logging) get(source string) logger {
	if l, ok := log.loggers[source]; ok {
		return l
	}
	l := logger(len(log.loggers))
	log.loggers[source] = l
	log.sources[l] = source
	log.align(l)
	state, ok := log.dbgmap[source]
	if !ok {
		state = log.dbgmap["*"]
	}
	log.setDebug(source, state)
	return l
}
Logger

get returns the logger for source, creating one if necessary.
package log
import (
	"fmt"
	"strings"
	"sync"
	"k8s.io/klog/v2"
)
type Level int
const (
	levelUnset Level = iota
	LevelDebug
	LevelInfo
	LevelWarn
	LevelError
	LevelPanic
	LevelFatal
)
var levelTag = map[Level]string{
	levelUnset: "?: ",
	LevelDebug: "D: ",
	LevelInfo:  "I: ",
	LevelWarn:  "W: ",
	LevelError: "E: ",
	LevelFatal: "F: ",
	LevelPanic: "P: ",
}
type Logger interface {
	Debugf(format string, v ...interface{})
	Infof(format string, v ...interface{})
	Warnf(format string, v ...interface{})
	Errorf(format string, v ...interface{})
	Panicf(format string, v ...interface{})
	Fatalf(format string, v ...interface{})
	Debug(format string, args ...interface{})
	Info(format string, args ...interface{})
	Warn(format string, args ...interface{})
	Error(format string, args ...interface{})
	Panic(format string, args ...interface{})
	Fatal(format string, args ...interface{})
	DebugBlock(prefix string, format string, args ...interface{})
	InfoBlock(prefix string, format string, args ...interface{})
	WarnBlock(prefix string, format string, args ...interface{})
	ErrorBlock(prefix string, format string, args ...interface{})
	EnableDebug(bool) bool
	DebugEnabled() bool
	Source() string
}
type logger uint
type logging struct {
	sync.RWMutex
	level   Level                
	dbgmap  srcmap               
	loggers map[string]logger    
	sources map[logger]string    
	debug   map[logger]struct{}  
	maxlen  int                  
	forced  bool                 
	prefix  bool                 
	aligned map[logger]string    
}
var log = &logging{
	level:   DefaultLevel,
	loggers: make(map[string]logger),
	sources: make(map[logger]string),
	aligned: make(map[logger]string),
	debug:   make(map[logger]struct{}),
}
func Get(source string) Logger {
	log.Lock()
	defer log.Unlock()
	return log.get(source)
}
func NewLogger(source string) Logger {
	return Get(source)
}
func EnableDebug(source string) bool {
	log.Lock()
	defer log.Unlock()
	return log.setDebug(source, true)
}
func DisableDebug(source string) bool {
	log.Lock()
	defer log.Unlock()
	return log.setDebug(source, false)
}
func DebugEnabled(source string) bool {
	log.Lock()
	defer log.Unlock()
	return log.getDebug(source)
}
func SetLevel(level Level) {
	log.Lock()
	defer log.Unlock()
	log.setLevel(level)
}
func Flush() {
	log.RLock()
	defer log.RUnlock()
	klog.Flush()
}
func (l Level) String() string {
	switch l {
	case LevelDebug:
		return "debug"
	case LevelInfo:
		return "info"
	case LevelWarn:
		return "warning"
	case LevelError:
		return "error"
	case LevelPanic:
		return "panic"
	case LevelFatal:
		return "fatal"
	}
	return "unknown"
}
func (log *logging) setLevel(level Level) error {
	log.level = level
	kThreshold := ""
	switch level {
	case LevelDebug, LevelInfo:
		kThreshold = "INFO"
	case LevelWarn:
		kThreshold = "WARNING"
	case LevelError, LevelPanic, LevelFatal:
		kThreshold = "ERROR"
	}
	if err := klogctl.Set("stderrthreshold", kThreshold); err != nil {
		return loggerError("failed to set log level/threshold to %s: %v", kThreshold, err)
	}
	return nil
}
func (log *logging) setDebug(source string, enabled bool) bool {
	l := log.get(source)
	_, old := log.debug[l]
	if enabled {
		log.debug[l] = struct{}{}
	} else {
		delete(log.debug, l)
	}
	return old
}
func (log *logging) getDebug(source string) bool {
	if log.forced {
		return true
	}
	l := log.get(source)
	_, enabled := log.debug[l]
	return enabled
}
func (log *logging) setDbgMap(dbgmap srcmap) {
	log.dbgmap = dbgmap
	log.debug = make(map[logger]struct{})
	for source := range log.loggers {
		state, ok := log.dbgmap[source]
		if !ok {
			state = log.dbgmap["*"]
		}
		log.setDebug(source, state)
	}
}
func (log *logging) setPrefix(prefix bool) {
	log.prefix = prefix
}
func (log *logging) align(l logger) {
	source := log.sources[l]
	srclen := len(source)
	if srclen > log.maxlen {
		log.realign(srclen)
		return
	}
	pad := log.maxlen - srclen
	pre := (pad + 1) / 2
	suf := pad - pre
	log.aligned[l] = "[" + fmt.Sprintf("%*s", pre, "") + source + fmt.Sprintf("%*s", suf, "") + "] "
}
func (log *logging) realign(maxlen int) {
	if maxlen <= 0 {
		for _, source := range log.sources {
			if srclen := len(source); srclen > maxlen {
				maxlen = srclen
			}
		}
	}
	log.maxlen = maxlen
	log.aligned = make(map[logger]string)
	for l := range log.sources {
		log.align(l)
	}
}