...

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

Documentation: github.com/sirupsen/logrus

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

View as plain text