kuma

Форк
0
/
logger.go 
131 строка · 3.3 Кб
1
package log
2

3
import (
4
	"context"
5
	"io"
6
	"os"
7

8
	"github.com/go-logr/logr"
9
	"github.com/go-logr/zapr"
10
	"github.com/pkg/errors"
11
	"go.opentelemetry.io/otel/trace"
12
	"go.uber.org/zap"
13
	"go.uber.org/zap/zapcore"
14
	"gopkg.in/natefinch/lumberjack.v2"
15
	kube_log_zap "sigs.k8s.io/controller-runtime/pkg/log/zap"
16

17
	"github.com/kumahq/kuma/pkg/multitenant"
18
	logger_extensions "github.com/kumahq/kuma/pkg/plugins/extensions/logger"
19
)
20

21
type LogLevel int
22

23
const (
24
	OffLevel LogLevel = iota
25
	InfoLevel
26
	DebugLevel
27
)
28

29
func (l LogLevel) String() string {
30
	switch l {
31
	case OffLevel:
32
		return "off"
33
	case InfoLevel:
34
		return "info"
35
	case DebugLevel:
36
		return "debug"
37
	default:
38
		return "unknown"
39
	}
40
}
41

42
func ParseLogLevel(text string) (LogLevel, error) {
43
	switch text {
44
	case "off":
45
		return OffLevel, nil
46
	case "info":
47
		return InfoLevel, nil
48
	case "debug":
49
		return DebugLevel, nil
50
	default:
51
		return OffLevel, errors.Errorf("unknown log level %q", text)
52
	}
53
}
54

55
func NewLogger(level LogLevel) logr.Logger {
56
	return NewLoggerTo(os.Stderr, level)
57
}
58

59
func NewLoggerWithRotation(level LogLevel, outputPath string, maxSize int, maxBackups int, maxAge int) logr.Logger {
60
	return NewLoggerTo(&lumberjack.Logger{
61
		Filename:   outputPath,
62
		MaxSize:    maxSize,
63
		MaxBackups: maxBackups,
64
		MaxAge:     maxAge,
65
	}, level)
66
}
67

68
func NewLoggerTo(destWriter io.Writer, level LogLevel) logr.Logger {
69
	return zapr.NewLogger(newZapLoggerTo(destWriter, level))
70
}
71

72
func newZapLoggerTo(destWriter io.Writer, level LogLevel, opts ...zap.Option) *zap.Logger {
73
	var lvl zap.AtomicLevel
74
	switch level {
75
	case OffLevel:
76
		return zap.NewNop()
77
	case DebugLevel:
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))
84
	default:
85
		lvl = zap.NewAtomicLevelAt(zap.InfoLevel)
86
	}
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)).
92
		WithOptions(opts...)
93
}
94

95
const tenantLoggerKey = "tenantID"
96

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
101
// values.
102
func AddFieldsFromCtx(
103
	logger logr.Logger,
104
	ctx context.Context,
105
	extensions context.Context,
106
) logr.Logger {
107
	if tenantId, ok := multitenant.TenantFromCtx(ctx); ok {
108
		logger = logger.WithValues(tenantLoggerKey, tenantId)
109
	}
110

111
	return addSpanValuesToLogger(logger, ctx, extensions)
112
}
113

114
func addSpanValuesToLogger(
115
	logger logr.Logger,
116
	ctx context.Context,
117
	extensions context.Context,
118
) logr.Logger {
119
	if span := trace.SpanFromContext(ctx); span.IsRecording() {
120
		if fn, ok := logger_extensions.FromSpanLogValuesProcessorContext(extensions); ok {
121
			return logger.WithValues(fn(span)...)
122
		}
123

124
		return logger.WithValues(
125
			"trace_id", span.SpanContext().TraceID(),
126
			"span_id", span.SpanContext().SpanID(),
127
		)
128
	}
129

130
	return logger
131
}
132

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.