-
Notifications
You must be signed in to change notification settings - Fork 11
/
log.go
169 lines (138 loc) · 5.34 KB
/
log.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package logger
import (
"fmt"
"github.com/go-logr/logr"
"go.uber.org/zap"
"sigs.k8s.io/controller-runtime/pkg/log"
crzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
"github.com/agoda-com/samsahai/internal"
)
// Log is the base logger used by kubebuilder. It delegates
// to another logr.Logger. You *must* call SetLogger to
// get any actual logging.
var Log = NewS2hLogger(log.NullLogger{})
var S2HLog Logger
func init() {
S2HLog = Log.WithName(internal.AppName)
}
// DelegatingLogger is a logr.Logger that delegates to another logr.Logger.
// If the underlying promise is not nil, it registers calls to sub-loggers with
// the logging factory to be populated later, and returns a new delegating
// logger. It expects to have *some* logr.Logger set at all times (generally
// a no-op logger before the promises are fulfilled).
type DelegatingLogger struct {
logger *log.DelegatingLogger
}
func GetLogger(debug bool) logr.Logger {
l := crzap.New(func(o *crzap.Options) {
o.Development = debug
lvl := zap.NewAtomicLevelAt(zap.ErrorLevel)
o.StacktraceLevel = &lvl
})
return l
}
func NewS2hLogger(initial logr.Logger) *DelegatingLogger {
return &DelegatingLogger{
logger: log.NewDelegatingLogger(initial),
}
}
// SetLogger sets a concrete logging implementation for all deferred Loggers.
func SetLogger(l logr.Logger) {
Log.Fulfill(l)
}
// Fulfill switches the logger over to use the actual logger
// provided, instead of the temporary initial one, if this method
// has not been previously called.
func (l *DelegatingLogger) Fulfill(actual logr.Logger) {
l.logger.Fulfill(actual)
}
// Logger represents the ability to log messages, both errors and not.
type Logger interface {
// All Loggers implement InfoLogger. Calling InfoLogger methods directly on
// a Logger value is equivalent to calling them on a V(0) InfoLogger. For
// example, logger.Info() produces the same result as logger.V(0).Info.
logr.InfoLogger
// Error logs an error, with the given message and key/value pairs as context.
// It functions similarly to calling Info with the "error" named value, but may
// have unique behavior, and should be preferred for logging errors (see the
// package documentations for more information).
//
// The msg field should be used to add context to any underlying error,
// while the err field should be used to attach the actual error that
// triggered this log line, if present.
Error(err error, msg string, keysAndValues ...interface{})
// Debug logs a non-error message with the given key/value pairs as context.
// It functions similarly to calling Info with verbosity level as 1.
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
Debug(msg string, keysAndValues ...interface{})
// Warn logs a non-error message with the given key/value pairs as context.
// It functions similarly to calling Info with verbosity level as -1.
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
Warn(msg string, keysAndValues ...interface{})
Warnf(format string, args ...interface{})
// WithValues adds some key-value pairs of context to a logger.
// See Info for documentation on how key/value pairs work.
WithValues(keysAndValues ...interface{}) Logger
// WithName adds a new element to the logger's name.
// Successive calls with WithName continue to append
// suffixes to the logger's name. It's strongly reccomended
// that name segments contain only letters, digits, and hyphens
// (see the package documentation for more information).
WithName(name string) Logger
}
// Enabled implements logr.InfoLogger
func (l *DelegatingLogger) Enabled() bool {
return l.logger.Enabled()
}
// Info implements logr.InfoLogger
func (l *DelegatingLogger) Info(msg string, keyAndValues ...interface{}) {
l.logger.Info(msg, keyAndValues...)
}
// Error implements logr.Logger
func (l *DelegatingLogger) Error(err error, msg string, keyAndValues ...interface{}) {
l.logger.Error(err, msg, keyAndValues...)
}
// Debug implements logr.Logger
func (l *DelegatingLogger) Debug(msg string, keysAndValues ...interface{}) {
l.logger.V(1).Info(msg, keysAndValues...)
}
// Warn implements logr.Logger
func (l *DelegatingLogger) Warn(msg string, keysAndValues ...interface{}) {
l.logger.V(-1).Info(msg, keysAndValues...)
}
// Warnf prints a message with the specified format
func (l *DelegatingLogger) Warnf(format string, args ...interface{}) {
l.logger.V(-1).Info(fmt.Sprintf(format, args...))
}
// WithName implements logr.Logger
func (l *DelegatingLogger) WithName(name string) Logger {
ln := l.logger.WithName(name)
delegatingLn, ok := ln.(*log.DelegatingLogger)
if !ok {
delegatingLn = log.NewDelegatingLogger(ln)
}
res := &DelegatingLogger{
logger: delegatingLn,
}
return res
}
// WithValues implements logr.Logger
func (l *DelegatingLogger) WithValues(tags ...interface{}) Logger {
ln := l.logger.WithValues(tags...)
delegatingLn, ok := ln.(*log.DelegatingLogger)
if !ok {
delegatingLn = log.NewDelegatingLogger(ln)
}
res := &DelegatingLogger{
logger: delegatingLn,
}
return res
}