github.com/grailbio/base@v0.0.11/log/log.go (about) 1 // Copyright 2018 GRAIL, Inc. All rights reserved. 2 // Use of this source code is governed by the Apache 2.0 3 // license that can be found in the LICENSE file. 4 5 // Package log provides simple level logging. Log output is 6 // implemented by an outputter, which by default outputs to Go's 7 // logging package. Alternative implementations (e.g., vlog, glog) 8 // can provide their own outputter implementation so that logging 9 // output is unified. 10 // 11 // The package can be used as a replacement for Go's standard logging 12 // package; the behavior of its toplevel functions are identical with 13 // the default configuration. 14 // 15 // If the application wishes to configure logging levels by standard 16 // flags, it should call log.AddFlags before flag.Parse. 17 // log.AddFlags. 18 // 19 // Note that this package is intended to bridge Go's standard log 20 // package with Vanadium's (vlog). As we transition away from vlog, 21 // we can simplify this package by removing the Outputter interface. 22 package log 23 24 import ( 25 "fmt" 26 "os" 27 ) 28 29 // An Outputter provides a destination for leveled log output. 30 type Outputter interface { 31 // Level returns the level at which the outputter is accepting 32 // messages. 33 Level() Level 34 35 // Output writes the provided message to the outputter at the 36 // provided calldepth and level. The message is dropped by 37 // the outputter if it is not logging at the desired level. 38 Output(calldepth int, level Level, s string) error 39 } 40 41 var out Outputter = gologOutputter{} 42 43 // SetOutputter provides a new outputter for use in the log package. 44 // SetOutputter should not be called concurrently with any log 45 // output, and is thus suitable to be called only upon program 46 // initialization. SetOutputter returns the old outputter. 47 func SetOutputter(newOut Outputter) Outputter { 48 old := out 49 out = newOut 50 return old 51 } 52 53 // GetOutputter returns the current outputter used by the log package. 54 func GetOutputter() Outputter { 55 return out 56 } 57 58 // At returns whether the logger is currently logging at the provided level. 59 func At(level Level) bool { 60 return level <= out.Level() 61 } 62 63 // Output outputs a log message to the current outputter at the provided 64 // level and call depth. 65 func Output(calldepth int, level Level, s string) error { 66 return out.Output(calldepth+1, level, s) 67 } 68 69 // A Level is a log verbosity level. Increasing levels decrease in 70 // priority and (usually) increase in verbosity: if the outputter is 71 // logging at level L, then all messages with level M <= L are 72 // outputted. 73 type Level int 74 75 const ( 76 // Off never outputs messages. 77 Off = Level(-3) 78 // Error outputs error messages. 79 Error = Level(-2) 80 // Info outputs informational messages. This is the standard 81 // logging level. 82 Info = Level(0) 83 // Debug outputs messages intended for debugging and development, 84 // not for regular users. 85 Debug = Level(1) 86 ) 87 88 // String returns the string representation of the level l. 89 func (l Level) String() string { 90 switch l { 91 case Off: 92 return "off" 93 case Error: 94 return "error" 95 case Info: 96 return "info" 97 case Debug: 98 return "debug" 99 default: 100 if l < 0 { 101 panic("invalid log level") 102 } 103 return fmt.Sprintf("debug%d", l) 104 } 105 } 106 107 // Print formats a message in the manner of fmt.Sprint and outputs it 108 // at level l to the current outputter. 109 func (l Level) Print(v ...interface{}) { 110 if At(l) { 111 _ = out.Output(2, l, fmt.Sprint(v...)) 112 } 113 } 114 115 // Printkln formats a message in the manner of fmt.Sprintln and outputs 116 // it at level l to the current outputter. 117 func (l Level) Println(v ...interface{}) { 118 if At(l) { 119 _ = out.Output(2, l, fmt.Sprintln(v...)) 120 } 121 } 122 123 // Printf formats a message in the manner of fmt.Sprintf and outputs 124 // it at level l to the current outputter. 125 func (l Level) Printf(format string, v ...interface{}) { 126 if At(l) { 127 _ = out.Output(2, l, fmt.Sprintf(format, v...)) 128 } 129 } 130 131 // Print formats a message in the manner of fmt.Sprint 132 // and outputs it at the Info level to the current outputter. 133 func Print(v ...interface{}) { 134 if At(Info) { 135 _ = out.Output(2, Info, fmt.Sprint(v...)) 136 } 137 } 138 139 // Printf formats a message in the manner of fmt.Sprintf 140 // and outputs it at the Info level to the current outputter. 141 func Printf(format string, v ...interface{}) { 142 if At(Info) { 143 _ = out.Output(2, Info, fmt.Sprintf(format, v...)) 144 } 145 } 146 147 // Errorf formats a message in the manner of fmt.Sprintf 148 // and outputs it at the Error level to the current outputter. 149 func Errorf(format string, v ...interface{}) { 150 _ = out.Output(2, Error, fmt.Sprintf(format, v...)) 151 } 152 153 // Fatal formats a message in the manner of fmt.Sprint, outputs it at 154 // the error level to the current outputter and then calls 155 // os.Exit(1). 156 func Fatal(v ...interface{}) { 157 _ = out.Output(2, Error, fmt.Sprint(v...)) 158 os.Exit(1) 159 } 160 161 // Fatalf formats a message in the manner of fmt.Sprintf, outputs it at 162 // the error level to the current outputter and then calls 163 // os.Exit(1). 164 func Fatalf(format string, v ...interface{}) { 165 _ = out.Output(2, Error, fmt.Sprintf(format, v...)) 166 os.Exit(1) 167 } 168 169 // Panic formats a message in the manner of fmt.Sprint, outputs it 170 // at the error level to the current outputter and then panics. 171 func Panic(v ...interface{}) { 172 s := fmt.Sprint(v...) 173 _ = out.Output(2, Error, s) 174 panic(s) 175 } 176 177 // Panicf formats a message in the manner of fmt.Sprintf, outputs it 178 // at the error level to the current outputter and then panics. 179 func Panicf(format string, v ...interface{}) { 180 s := fmt.Sprintf(format, v...) 181 _ = out.Output(2, Error, s) 182 panic(s) 183 } 184 185 // Outputf is formats a message using fmt.Sprintf and outputs it 186 // to the provided logger at the provided level. 187 func Outputf(out Outputter, level Level, format string, v ...interface{}) { 188 _ = out.Output(2, level, fmt.Sprintf(format, v...)) 189 }