...

Source file src/github.com/ory/x/logrusx/logrus.go

Documentation: github.com/ory/x/logrusx

     1  package logrusx
     2  
     3  import (
     4  	"os"
     5  
     6  	"github.com/sirupsen/logrus"
     7  
     8  	gelf "github.com/seatgeek/logrus-gelf-formatter"
     9  
    10  	"github.com/ory/x/stringsx"
    11  )
    12  
    13  type (
    14  	options struct {
    15  		l             *logrus.Logger
    16  		level         *logrus.Level
    17  		formatter     logrus.Formatter
    18  		format        string
    19  		reportCaller  bool
    20  		exitFunc      func(int)
    21  		leakSensitive bool
    22  		hooks         []logrus.Hook
    23  		c             configurator
    24  	}
    25  	Option           func(*options)
    26  	nullConfigurator struct{}
    27  	configurator     interface {
    28  		Bool(key string) bool
    29  		String(key string) string
    30  	}
    31  )
    32  
    33  func newLogger(parent *logrus.Logger, o *options) *logrus.Logger {
    34  	l := parent
    35  	if l == nil {
    36  		l = logrus.New()
    37  	}
    38  
    39  	if o.exitFunc != nil {
    40  		l.ExitFunc = o.exitFunc
    41  	}
    42  
    43  	setLevel(l, o)
    44  	setFormatter(l, o)
    45  
    46  	for _, hook := range o.hooks {
    47  		l.AddHook(hook)
    48  	}
    49  
    50  	l.ReportCaller = o.reportCaller || l.IsLevelEnabled(logrus.TraceLevel)
    51  	return l
    52  }
    53  
    54  func setLevel(l *logrus.Logger, o *options) {
    55  	if o.level != nil {
    56  		l.Level = *o.level
    57  	} else {
    58  		var err error
    59  		l.Level, err = logrus.ParseLevel(stringsx.Coalesce(
    60  			o.c.String("log.level"),
    61  			os.Getenv("LOG_LEVEL")))
    62  		if err != nil {
    63  			l.Level = logrus.InfoLevel
    64  		}
    65  	}
    66  }
    67  
    68  func setFormatter(l *logrus.Logger, o *options) {
    69  	if o.formatter != nil {
    70  		l.Formatter = o.formatter
    71  	} else {
    72  		switch stringsx.Coalesce(o.format, o.c.String("log.format"), os.Getenv("LOG_FORMAT")) {
    73  		case "json":
    74  			l.Formatter = &logrus.JSONFormatter{PrettyPrint: false}
    75  		case "json_pretty":
    76  			l.Formatter = &logrus.JSONFormatter{PrettyPrint: true}
    77  		case "gelf":
    78  			l.Formatter = new(gelf.GelfFormatter)
    79  		default:
    80  			l.Formatter = &logrus.TextFormatter{
    81  				DisableQuote:     true,
    82  				DisableTimestamp: false,
    83  				FullTimestamp:    true,
    84  			}
    85  		}
    86  	}
    87  }
    88  
    89  func ForceLevel(level logrus.Level) Option {
    90  	return func(o *options) {
    91  		o.level = &level
    92  	}
    93  }
    94  
    95  func ForceFormatter(formatter logrus.Formatter) Option {
    96  	return func(o *options) {
    97  		o.formatter = formatter
    98  	}
    99  }
   100  
   101  func WithConfigurator(c configurator) Option {
   102  	return func(o *options) {
   103  		o.c = c
   104  	}
   105  }
   106  
   107  func ForceFormat(format string) Option {
   108  	return func(o *options) {
   109  		o.format = format
   110  	}
   111  }
   112  
   113  func WithHook(hook logrus.Hook) Option {
   114  	return func(o *options) {
   115  		o.hooks = append(o.hooks, hook)
   116  	}
   117  }
   118  
   119  func WithExitFunc(exitFunc func(int)) Option {
   120  	return func(o *options) {
   121  		o.exitFunc = exitFunc
   122  	}
   123  }
   124  
   125  func ReportCaller(reportCaller bool) Option {
   126  	return func(o *options) {
   127  		o.reportCaller = reportCaller
   128  	}
   129  }
   130  
   131  func UseLogger(l *logrus.Logger) Option {
   132  	return func(o *options) {
   133  		o.l = l
   134  	}
   135  }
   136  
   137  func LeakSensitive() Option {
   138  	return func(o *options) {
   139  		o.leakSensitive = true
   140  	}
   141  }
   142  
   143  func (c *nullConfigurator) Bool(_ string) bool {
   144  	return false
   145  }
   146  
   147  func (c *nullConfigurator) String(_ string) string {
   148  	return ""
   149  }
   150  
   151  func newOptions(opts []Option) *options {
   152  	o := new(options)
   153  	o.c = new(nullConfigurator)
   154  	for _, f := range opts {
   155  		f(o)
   156  	}
   157  	return o
   158  }
   159  
   160  // New creates a new logger with all the important fields set.
   161  func New(name string, version string, opts ...Option) *Logger {
   162  	o := newOptions(opts)
   163  	return &Logger{
   164  		opts:          opts,
   165  		name:          name,
   166  		version:       version,
   167  		leakSensitive: o.leakSensitive || o.c.Bool("log.leak_sensitive_values"),
   168  		Entry: newLogger(o.l, o).WithFields(logrus.Fields{
   169  			"audience": "application", "service_name": name, "service_version": version}),
   170  	}
   171  }
   172  
   173  func NewAudit(name string, version string, opts ...Option) *Logger {
   174  	return New(name, version, opts...).WithField("audience", "audit")
   175  }
   176  
   177  func (l *Logger) UseConfig(c configurator) {
   178  	l.leakSensitive = l.leakSensitive || c.Bool("log.leak_sensitive_values")
   179  	o := newOptions(append(l.opts, WithConfigurator(c)))
   180  	setLevel(l.Entry.Logger, o)
   181  	setFormatter(l.Entry.Logger, o)
   182  }
   183  

View as plain text