8
"github.com/go-logr/logr"
9
"github.com/go-logr/zapr"
10
"github.com/pkg/errors"
11
"go.opentelemetry.io/otel/trace"
13
"go.uber.org/zap/zapcore"
14
"gopkg.in/natefinch/lumberjack.v2"
15
kube_log_zap "sigs.k8s.io/controller-runtime/pkg/log/zap"
17
"github.com/kumahq/kuma/pkg/multitenant"
18
logger_extensions "github.com/kumahq/kuma/pkg/plugins/extensions/logger"
24
OffLevel LogLevel = iota
29
func (l LogLevel) String() string {
42
func ParseLogLevel(text string) (LogLevel, error) {
49
return DebugLevel, nil
51
return OffLevel, errors.Errorf("unknown log level %q", text)
55
func NewLogger(level LogLevel) logr.Logger {
56
return NewLoggerTo(os.Stderr, level)
59
func NewLoggerWithRotation(level LogLevel, outputPath string, maxSize int, maxBackups int, maxAge int) logr.Logger {
60
return NewLoggerTo(&lumberjack.Logger{
63
MaxBackups: maxBackups,
68
func NewLoggerTo(destWriter io.Writer, level LogLevel) logr.Logger {
69
return zapr.NewLogger(newZapLoggerTo(destWriter, level))
72
func newZapLoggerTo(destWriter io.Writer, level LogLevel, opts ...zap.Option) *zap.Logger {
73
var lvl zap.AtomicLevel
78
// The value we pass here is the most verbose level that
79
// will end up being emitted through the `V(level int)`
80
// accessor. Passing -10 ensures that levels up to `V(10)`
81
// will work, which seems like plenty.
82
lvl = zap.NewAtomicLevelAt(-10)
83
opts = append(opts, zap.AddStacktrace(zap.ErrorLevel))
85
lvl = zap.NewAtomicLevelAt(zap.InfoLevel)
87
encCfg := zap.NewDevelopmentEncoderConfig()
88
enc := zapcore.NewConsoleEncoder(encCfg)
89
sink := zapcore.AddSync(destWriter)
90
opts = append(opts, zap.AddCallerSkip(1), zap.ErrorOutput(sink))
91
return zap.New(zapcore.NewCore(&kube_log_zap.KubeAwareEncoder{Encoder: enc, Verbose: level == DebugLevel}, sink, lvl)).
95
const tenantLoggerKey = "tenantID"
97
// AddFieldsFromCtx will check if provided context contain tracing span and
98
// if the span is currently recording. If so, it will call spanLogValuesProcessor
99
// function if it's also present in the context. If not it will add trace_id
100
// and span_id to logged values. It will also add the tenant id to the logged
102
func AddFieldsFromCtx(
105
extensions context.Context,
107
if tenantId, ok := multitenant.TenantFromCtx(ctx); ok {
108
logger = logger.WithValues(tenantLoggerKey, tenantId)
111
return addSpanValuesToLogger(logger, ctx, extensions)
114
func addSpanValuesToLogger(
117
extensions context.Context,
119
if span := trace.SpanFromContext(ctx); span.IsRecording() {
120
if fn, ok := logger_extensions.FromSpanLogValuesProcessorContext(extensions); ok {
121
return logger.WithValues(fn(span)...)
124
return logger.WithValues(
125
"trace_id", span.SpanContext().TraceID(),
126
"span_id", span.SpanContext().SpanID(),