...

Source file src/github.com/sirupsen/logrus/logger.go

Documentation: github.com/sirupsen/logrus

     1  package logrus
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"os"
     7  	"sync"
     8  	"sync/atomic"
     9  	"time"
    10  )
    11  
    12  // LogFunction For big messages, it can be more efficient to pass a function
    13  // and only call it if the log level is actually enables rather than
    14  // generating the log message and then checking if the level is enabled
    15  type LogFunction func() []interface{}
    16  
    17  type Logger struct {
    18  	// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
    19  	// file, or leave it default which is `os.Stderr`. You can also set this to
    20  	// something more adventurous, such as logging to Kafka.
    21  	Out io.Writer
    22  	// Hooks for the logger instance. These allow firing events based on logging
    23  	// levels and log entries. For example, to send errors to an error tracking
    24  	// service, log to StatsD or dump the core on fatal errors.
    25  	Hooks LevelHooks
    26  	// All log entries pass through the formatter before logged to Out. The
    27  	// included formatters are `TextFormatter` and `JSONFormatter` for which
    28  	// TextFormatter is the default. In development (when a TTY is attached) it
    29  	// logs with colors, but to a file it wouldn't. You can easily implement your
    30  	// own that implements the `Formatter` interface, see the `README` or included
    31  	// formatters for examples.
    32  	Formatter Formatter
    33  
    34  	// Flag for whether to log caller info (off by default)
    35  	ReportCaller bool
    36  
    37  	// The logging level the logger should log at. This is typically (and defaults
    38  	// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
    39  	// logged.
    40  	Level Level
    41  	// Used to sync writing to the log. Locking is enabled by Default
    42  	mu MutexWrap
    43  	// Reusable empty entry
    44  	entryPool sync.Pool
    45  	// Function to exit the application, defaults to `os.Exit()`
    46  	ExitFunc exitFunc
    47  	// The buffer pool used to format the log. If it is nil, the default global
    48  	// buffer pool will be used.
    49  	BufferPool BufferPool
    50  }
    51  
    52  type exitFunc func(int)
    53  
    54  type MutexWrap struct {
    55  	lock     sync.Mutex
    56  	disabled bool
    57  }
    58  
    59  func (mw *MutexWrap) Lock() {
    60  	if !mw.disabled {
    61  		mw.lock.Lock()
    62  	}
    63  }
    64  
    65  func (mw *MutexWrap) Unlock() {
    66  	if !mw.disabled {
    67  		mw.lock.Unlock()
    68  	}
    69  }
    70  
    71  func (mw *MutexWrap) Disable() {
    72  	mw.disabled = true
    73  }
    74  
    75  // Creates a new logger. Configuration should be set by changing `Formatter`,
    76  // `Out` and `Hooks` directly on the default logger instance. You can also just
    77  // instantiate your own:
    78  //
    79  //    var log = &logrus.Logger{
    80  //      Out: os.Stderr,
    81  //      Formatter: new(logrus.TextFormatter),
    82  //      Hooks: make(logrus.LevelHooks),
    83  //      Level: logrus.DebugLevel,
    84  //    }
    85  //
    86  // It's recommended to make this a global instance called `log`.
    87  func New() *Logger {
    88  	return &Logger{
    89  		Out:          os.Stderr,
    90  		Formatter:    new(TextFormatter),
    91  		Hooks:        make(LevelHooks),
    92  		Level:        InfoLevel,
    93  		ExitFunc:     os.Exit,
    94  		ReportCaller: false,
    95  	}
    96  }
    97  
    98  func (logger *Logger) newEntry() *Entry {
    99  	entry, ok := logger.entryPool.Get().(*Entry)
   100  	if ok {
   101  		return entry
   102  	}
   103  	return NewEntry(logger)
   104  }
   105  
   106  func (logger *Logger) releaseEntry(entry *Entry) {
   107  	entry.Data = map[string]interface{}{}
   108  	logger.entryPool.Put(entry)
   109  }
   110  
   111  // WithField allocates a new entry and adds a field to it.
   112  // Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to
   113  // this new returned entry.
   114  // If you want multiple fields, use `WithFields`.
   115  func (logger *Logger) WithField(key string, value interface{}) *Entry {
   116  	entry := logger.newEntry()
   117  	defer logger.releaseEntry(entry)
   118  	return entry.WithField(key, value)
   119  }
   120  
   121  // Adds a struct of fields to the log entry. All it does is call `WithField` for
   122  // each `Field`.
   123  func (logger *Logger) WithFields(fields Fields) *Entry {
   124  	entry := logger.newEntry()
   125  	defer logger.releaseEntry(entry)
   126  	return entry.WithFields(fields)
   127  }
   128  
   129  // Add an error as single field to the log entry.  All it does is call
   130  // `WithError` for the given `error`.
   131  func (logger *Logger) WithError(err error) *Entry {
   132  	entry := logger.newEntry()
   133  	defer logger.releaseEntry(entry)
   134  	return entry.WithError(err)
   135  }
   136  
   137  // Add a context to the log entry.
   138  func (logger *Logger) WithContext(ctx context.Context) *Entry {
   139  	entry := logger.newEntry()
   140  	defer logger.releaseEntry(entry)
   141  	return entry.WithContext(ctx)
   142  }
   143  
   144  // Overrides the time of the log entry.
   145  func (logger *Logger) WithTime(t time.Time) *Entry {
   146  	entry := logger.newEntry()
   147  	defer logger.releaseEntry(entry)
   148  	return entry.WithTime(t)
   149  }
   150  
   151  func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
   152  	if logger.IsLevelEnabled(level) {
   153  		entry := logger.newEntry()
   154  		entry.Logf(level, format, args...)
   155  		logger.releaseEntry(entry)
   156  	}
   157  }
   158  
   159  func (logger *Logger) Tracef(format string, args ...interface{}) {
   160  	logger.Logf(TraceLevel, format, args...)
   161  }
   162  
   163  func (logger *Logger) Debugf(format string, args ...interface{}) {
   164  	logger.Logf(DebugLevel, format, args...)
   165  }
   166  
   167  func (logger *Logger) Infof(format string, args ...interface{}) {
   168  	logger.Logf(InfoLevel, format, args...)
   169  }
   170  
   171  func (logger *Logger) Printf(format string, args ...interface{}) {
   172  	entry := logger.newEntry()
   173  	entry.Printf(format, args...)
   174  	logger.releaseEntry(entry)
   175  }
   176  
   177  func (logger *Logger) Warnf(format string, args ...interface{}) {
   178  	logger.Logf(WarnLevel, format, args...)
   179  }
   180  
   181  func (logger *Logger) Warningf(format string, args ...interface{}) {
   182  	logger.Warnf(format, args...)
   183  }
   184  
   185  func (logger *Logger) Errorf(format string, args ...interface{}) {
   186  	logger.Logf(ErrorLevel, format, args...)
   187  }
   188  
   189  func (logger *Logger) Fatalf(format string, args ...interface{}) {
   190  	logger.Logf(FatalLevel, format, args...)
   191  	logger.Exit(1)
   192  }
   193  
   194  func (logger *Logger) Panicf(format string, args ...interface{}) {
   195  	logger.Logf(PanicLevel, format, args...)
   196  }
   197  
   198  // Log will log a message at the level given as parameter.
   199  // Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit.
   200  // For this behaviour Logger.Panic or Logger.Fatal should be used instead.
   201  func (logger *Logger) Log(level Level, args ...interface{}) {
   202  	if logger.IsLevelEnabled(level) {
   203  		entry := logger.newEntry()
   204  		entry.Log(level, args...)
   205  		logger.releaseEntry(entry)
   206  	}
   207  }
   208  
   209  func (logger *Logger) LogFn(level Level, fn LogFunction) {
   210  	if logger.IsLevelEnabled(level) {
   211  		entry := logger.newEntry()
   212  		entry.Log(level, fn()...)
   213  		logger.releaseEntry(entry)
   214  	}
   215  }
   216  
   217  func (logger *Logger) Trace(args ...interface{}) {
   218  	logger.Log(TraceLevel, args...)
   219  }
   220  
   221  func (logger *Logger) Debug(args ...interface{}) {
   222  	logger.Log(DebugLevel, args...)
   223  }
   224  
   225  func (logger *Logger) Info(args ...interface{}) {
   226  	logger.Log(InfoLevel, args...)
   227  }
   228  
   229  func (logger *Logger) Print(args ...interface{}) {
   230  	entry := logger.newEntry()
   231  	entry.Print(args...)
   232  	logger.releaseEntry(entry)
   233  }
   234  
   235  func (logger *Logger) Warn(args ...interface{}) {
   236  	logger.Log(WarnLevel, args...)
   237  }
   238  
   239  func (logger *Logger) Warning(args ...interface{}) {
   240  	logger.Warn(args...)
   241  }
   242  
   243  func (logger *Logger) Error(args ...interface{}) {
   244  	logger.Log(ErrorLevel, args...)
   245  }
   246  
   247  func (logger *Logger) Fatal(args ...interface{}) {
   248  	logger.Log(FatalLevel, args...)
   249  	logger.Exit(1)
   250  }
   251  
   252  func (logger *Logger) Panic(args ...interface{}) {
   253  	logger.Log(PanicLevel, args...)
   254  }
   255  
   256  func (logger *Logger) TraceFn(fn LogFunction) {
   257  	logger.LogFn(TraceLevel, fn)
   258  }
   259  
   260  func (logger *Logger) DebugFn(fn LogFunction) {
   261  	logger.LogFn(DebugLevel, fn)
   262  }
   263  
   264  func (logger *Logger) InfoFn(fn LogFunction) {
   265  	logger.LogFn(InfoLevel, fn)
   266  }
   267  
   268  func (logger *Logger) PrintFn(fn LogFunction) {
   269  	entry := logger.newEntry()
   270  	entry.Print(fn()...)
   271  	logger.releaseEntry(entry)
   272  }
   273  
   274  func (logger *Logger) WarnFn(fn LogFunction) {
   275  	logger.LogFn(WarnLevel, fn)
   276  }
   277  
   278  func (logger *Logger) WarningFn(fn LogFunction) {
   279  	logger.WarnFn(fn)
   280  }
   281  
   282  func (logger *Logger) ErrorFn(fn LogFunction) {
   283  	logger.LogFn(ErrorLevel, fn)
   284  }
   285  
   286  func (logger *Logger) FatalFn(fn LogFunction) {
   287  	logger.LogFn(FatalLevel, fn)
   288  	logger.Exit(1)
   289  }
   290  
   291  func (logger *Logger) PanicFn(fn LogFunction) {
   292  	logger.LogFn(PanicLevel, fn)
   293  }
   294  
   295  func (logger *Logger) Logln(level Level, args ...interface{}) {
   296  	if logger.IsLevelEnabled(level) {
   297  		entry := logger.newEntry()
   298  		entry.Logln(level, args...)
   299  		logger.releaseEntry(entry)
   300  	}
   301  }
   302  
   303  func (logger *Logger) Traceln(args ...interface{}) {
   304  	logger.Logln(TraceLevel, args...)
   305  }
   306  
   307  func (logger *Logger) Debugln(args ...interface{}) {
   308  	logger.Logln(DebugLevel, args...)
   309  }
   310  
   311  func (logger *Logger) Infoln(args ...interface{}) {
   312  	logger.Logln(InfoLevel, args...)
   313  }
   314  
   315  func (logger *Logger) Println(args ...interface{}) {
   316  	entry := logger.newEntry()
   317  	entry.Println(args...)
   318  	logger.releaseEntry(entry)
   319  }
   320  
   321  func (logger *Logger) Warnln(args ...interface{}) {
   322  	logger.Logln(WarnLevel, args...)
   323  }
   324  
   325  func (logger *Logger) Warningln(args ...interface{}) {
   326  	logger.Warnln(args...)
   327  }
   328  
   329  func (logger *Logger) Errorln(args ...interface{}) {
   330  	logger.Logln(ErrorLevel, args...)
   331  }
   332  
   333  func (logger *Logger) Fatalln(args ...interface{}) {
   334  	logger.Logln(FatalLevel, args...)
   335  	logger.Exit(1)
   336  }
   337  
   338  func (logger *Logger) Panicln(args ...interface{}) {
   339  	logger.Logln(PanicLevel, args...)
   340  }
   341  
   342  func (logger *Logger) Exit(code int) {
   343  	runHandlers()
   344  	if logger.ExitFunc == nil {
   345  		logger.ExitFunc = os.Exit
   346  	}
   347  	logger.ExitFunc(code)
   348  }
   349  
   350  //When file is opened with appending mode, it's safe to
   351  //write concurrently to a file (within 4k message on Linux).
   352  //In these cases user can choose to disable the lock.
   353  func (logger *Logger) SetNoLock() {
   354  	logger.mu.Disable()
   355  }
   356  
   357  func (logger *Logger) level() Level {
   358  	return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
   359  }
   360  
   361  // SetLevel sets the logger level.
   362  func (logger *Logger) SetLevel(level Level) {
   363  	atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
   364  }
   365  
   366  // GetLevel returns the logger level.
   367  func (logger *Logger) GetLevel() Level {
   368  	return logger.level()
   369  }
   370  
   371  // AddHook adds a hook to the logger hooks.
   372  func (logger *Logger) AddHook(hook Hook) {
   373  	logger.mu.Lock()
   374  	defer logger.mu.Unlock()
   375  	logger.Hooks.Add(hook)
   376  }
   377  
   378  // IsLevelEnabled checks if the log level of the logger is greater than the level param
   379  func (logger *Logger) IsLevelEnabled(level Level) bool {
   380  	return logger.level() >= level
   381  }
   382  
   383  // SetFormatter sets the logger formatter.
   384  func (logger *Logger) SetFormatter(formatter Formatter) {
   385  	logger.mu.Lock()
   386  	defer logger.mu.Unlock()
   387  	logger.Formatter = formatter
   388  }
   389  
   390  // SetOutput sets the logger output.
   391  func (logger *Logger) SetOutput(output io.Writer) {
   392  	logger.mu.Lock()
   393  	defer logger.mu.Unlock()
   394  	logger.Out = output
   395  }
   396  
   397  func (logger *Logger) SetReportCaller(reportCaller bool) {
   398  	logger.mu.Lock()
   399  	defer logger.mu.Unlock()
   400  	logger.ReportCaller = reportCaller
   401  }
   402  
   403  // ReplaceHooks replaces the logger hooks and returns the old ones
   404  func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
   405  	logger.mu.Lock()
   406  	oldHooks := logger.Hooks
   407  	logger.Hooks = hooks
   408  	logger.mu.Unlock()
   409  	return oldHooks
   410  }
   411  
   412  // SetBufferPool sets the logger buffer pool.
   413  func (logger *Logger) SetBufferPool(pool BufferPool) {
   414  	logger.mu.Lock()
   415  	defer logger.mu.Unlock()
   416  	logger.BufferPool = pool
   417  }
   418  

View as plain text