11 // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
12 // file, or leave it default which is `os.Stderr`. You can also set this to
13 // something more adventorous, such as logging to Kafka.
15 // Hooks for the logger instance. These allow firing events based on logging
16 // levels and log entries. For example, to send errors to an error tracking
17 // service, log to StatsD or dump the core on fatal errors.
19 // All log entries pass through the formatter before logged to Out. The
20 // included formatters are `TextFormatter` and `JSONFormatter` for which
21 // TextFormatter is the default. In development (when a TTY is attached) it
22 // logs with colors, but to a file it wouldn't. You can easily implement your
23 // own that implements the `Formatter` interface, see the `README` or included
24 // formatters for examples.
26 // The logging level the logger should log at. This is typically (and defaults
27 // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
28 // logged. `logrus.Debug` is useful in
30 // Used to sync writing to the log. Locking is enabled by Default
32 // Reusable empty entry
36 type MutexWrap struct {
41 func (mw *MutexWrap) Lock() {
47 func (mw *MutexWrap) Unlock() {
53 func (mw *MutexWrap) Disable() {
57 // Creates a new logger. Configuration should be set by changing `Formatter`,
58 // `Out` and `Hooks` directly on the default logger instance. You can also just
59 // instantiate your own:
63 // Formatter: new(JSONFormatter),
64 // Hooks: make(LevelHooks),
65 // Level: logrus.DebugLevel,
68 // It's recommended to make this a global instance called `log`.
72 Formatter: new(TextFormatter),
73 Hooks: make(LevelHooks),
78 func (logger *Logger) newEntry() *Entry {
79 entry, ok := logger.entryPool.Get().(*Entry)
83 return NewEntry(logger)
86 func (logger *Logger) releaseEntry(entry *Entry) {
87 logger.entryPool.Put(entry)
90 // Adds a field to the log entry, note that it doesn't log until you call
91 // Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
92 // If you want multiple fields, use `WithFields`.
93 func (logger *Logger) WithField(key string, value interface{}) *Entry {
94 entry := logger.newEntry()
95 defer logger.releaseEntry(entry)
96 return entry.WithField(key, value)
99 // Adds a struct of fields to the log entry. All it does is call `WithField` for
101 func (logger *Logger) WithFields(fields Fields) *Entry {
102 entry := logger.newEntry()
103 defer logger.releaseEntry(entry)
104 return entry.WithFields(fields)
107 // Add an error as single field to the log entry. All it does is call
108 // `WithError` for the given `error`.
109 func (logger *Logger) WithError(err error) *Entry {
110 entry := logger.newEntry()
111 defer logger.releaseEntry(entry)
112 return entry.WithError(err)
115 func (logger *Logger) Debugf(format string, args ...interface{}) {
116 if logger.level() >= DebugLevel {
117 entry := logger.newEntry()
118 entry.Debugf(format, args...)
119 logger.releaseEntry(entry)
123 func (logger *Logger) Infof(format string, args ...interface{}) {
124 if logger.level() >= InfoLevel {
125 entry := logger.newEntry()
126 entry.Infof(format, args...)
127 logger.releaseEntry(entry)
131 func (logger *Logger) Printf(format string, args ...interface{}) {
132 entry := logger.newEntry()
133 entry.Printf(format, args...)
134 logger.releaseEntry(entry)
137 func (logger *Logger) Warnf(format string, args ...interface{}) {
138 if logger.level() >= WarnLevel {
139 entry := logger.newEntry()
140 entry.Warnf(format, args...)
141 logger.releaseEntry(entry)
145 func (logger *Logger) Warningf(format string, args ...interface{}) {
146 if logger.level() >= WarnLevel {
147 entry := logger.newEntry()
148 entry.Warnf(format, args...)
149 logger.releaseEntry(entry)
153 func (logger *Logger) Errorf(format string, args ...interface{}) {
154 if logger.level() >= ErrorLevel {
155 entry := logger.newEntry()
156 entry.Errorf(format, args...)
157 logger.releaseEntry(entry)
161 func (logger *Logger) Fatalf(format string, args ...interface{}) {
162 if logger.level() >= FatalLevel {
163 entry := logger.newEntry()
164 entry.Fatalf(format, args...)
165 logger.releaseEntry(entry)
170 func (logger *Logger) Panicf(format string, args ...interface{}) {
171 if logger.level() >= PanicLevel {
172 entry := logger.newEntry()
173 entry.Panicf(format, args...)
174 logger.releaseEntry(entry)
178 func (logger *Logger) Debug(args ...interface{}) {
179 if logger.level() >= DebugLevel {
180 entry := logger.newEntry()
182 logger.releaseEntry(entry)
186 func (logger *Logger) Info(args ...interface{}) {
187 if logger.level() >= InfoLevel {
188 entry := logger.newEntry()
190 logger.releaseEntry(entry)
194 func (logger *Logger) Print(args ...interface{}) {
195 entry := logger.newEntry()
197 logger.releaseEntry(entry)
200 func (logger *Logger) Warn(args ...interface{}) {
201 if logger.level() >= WarnLevel {
202 entry := logger.newEntry()
204 logger.releaseEntry(entry)
208 func (logger *Logger) Warning(args ...interface{}) {
209 if logger.level() >= WarnLevel {
210 entry := logger.newEntry()
212 logger.releaseEntry(entry)
216 func (logger *Logger) Error(args ...interface{}) {
217 if logger.level() >= ErrorLevel {
218 entry := logger.newEntry()
220 logger.releaseEntry(entry)
224 func (logger *Logger) Fatal(args ...interface{}) {
225 if logger.level() >= FatalLevel {
226 entry := logger.newEntry()
228 logger.releaseEntry(entry)
233 func (logger *Logger) Panic(args ...interface{}) {
234 if logger.level() >= PanicLevel {
235 entry := logger.newEntry()
237 logger.releaseEntry(entry)
241 func (logger *Logger) Debugln(args ...interface{}) {
242 if logger.level() >= DebugLevel {
243 entry := logger.newEntry()
244 entry.Debugln(args...)
245 logger.releaseEntry(entry)
249 func (logger *Logger) Infoln(args ...interface{}) {
250 if logger.level() >= InfoLevel {
251 entry := logger.newEntry()
252 entry.Infoln(args...)
253 logger.releaseEntry(entry)
257 func (logger *Logger) Println(args ...interface{}) {
258 entry := logger.newEntry()
259 entry.Println(args...)
260 logger.releaseEntry(entry)
263 func (logger *Logger) Warnln(args ...interface{}) {
264 if logger.level() >= WarnLevel {
265 entry := logger.newEntry()
266 entry.Warnln(args...)
267 logger.releaseEntry(entry)
271 func (logger *Logger) Warningln(args ...interface{}) {
272 if logger.level() >= WarnLevel {
273 entry := logger.newEntry()
274 entry.Warnln(args...)
275 logger.releaseEntry(entry)
279 func (logger *Logger) Errorln(args ...interface{}) {
280 if logger.level() >= ErrorLevel {
281 entry := logger.newEntry()
282 entry.Errorln(args...)
283 logger.releaseEntry(entry)
287 func (logger *Logger) Fatalln(args ...interface{}) {
288 if logger.level() >= FatalLevel {
289 entry := logger.newEntry()
290 entry.Fatalln(args...)
291 logger.releaseEntry(entry)
296 func (logger *Logger) Panicln(args ...interface{}) {
297 if logger.level() >= PanicLevel {
298 entry := logger.newEntry()
299 entry.Panicln(args...)
300 logger.releaseEntry(entry)
304 //When file is opened with appending mode, it's safe to
305 //write concurrently to a file (within 4k message on Linux).
306 //In these cases user can choose to disable the lock.
307 func (logger *Logger) SetNoLock() {
311 func (logger *Logger) level() Level {
312 return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
315 func (logger *Logger) setLevel(level Level) {
316 atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))