├── go.mod ├── LICENSE ├── README.md └── log.go /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gologme/log 2 | 3 | go 1.17 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2021 Bret Jordan. All rights reserved. 2 | Copyright (c) 2009 The Go Authors. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors 15 | may be used to endorse or promote products derived from this software without 16 | specific prior written permission. ∑ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 17 | HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 | OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 26 | OF SUCH DAMAGE. 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gologme/log # 2 | 3 | [![Go Report Card](https://goreportcard.com/badge/github.com/gologme/log)](https://goreportcard.com/report/github.com/gologme/log) 4 | [![GoDoc](https://godoc.org/github.com/gologme/log?status.png)](https://godoc.org/github.com/gologme/log) 5 | [![GitHub license](https://img.shields.io/github/license/gologme/log.svg?style=flat)](https://github.com/gologme/log/blob/master/LICENSE) 6 | [![GitHub go.mod Go version of a Go module](https://img.shields.io/github/go-mod/go-version/gologme/log.svg?style=flat)](https://github.com/gologme/log) 7 | 8 | 9 | This package is a drop in replacement for the built-in Go log package. All the 10 | functionality of the built-in package still exists and is unchanged. In addition, 11 | this package contains a series of small enhancements and additions. Namely, it 12 | adds five logging levels. These logging levels are: 13 | 14 | - Error 15 | - Warn 16 | - Info 17 | - Debug 18 | - Trace 19 | 20 | In addition to these five defined logging levels, users can also define their 21 | own arbitrary logging levels. 22 | 23 | Unlike other loggers, these logging levels are not enabled in a chain. Meaning, 24 | once a level is enabled, say Warn, all levels above it are not also enabled. 25 | This package is implemented in such a way that users can individually turn on 26 | and turn off the various new logging levels. However, starting with v1.3.0 27 | users can enable logging in a chain buy enabling logging levels by number 28 | (see below). If existing code uses the build-in log package, no change is 29 | needed to use this package. 30 | 31 | Another feature that was added, based on comments seen on the various golang 32 | boards, is the ability to set the calldepth. 33 | 34 | 35 | ## Version ## 36 | 1.3.0 37 | 38 | ### New to version 1.3.0 ### 39 | - Made changes to bring it current as of Go 1.17.1 so it remains a drop in replacement 40 | - Made chagnes based on feedback 41 | - Sorted log levels into natural order 42 | - Enabled formatted prefixes that include the log level (e.g., [info] {rest of log line}) 43 | - Enabled turning on logging levels by number similar to syslog 44 | 45 | ## Installation ## 46 | 47 | This package can be installed with the go get command: 48 | ``` 49 | go get github.com/gologme/log 50 | go install github.com/gologme/log 51 | ``` 52 | 53 | ## Example ## 54 | 55 | Just like the built-in package, code can still do simple logging just like: 56 | ``` 57 | log.Println("some interesting logging message") 58 | ``` 59 | 60 | In addition to this, users can enable info, warn, error, debug, or trace logging like: 61 | ``` 62 | log.EnableLevel("error") 63 | log.EnableLevel("warn") 64 | log.EnableLevel("info") 65 | log.EnableLevel("debug") 66 | log.EnableLevel("trace") 67 | ``` 68 | 69 | Once these levels are enabled, calls to the info, warn, error, debug, or trace loggers 70 | will print out just like they do for the Print and Fatal built-in loggers. The 71 | functions / methods definitions that are defined for each level, match exactly 72 | the ones defined in the built-in package. The new functions/methods are called: 73 | ``` 74 | log.Error() 75 | log.Errorf() 76 | log.Errorln() 77 | log.Warn() 78 | log.Warnf() 79 | log.Warnln() 80 | log.Info() 81 | log.Infof() 82 | log.Infoln() 83 | log.Debug() 84 | log.Debugf() 85 | log.Debugln() 86 | log.Trace() 87 | log.Tracef() 88 | log.Traceln() 89 | ``` 90 | 91 | In addition to the defined levels, arbitrary levels can be enabled. For example: 92 | ``` 93 | log.EnableLevel("tracedebug") 94 | ``` 95 | 96 | This level can then be used from an application as shown below. All three 97 | functions/methods are defined for this: log.Level(), log.Levelln(), log.Levelf(). 98 | For each of these, the first argument is the level name. 99 | ``` 100 | log.Levelln("tracedebug", "some other neat logging message for this level") 101 | ``` 102 | 103 | To enable the log level to be included in the prefix enable it. 104 | ``` 105 | log.EnableFormattedPrefix() 106 | ``` 107 | This will make the log lines look like, note the log level prefix: 108 | 109 | `[debug] 2021/10/15 12:46:52 some logging message ` 110 | 111 | To enable logging by the following numerical levels 112 | - Level 10 = panic, fatal, error, warn, info, debug, & trace 113 | - Level 5 = panic, fatal, error, warn, info, & debug 114 | - Level 4 = panic, fatal, error, warn, & info 115 | - Level 3 = panic, fatal, error, & warn 116 | - Level 2 = panic, fatal & error 117 | - Level 1 = panic, fatal 118 | 119 | ``` 120 | log.EnableLevelsByNumber(int) 121 | ``` 122 | 123 | To disable all logging levels 124 | ``` 125 | log.DisableAllLevels() 126 | ``` 127 | 128 | The last thing that was enabled was the ability to define the calldepth. The 129 | built-in package from the Go authors had this hard coded to a value of 2. A small 130 | change was made to enable this to be set by the application using the log package. 131 | From the Go authors source code it seems like the normal possible values would 132 | be 1, 2, or 3. 133 | ``` 134 | log.SetCallDepth(int) 135 | ``` 136 | 137 | 138 | ## License ## 139 | 140 | This is free software, licensed under the same BSD license that the original 141 | Go log package was licensed. 142 | 143 | 144 | ## Copyright ## 145 | 146 | Copyright 2017-2021 Bret Jordan, All rights reserved. 147 | -------------------------------------------------------------------------------- /log.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2021 Bret Jordan, All rights reserved. 2 | // 3 | // This package contains a series of changes and additions to the the build-in 4 | // log package from the Go Authors found here: 5 | // https://golang.org/src/log/log.go 6 | // See their copyright below. 7 | // 8 | // Version 1.3.0 9 | 10 | // Copyright 2009 The Go Authors. All rights reserved. 11 | // Use of this source code is governed by a BSD-style 12 | // license that can be found in the LICENSE file. 13 | 14 | // Package log implements a simple logging package. It defines a type, Logger, 15 | // with methods for formatting output. It also has a predefined 'standard' 16 | // Logger accessible through helper functions Print[f|ln], Fatal[f|ln], and 17 | // Panic[f|ln], which are easier to use than creating a Logger manually. 18 | // That logger writes to standard error and prints the date and time 19 | // of each logged message. 20 | // Every log message is output on a separate line: if the message being 21 | // printed does not end in a newline, the logger will add one. 22 | // The Fatal functions call os.Exit(1) after writing the log message. 23 | // The Panic functions call panic after writing the log message. 24 | package log 25 | 26 | import ( 27 | "fmt" 28 | "io" 29 | "os" 30 | "runtime" 31 | "strings" 32 | "sync" 33 | "time" 34 | ) 35 | 36 | // These flags define which text to prefix to each log entry generated by the Logger. 37 | // Bits are or'ed together to control what's printed. 38 | // With the exception of the Lmsgprefix flag, there is no 39 | // control over the order they appear (the order listed here) 40 | // or the format they present (as described in the comments). 41 | // The prefix is followed by a colon only when Llongfile or Lshortfile 42 | // is specified. 43 | // For example, flags Ldate | Ltime (or LstdFlags) produce, 44 | // 2009/01/23 01:23:23 message 45 | // while flags Ldate | Ltime | Lmicroseconds | Llongfile produce, 46 | // 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message 47 | const ( 48 | Ldate = 1 << iota // the date in the local time zone: 2009/01/23 49 | Ltime // the time in the local time zone: 01:23:23 50 | Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. 51 | Llongfile // full file name and line number: /a/b/c/d.go:23 52 | Lshortfile // final file name element and line number: d.go:23. overrides Llongfile 53 | LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone 54 | Lmsgprefix // move the "prefix" from the beginning of the line to before the message 55 | LstdFlags = Ldate | Ltime // initial values for the standard logger 56 | ) 57 | 58 | // A Logger represents an active logging object that generates lines of 59 | // output to an io.Writer. Each logging operation makes a single call to 60 | // the Writer's Write method. A Logger can be used simultaneously from 61 | // multiple goroutines; it guarantees to serialize access to the Writer. 62 | // 63 | // Calldepth is used to recover the PC and is provided for generality, although 64 | // at the moment on all pre-defined paths it will be 2. 65 | // Jordan: Added calldepth, levels, and formattedPrefix to the struct 66 | type Logger struct { 67 | mu sync.Mutex // ensures atomic writes; protects the following fields 68 | prefix string // prefix to write at beginning of each line 69 | flag int // properties 70 | out io.Writer // destination for output 71 | buf []byte // for accumulating text to write 72 | calldepth int 73 | levels map[string]bool 74 | formattedPrefix bool 75 | } 76 | 77 | // New creates a new Logger. The out variable sets the 78 | // destination to which log data will be written. 79 | // The prefix appears at the beginning of each generated log line, or 80 | // after the log header if the Lmsgprefix flag is provided. 81 | // The flag argument defines the logging properties. 82 | // Jordan: Added levels and enabled fatal by default 83 | func New(out io.Writer, prefix string, flag int) *Logger { 84 | l := Logger{out: out, prefix: prefix, flag: flag} 85 | // Since panic and fatal are part of the standard library, lets enable them 86 | // by default so that they just work and the checks in the Output function 87 | // will allow them. 88 | l.levels = map[string]bool{ 89 | "panic": true, 90 | "fatal": true, 91 | "error": false, 92 | "warn": false, 93 | "info": false, 94 | "debug": false, 95 | "trace": false, 96 | } 97 | return &l 98 | } 99 | 100 | // SetOutput sets the output destination for the logger. 101 | func (l *Logger) SetOutput(w io.Writer) { 102 | l.mu.Lock() 103 | defer l.mu.Unlock() 104 | l.out = w 105 | } 106 | 107 | var std = New(os.Stderr, "", LstdFlags) 108 | 109 | // Default returns the standard logger used by the package-level output functions. 110 | func Default() *Logger { return std } 111 | 112 | // Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. 113 | func itoa(buf *[]byte, i int, wid int) { 114 | // Assemble decimal in reverse order. 115 | var b [20]byte 116 | bp := len(b) - 1 117 | for i >= 10 || wid > 1 { 118 | wid-- 119 | q := i / 10 120 | b[bp] = byte('0' + i - q*10) 121 | bp-- 122 | i = q 123 | } 124 | // i < 10 125 | b[bp] = byte('0' + i) 126 | *buf = append(*buf, b[bp:]...) 127 | } 128 | 129 | // formatHeader writes log header to buf in following order: 130 | // * l.prefix (if it's not blank and Lmsgprefix is unset), 131 | // * date and/or time (if corresponding flags are provided), 132 | // * file and line number (if corresponding flags are provided), 133 | // * l.prefix (if it's not blank and Lmsgprefix is set). 134 | func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) { 135 | if l.flag&Lmsgprefix == 0 { 136 | *buf = append(*buf, l.prefix...) 137 | } 138 | if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 { 139 | if l.flag&LUTC != 0 { 140 | t = t.UTC() 141 | } 142 | if l.flag&Ldate != 0 { 143 | year, month, day := t.Date() 144 | itoa(buf, year, 4) 145 | *buf = append(*buf, '/') 146 | itoa(buf, int(month), 2) 147 | *buf = append(*buf, '/') 148 | itoa(buf, day, 2) 149 | *buf = append(*buf, ' ') 150 | } 151 | if l.flag&(Ltime|Lmicroseconds) != 0 { 152 | hour, min, sec := t.Clock() 153 | itoa(buf, hour, 2) 154 | *buf = append(*buf, ':') 155 | itoa(buf, min, 2) 156 | *buf = append(*buf, ':') 157 | itoa(buf, sec, 2) 158 | if l.flag&Lmicroseconds != 0 { 159 | *buf = append(*buf, '.') 160 | itoa(buf, t.Nanosecond()/1e3, 6) 161 | } 162 | *buf = append(*buf, ' ') 163 | } 164 | } 165 | if l.flag&(Lshortfile|Llongfile) != 0 { 166 | if l.flag&Lshortfile != 0 { 167 | short := file 168 | for i := len(file) - 1; i > 0; i-- { 169 | if file[i] == '/' { 170 | short = file[i+1:] 171 | break 172 | } 173 | } 174 | file = short 175 | } 176 | *buf = append(*buf, file...) 177 | *buf = append(*buf, ':') 178 | itoa(buf, line, -1) 179 | *buf = append(*buf, ": "...) 180 | } 181 | if l.flag&Lmsgprefix != 0 { 182 | *buf = append(*buf, l.prefix...) 183 | } 184 | } 185 | 186 | // Output writes the output for a logging event. The string s contains 187 | // the text to print after the prefix specified by the flags of the 188 | // Logger. A newline is appended if the last character of s is not 189 | // already a newline. Calldepth is used to recover the PC and is 190 | // provided for generality, although at the moment on all pre-defined 191 | // paths it will be 2. 192 | // Jordan: Set calldepth and allow default levels. Call depth is now in object 193 | func (l *Logger) Output(level string, s string) error { 194 | // Lets set the default value to 2, just like it was before. 195 | if l.calldepth == 0 { 196 | l.calldepth = 2 197 | } 198 | 199 | // Allow the default standard log types to just work and do not output 200 | // log levels that are turned off. However, we need to address the "fatal" 201 | // loglevel and allow it, as it is part of the standard library. This was 202 | // done in the new function to enable fatal by default. 203 | if level != "" { 204 | if val, ok := l.levels[level]; !ok || val == false { 205 | return nil 206 | } 207 | } 208 | 209 | // Set prefix to be formatted 210 | var pre string 211 | if l.formattedPrefix { 212 | if level == "warn" || level == "info" { 213 | pre = "[" + strings.ToUpper(level) + "] " 214 | } else { 215 | pre = "[" + strings.ToUpper(level) + "] " 216 | } 217 | 218 | l.SetPrefix(pre) 219 | } 220 | 221 | now := time.Now() // get this early. 222 | var file string 223 | var line int 224 | l.mu.Lock() 225 | defer l.mu.Unlock() 226 | if l.flag&(Lshortfile|Llongfile) != 0 { 227 | // Release lock while getting caller info - it's expensive. 228 | l.mu.Unlock() 229 | var ok bool 230 | // Jordan: use calldepth on object 231 | _, file, line, ok = runtime.Caller(l.calldepth) 232 | if !ok { 233 | file = "???" 234 | line = 0 235 | } 236 | l.mu.Lock() 237 | } 238 | l.buf = l.buf[:0] 239 | l.formatHeader(&l.buf, now, file, line) 240 | l.buf = append(l.buf, s...) 241 | if len(s) == 0 || s[len(s)-1] != '\n' { 242 | l.buf = append(l.buf, '\n') 243 | } 244 | _, err := l.out.Write(l.buf) 245 | return err 246 | } 247 | 248 | // Jordan: In all of these functions we are passing in the logging level now 249 | // not the calldepth, since the calldepth is set on the object 250 | 251 | // Printf calls l.Output to print to the logger. 252 | // Arguments are handled in the manner of fmt.Printf. 253 | func (l *Logger) Printf(format string, v ...interface{}) { 254 | l.Output("", fmt.Sprintf(format, v...)) 255 | } 256 | 257 | // Print calls l.Output to print to the logger. 258 | // Arguments are handled in the manner of fmt.Print. 259 | func (l *Logger) Print(v ...interface{}) { l.Output("", fmt.Sprint(v...)) } 260 | 261 | // Println calls l.Output to print to the logger. 262 | // Arguments are handled in the manner of fmt.Println. 263 | func (l *Logger) Println(v ...interface{}) { l.Output("", fmt.Sprintln(v...)) } 264 | 265 | // Fatal is equivalent to l.Print() followed by a call to os.Exit(1). 266 | // Jordan: added fatal as a level so it can show up in formatted logs 267 | func (l *Logger) Fatal(v ...interface{}) { 268 | l.Output("fatal", fmt.Sprint(v...)) 269 | os.Exit(1) 270 | } 271 | 272 | // Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1). 273 | // Jordan: added fatal as a level so it can show up in formatted logs 274 | func (l *Logger) Fatalf(format string, v ...interface{}) { 275 | l.Output("fatal", fmt.Sprintf(format, v...)) 276 | os.Exit(1) 277 | } 278 | 279 | // Fatalln is equivalent to l.Println() followed by a call to os.Exit(1). 280 | // Jordan: added fatal as a level so it can show up in formatted logs 281 | func (l *Logger) Fatalln(v ...interface{}) { 282 | l.Output("fatal", fmt.Sprintln(v...)) 283 | os.Exit(1) 284 | } 285 | 286 | // Panic is equivalent to l.Print() followed by a call to panic(). 287 | // Jordan: added panic as a level so it can show up in formatted logs 288 | func (l *Logger) Panic(v ...interface{}) { 289 | s := fmt.Sprint(v...) 290 | l.Output("panic", s) 291 | panic(s) 292 | } 293 | 294 | // Panicf is equivalent to l.Printf() followed by a call to panic(). 295 | // Jordan: added panic as a level so it can show up in formatted logs 296 | func (l *Logger) Panicf(format string, v ...interface{}) { 297 | s := fmt.Sprintf(format, v...) 298 | l.Output("panic", s) 299 | panic(s) 300 | } 301 | 302 | // Panicln is equivalent to l.Println() followed by a call to panic(). 303 | // Jordan: added panic as a level so it can show up in formatted logs 304 | func (l *Logger) Panicln(v ...interface{}) { 305 | s := fmt.Sprintln(v...) 306 | l.Output("panic", s) 307 | panic(s) 308 | } 309 | 310 | // Flags returns the output flags for the logger. 311 | // The flag bits are Ldate, Ltime, and so on. 312 | func (l *Logger) Flags() int { 313 | l.mu.Lock() 314 | defer l.mu.Unlock() 315 | return l.flag 316 | } 317 | 318 | // SetFlags sets the output flags for the logger. 319 | // The flag bits are Ldate, Ltime, and so on. 320 | func (l *Logger) SetFlags(flag int) { 321 | l.mu.Lock() 322 | defer l.mu.Unlock() 323 | l.flag = flag 324 | } 325 | 326 | // Prefix returns the output prefix for the logger. 327 | func (l *Logger) Prefix() string { 328 | l.mu.Lock() 329 | defer l.mu.Unlock() 330 | return l.prefix 331 | } 332 | 333 | // SetPrefix sets the output prefix for the logger. 334 | func (l *Logger) SetPrefix(prefix string) { 335 | l.mu.Lock() 336 | defer l.mu.Unlock() 337 | l.prefix = prefix 338 | } 339 | 340 | // Writer returns the output destination for the logger. 341 | func (l *Logger) Writer() io.Writer { 342 | l.mu.Lock() 343 | defer l.mu.Unlock() 344 | return l.out 345 | } 346 | 347 | // SetOutput sets the output destination for the standard logger. 348 | func SetOutput(w io.Writer) { 349 | std.mu.Lock() 350 | defer std.mu.Unlock() 351 | std.out = w 352 | } 353 | 354 | // Flags returns the output flags for the standard logger. 355 | // The flag bits are Ldate, Ltime, and so on. 356 | func Flags() int { 357 | return std.Flags() 358 | } 359 | 360 | // SetFlags sets the output flags for the standard logger. 361 | // The flag bits are Ldate, Ltime, and so on. 362 | func SetFlags(flag int) { 363 | std.SetFlags(flag) 364 | } 365 | 366 | // Prefix returns the output prefix for the standard logger. 367 | func Prefix() string { 368 | return std.Prefix() 369 | } 370 | 371 | // SetPrefix sets the output prefix for the standard logger. 372 | func SetPrefix(prefix string) { 373 | std.SetPrefix(prefix) 374 | } 375 | 376 | // Writer returns the output destination for the standard logger. 377 | func Writer() io.Writer { 378 | return std.Writer() 379 | } 380 | 381 | // These functions write to the standard logger. 382 | 383 | // Print calls Output to print to the standard logger. 384 | // Arguments are handled in the manner of fmt.Print. 385 | func Print(v ...interface{}) { 386 | std.Output("", fmt.Sprint(v...)) 387 | } 388 | 389 | // Printf calls Output to print to the standard logger. 390 | // Arguments are handled in the manner of fmt.Printf. 391 | func Printf(format string, v ...interface{}) { 392 | std.Output("", fmt.Sprintf(format, v...)) 393 | } 394 | 395 | // Println calls Output to print to the standard logger. 396 | // Arguments are handled in the manner of fmt.Println. 397 | func Println(v ...interface{}) { 398 | std.Output("", fmt.Sprintln(v...)) 399 | } 400 | 401 | // Fatal is equivalent to Print() followed by a call to os.Exit(1). 402 | // Jordan: added fatal as a level so it can show up in formatted logs 403 | func Fatal(v ...interface{}) { 404 | std.Output("fatal", fmt.Sprint(v...)) 405 | os.Exit(1) 406 | } 407 | 408 | // Fatalf is equivalent to Printf() followed by a call to os.Exit(1). 409 | // Jordan: added fatal as a level so it can show up in formatted logs 410 | func Fatalf(format string, v ...interface{}) { 411 | std.Output("fatal", fmt.Sprintf(format, v...)) 412 | os.Exit(1) 413 | } 414 | 415 | // Fatalln is equivalent to Println() followed by a call to os.Exit(1). 416 | // Jordan: added fatal as a level so it can show up in formatted logs 417 | func Fatalln(v ...interface{}) { 418 | std.Output("fatal", fmt.Sprintln(v...)) 419 | os.Exit(1) 420 | } 421 | 422 | // Panic is equivalent to Print() followed by a call to panic(). 423 | // Jordan: added panic as a level so it can show up in formatted logs 424 | func Panic(v ...interface{}) { 425 | s := fmt.Sprint(v...) 426 | std.Output("panic", s) 427 | panic(s) 428 | } 429 | 430 | // Panicf is equivalent to Printf() followed by a call to panic(). 431 | // Jordan: added panic as a level so it can show up in formatted logs 432 | func Panicf(format string, v ...interface{}) { 433 | s := fmt.Sprintf(format, v...) 434 | std.Output("panic", s) 435 | panic(s) 436 | } 437 | 438 | // Panicln is equivalent to Println() followed by a call to panic(). 439 | // Jordan: added panic as a level so it can show up in formatted logs 440 | func Panicln(v ...interface{}) { 441 | s := fmt.Sprintln(v...) 442 | std.Output("panic", s) 443 | panic(s) 444 | } 445 | 446 | // Output writes the output for a logging event. The string s contains 447 | // the text to print after the prefix specified by the flags of the 448 | // Logger. A newline is appended if the last character of s is not 449 | // already a newline. Calldepth is the count of the number of 450 | // frames to skip when computing the file name and line number 451 | // if Llongfile or Lshortfile is set; a value of 1 will print the details 452 | // for the caller of Output. 453 | // Jordan: calldepth is set on the object so passing in empty levels 454 | func Output(level string, s string) error { 455 | return std.Output("level", s) // +1 for this frame. 456 | } 457 | 458 | // ---------------------------------------------------------------------- 459 | // 460 | // Jordan: My changes to enable logging levels 461 | // 462 | // ---------------------------------------------------------------------- 463 | 464 | // SetCallDepth - This function will set the call depth. By default the call 465 | // depth is set at 2. A depth of 2 represents the behavior of the standard 466 | // library. 467 | func (l *Logger) SetCallDepth(d int) { 468 | l.calldepth = d 469 | } 470 | 471 | // SetCallDepth - This function will set the call depth. By default the call 472 | // depth is set at 2. A depth of 2 represents the behavior of the standard 473 | // library. 474 | func SetCallDepth(d int) { 475 | std.SetCallDepth(d) 476 | } 477 | 478 | // EnableLevel - This function will enable the output from the supplied logging 479 | // level 480 | func (l *Logger) EnableLevel(level string) { 481 | l.levels[level] = true 482 | } 483 | 484 | // EnableLevel - This function will enable the output from the supplied logging 485 | // level 486 | func EnableLevel(level string) { 487 | std.EnableLevel(level) 488 | } 489 | 490 | // DisableLevel - This function will disable the output from the supplied 491 | // logging level 492 | func (l *Logger) DisableLevel(level string) { 493 | if _, ok := l.levels[level]; ok { 494 | l.levels[level] = false 495 | } 496 | } 497 | 498 | // DisableLevel - This function will disable the output from the supplied 499 | // logging level 500 | func DisableLevel(level string) { 501 | std.DisableLevel(level) 502 | } 503 | 504 | // GetLevel - This function will return the state of a given level 505 | func (l *Logger) GetLevel(level string) bool { 506 | if _, ok := l.levels[level]; ok { 507 | return l.levels[level] 508 | } 509 | return false 510 | } 511 | 512 | // GetLevel - This function will return the state of a given level 513 | func GetLevel(level string) bool { 514 | return std.GetLevel(level) 515 | } 516 | 517 | // EnableFormattedPrefix - This function will enable the formatted prefix in output 518 | func (l *Logger) EnableFormattedPrefix() { 519 | l.formattedPrefix = true 520 | } 521 | 522 | // EnableFormattedPrefix - This function will enable the formatted prefix in output 523 | func EnableFormattedPrefix() { 524 | std.formattedPrefix = true 525 | } 526 | 527 | // EnableLevelsByNumber - This function will enable logging levels by number 528 | func (l *Logger) EnableLevelsByNumber(num int) { 529 | switch num { 530 | case 1: 531 | l.EnableLevel("panic") 532 | l.EnableLevel("fatal") 533 | case 2: 534 | l.EnableLevel("panic") 535 | l.EnableLevel("fatal") 536 | l.EnableLevel("error") 537 | case 3: 538 | l.EnableLevel("panic") 539 | l.EnableLevel("fatal") 540 | l.EnableLevel("error") 541 | l.EnableLevel("warn") 542 | case 4: 543 | l.EnableLevel("panic") 544 | l.EnableLevel("fatal") 545 | l.EnableLevel("error") 546 | l.EnableLevel("warn") 547 | l.EnableLevel("info") 548 | case 5: 549 | l.EnableLevel("panic") 550 | l.EnableLevel("fatal") 551 | l.EnableLevel("error") 552 | l.EnableLevel("warn") 553 | l.EnableLevel("info") 554 | l.EnableLevel("debug") 555 | case 10: 556 | l.EnableLevel("panic") 557 | l.EnableLevel("fatal") 558 | l.EnableLevel("error") 559 | l.EnableLevel("warn") 560 | l.EnableLevel("info") 561 | l.EnableLevel("debug") 562 | l.EnableLevel("trace") 563 | } 564 | return 565 | } 566 | 567 | // EnableLevelsByNumber - This function will enable logging levels by number 568 | func EnableLevelsByNumber(num int) { 569 | std.EnableLevelsByNumber(num) 570 | } 571 | 572 | // DisableAllLevels - This function will the output from all logging level 573 | func (l *Logger) DisableAllLevels() { 574 | for k := range l.levels { 575 | l.levels[k] = false 576 | } 577 | } 578 | 579 | // DisableAllLevels - This function will the output from all logging level 580 | func DisableAllLevels() { 581 | std.DisableAllLevels() 582 | } 583 | 584 | // ---------------------------------------------------------------------- 585 | // New logger functions and methods 586 | // ---------------------------------------------------------------------- 587 | 588 | // Error - This function calls Output to print to the standard logger. Arguments 589 | // are handled in the manner of fmt.Print. 590 | func (l *Logger) Error(v ...interface{}) { 591 | l.Output("error", fmt.Sprint(v...)) 592 | } 593 | 594 | // Errorf - This function calls Output to print to the standard logger. 595 | // Arguments are handled in the manner of fmt.Printf. 596 | func (l *Logger) Errorf(format string, v ...interface{}) { 597 | l.Output("error", fmt.Sprintf(format, v...)) 598 | } 599 | 600 | // Errorln - This function calls Output to print to the standard logger. 601 | // Arguments are handled in the manner of fmt.Println. 602 | func (l *Logger) Errorln(v ...interface{}) { 603 | l.Output("error", fmt.Sprintln(v...)) 604 | } 605 | 606 | // Warn - This function calls Output to print to the standard logger. Arguments 607 | // are handled in the manner of fmt.Print. 608 | func (l *Logger) Warn(v ...interface{}) { 609 | l.Output("warn", fmt.Sprint(v...)) 610 | } 611 | 612 | // Warnf - This function calls Output to print to the standard logger. Arguments 613 | // are handled in the manner of fmt.Printf. 614 | func (l *Logger) Warnf(format string, v ...interface{}) { 615 | l.Output("warn", fmt.Sprintf(format, v...)) 616 | } 617 | 618 | // Warnln - This function calls Output to print to the standard logger. 619 | // Arguments are handled in the manner of fmt.Println. 620 | func (l *Logger) Warnln(v ...interface{}) { 621 | l.Output("warn", fmt.Sprintln(v...)) 622 | } 623 | 624 | // Info - This function calls Output to print to the standard logger. Arguments 625 | // are handled in the manner of fmt.Print. 626 | func (l *Logger) Info(v ...interface{}) { 627 | l.Output("info", fmt.Sprint(v...)) 628 | } 629 | 630 | // Infof - This function calls Output to print to the standard logger. Arguments 631 | // are handled in the manner of fmt.Printf. 632 | func (l *Logger) Infof(format string, v ...interface{}) { 633 | l.Output("info", fmt.Sprintf(format, v...)) 634 | } 635 | 636 | // Infoln - This function calls Output to print to the standard logger. 637 | // Arguments are handled in the manner of fmt.Println. 638 | func (l *Logger) Infoln(v ...interface{}) { 639 | l.Output("info", fmt.Sprintln(v...)) 640 | } 641 | 642 | // Debug - This function calls Output to print to the standard logger. Arguments 643 | // are handled in the manner of fmt.Print. 644 | func (l *Logger) Debug(v ...interface{}) { 645 | l.Output("debug", fmt.Sprint(v...)) 646 | } 647 | 648 | // Debugf - This function calls Output to print to the standard logger. 649 | // Arguments are handled in the manner of fmt.Printf. 650 | func (l *Logger) Debugf(format string, v ...interface{}) { 651 | l.Output("debug", fmt.Sprintf(format, v...)) 652 | } 653 | 654 | // Debugln - This function calls Output to print to the standard logger. 655 | // Arguments are handled in the manner of fmt.Println. 656 | func (l *Logger) Debugln(v ...interface{}) { 657 | l.Output("debug", fmt.Sprintln(v...)) 658 | } 659 | 660 | // Trace - This function calls Output to print to the standard logger. Arguments 661 | // are handled in the manner of fmt.Print. 662 | func (l *Logger) Trace(v ...interface{}) { 663 | l.Output("trace", fmt.Sprint(v...)) 664 | } 665 | 666 | // Tracef - This function calls Output to print to the standard logger. 667 | // Arguments are handled in the manner of fmt.Printf. 668 | func (l *Logger) Tracef(format string, v ...interface{}) { 669 | l.Output("trace", fmt.Sprintf(format, v...)) 670 | } 671 | 672 | // Traceln - This function calls Output to print to the standard logger. 673 | // Arguments are handled in the manner of fmt.Println. 674 | func (l *Logger) Traceln(v ...interface{}) { 675 | l.Output("trace", fmt.Sprintln(v...)) 676 | } 677 | 678 | // Level - This function calls Output to print to the standard logger. The first 679 | // parameter is a logging level, this allows the printing of arbitrary logging 680 | // levels. Arguments are handled in the manner of fmt.Print. 681 | func (l *Logger) Level(level string, v ...interface{}) { 682 | l.Output(level, fmt.Sprint(v...)) 683 | } 684 | 685 | // Levelf - This function calls Output to print to the standard logger. The 686 | // first parameter is a logging level, this allows the printing of arbitrary 687 | // logging levels. Arguments are handled in the manner of fmt.Printf. 688 | func (l *Logger) Levelf(level, format string, v ...interface{}) { 689 | l.Output(level, fmt.Sprintf(format, v...)) 690 | } 691 | 692 | // Levelln - This function calls Output to print to the standard logger. The 693 | // first parameter is a logging level, this allows the printing of arbitrary 694 | // logging levels. Arguments are handled in the manner of fmt.Println. 695 | func (l *Logger) Levelln(level string, v ...interface{}) { 696 | l.Output(level, fmt.Sprintln(v...)) 697 | } 698 | 699 | // Error - This function calls Output to print to the standard logger. Arguments 700 | // are handled in the manner of fmt.Print. 701 | func Error(v ...interface{}) { 702 | std.Output("error", fmt.Sprint(v...)) 703 | } 704 | 705 | // Errorf - This function calls Output to print to the standard logger. 706 | // Arguments are handled in the manner of fmt.Printf. 707 | func Errorf(format string, v ...interface{}) { 708 | std.Output("error", fmt.Sprintf(format, v...)) 709 | } 710 | 711 | // Errorln - This function calls Output to print to the standard logger. 712 | // Arguments are handled in the manner of fmt.Println. 713 | func Errorln(v ...interface{}) { 714 | std.Output("error", fmt.Sprintln(v...)) 715 | } 716 | 717 | // Warn - This function calls Output to print to the standard logger. Arguments 718 | // are handled in the manner of fmt.Print. 719 | func Warn(v ...interface{}) { 720 | std.Output("warn", fmt.Sprint(v...)) 721 | } 722 | 723 | // Warnf - This function calls Output to print to the standard logger. Arguments 724 | // are handled in the manner of fmt.Printf. 725 | func Warnf(format string, v ...interface{}) { 726 | std.Output("warn", fmt.Sprintf(format, v...)) 727 | } 728 | 729 | // Warnln - This function calls Output to print to the standard logger. 730 | // Arguments are handled in the manner of fmt.Println. 731 | func Warnln(v ...interface{}) { 732 | std.Output("warn", fmt.Sprintln(v...)) 733 | } 734 | 735 | // Info - This function calls Output to print to the standard logger. Arguments 736 | // are handled in the manner of fmt.Print. 737 | func Info(v ...interface{}) { 738 | std.Output("info", fmt.Sprint(v...)) 739 | } 740 | 741 | // Infof - This function calls Output to print to the standard logger. Arguments 742 | // are handled in the manner of fmt.Printf. 743 | func Infof(format string, v ...interface{}) { 744 | std.Output("info", fmt.Sprintf(format, v...)) 745 | } 746 | 747 | // Infoln - This function calls Output to print to the standard logger. 748 | // Arguments are handled in the manner of fmt.Println. 749 | func Infoln(v ...interface{}) { 750 | std.Output("info", fmt.Sprintln(v...)) 751 | } 752 | 753 | // Debug - This function calls Output to print to the standard logger. Arguments 754 | // are handled in the manner of fmt.Print. 755 | func Debug(v ...interface{}) { 756 | std.Output("debug", fmt.Sprint(v...)) 757 | } 758 | 759 | // Debugf - This function calls Output to print to the standard logger. 760 | // Arguments are handled in the manner of fmt.Printf. 761 | func Debugf(format string, v ...interface{}) { 762 | std.Output("debug", fmt.Sprintf(format, v...)) 763 | } 764 | 765 | // Debugln - This function calls Output to print to the standard logger. 766 | // Arguments are handled in the manner of fmt.Println. 767 | func Debugln(v ...interface{}) { 768 | std.Output("debug", fmt.Sprintln(v...)) 769 | } 770 | 771 | // Trace - This function calls Output to print to the standard logger. Arguments 772 | // are handled in the manner of fmt.Print. 773 | func Trace(v ...interface{}) { 774 | std.Output("trace", fmt.Sprint(v...)) 775 | } 776 | 777 | // Tracef - This function calls Output to print to the standard logger. 778 | // Arguments are handled in the manner of fmt.Printf. 779 | func Tracef(format string, v ...interface{}) { 780 | std.Output("trace", fmt.Sprintf(format, v...)) 781 | } 782 | 783 | // Traceln - This function calls Output to print to the standard logger. 784 | // Arguments are handled in the manner of fmt.Println. 785 | func Traceln(v ...interface{}) { 786 | std.Output("trace", fmt.Sprintln(v...)) 787 | } 788 | 789 | // Level - This function calls Output to print to the standard logger. The first 790 | // parameter is a logging level, this allows the printing of arbitrary logging 791 | // levels. Arguments are handled in the manner of fmt.Print. 792 | func Level(level string, v ...interface{}) { 793 | std.Output(level, fmt.Sprint(v...)) 794 | } 795 | 796 | // Levelf - This function calls Output to print to the standard logger. The 797 | // first parameter is a logging level, this allows the printing of arbitrary 798 | // logging levels. Arguments are handled in the manner of fmt.Printf. 799 | func Levelf(level, format string, v ...interface{}) { 800 | std.Output(level, fmt.Sprintf(format, v...)) 801 | } 802 | 803 | // Levelln - This function calls Output to print to the standard logger. The 804 | // first parameter is a logging level, this allows the printing of arbitrary 805 | // logging levels. Arguments are handled in the manner of fmt.Println. 806 | func Levelln(level string, v ...interface{}) { 807 | std.Output(level, fmt.Sprintln(v...)) 808 | } 809 | 810 | // ---------------------------------------------------------------------- 811 | --------------------------------------------------------------------------------