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