default_logger.go raw

   1  package logger
   2  
   3  import (
   4  	"fmt"
   5  	"io"
   6  	"log"
   7  	"os"
   8  	"strconv"
   9  )
  10  
  11  var (
  12  	DefaultLogger        = newLogger(os.Stderr, LogLevelWarning)
  13  	logger        Logger = DefaultLogger
  14  )
  15  
  16  // loggerT is the default logger used by scaleway-sdk-go.
  17  type loggerT struct {
  18  	m [4]*log.Logger
  19  	v LogLevel
  20  }
  21  
  22  // Init create a new default logger.
  23  // Not mutex-protected, should be called before any scaleway-sdk-go functions.
  24  func (g *loggerT) Init(w io.Writer, level LogLevel) {
  25  	g.m = newLogger(w, level).m
  26  	g.v = level
  27  }
  28  
  29  // Debugf logs to the DEBUG log. Arguments are handled in the manner of fmt.Printf.
  30  func Debugf(format string, args ...any) { logger.Debugf(format, args...) }
  31  
  32  func (g *loggerT) Debugf(format string, args ...any) {
  33  	g.m[LogLevelDebug].Printf(format, args...)
  34  }
  35  
  36  // Infof logs to the INFO log. Arguments are handled in the manner of fmt.Printf.
  37  func Infof(format string, args ...any) { logger.Infof(format, args...) }
  38  
  39  func (g *loggerT) Infof(format string, args ...any) {
  40  	g.m[LogLevelInfo].Printf(format, args...)
  41  }
  42  
  43  // Warningf logs to the WARNING log. Arguments are handled in the manner of fmt.Printf.
  44  func Warningf(format string, args ...any) { logger.Warningf(format, args...) }
  45  
  46  func (g *loggerT) Warningf(format string, args ...any) {
  47  	g.m[LogLevelWarning].Printf(format, args...)
  48  }
  49  
  50  // Errorf logs to the ERROR log. Arguments are handled in the manner of fmt.Printf.
  51  func Errorf(format string, args ...any) { logger.Errorf(format, args...) }
  52  
  53  func (g *loggerT) Errorf(format string, args ...any) {
  54  	g.m[LogLevelError].Printf(format, args...)
  55  }
  56  
  57  // ShouldLog reports whether verbosity level l is at least the requested verbose level.
  58  func ShouldLog(level LogLevel) bool { return logger.ShouldLog(level) }
  59  
  60  func (g *loggerT) ShouldLog(level LogLevel) bool {
  61  	return level >= g.v
  62  }
  63  
  64  func isEnabled(envKey string) bool {
  65  	env, exist := os.LookupEnv(envKey)
  66  	if !exist {
  67  		return false
  68  	}
  69  
  70  	value, err := strconv.ParseBool(env)
  71  	if err != nil {
  72  		fmt.Fprintf(os.Stderr, "ERROR: environment variable %s has invalid boolean value\n", envKey)
  73  	}
  74  
  75  	return value
  76  }
  77  
  78  // newLogger creates a logger to be used as default logger.
  79  // All logs are written to w.
  80  func newLogger(w io.Writer, level LogLevel) *loggerT {
  81  	errorW := io.Discard
  82  	warningW := io.Discard
  83  	infoW := io.Discard
  84  	debugW := io.Discard
  85  	if isEnabled(DebugEnv) {
  86  		level = LogLevelDebug
  87  	}
  88  	switch level {
  89  	case LogLevelDebug:
  90  		debugW = w
  91  	case LogLevelInfo:
  92  		infoW = w
  93  	case LogLevelWarning:
  94  		warningW = w
  95  	case LogLevelError:
  96  		errorW = w
  97  	}
  98  
  99  	// Error logs will be written to errorW, warningW, infoW and debugW.
 100  	// Warning logs will be written to warningW, infoW and debugW.
 101  	// Info logs will be written to infoW and debugW.
 102  	// Debug logs will be written to debugW.
 103  	var m [4]*log.Logger
 104  
 105  	m[LogLevelError] = log.New(io.MultiWriter(debugW, infoW, warningW, errorW),
 106  		severityName[LogLevelError]+": ", log.LstdFlags)
 107  
 108  	m[LogLevelWarning] = log.New(io.MultiWriter(debugW, infoW, warningW),
 109  		severityName[LogLevelWarning]+": ", log.LstdFlags)
 110  
 111  	m[LogLevelInfo] = log.New(io.MultiWriter(debugW, infoW),
 112  		severityName[LogLevelInfo]+": ", log.LstdFlags)
 113  
 114  	m[LogLevelDebug] = log.New(debugW,
 115  		severityName[LogLevelDebug]+": ", log.LstdFlags)
 116  
 117  	return &loggerT{m: m, v: level}
 118  }
 119