/* Package log implements logging with two levels: info and debug. This distillation implements Dave Cheney's recommendation in his blog post, "Let's talk about logging" [1]. The methods provided are intended to mimic the most useful parts of the fmt and log standard packages. The easiest way to use this package is to just call the top-level Print-ish and Debug-ish functions. If you need to write to another writer than Stdout, replace Default: log.Default = log.Writer(myWriter, "[DEBUG]", "[INFO]") If you want to, say, write to two files for the two levels, implement Interface. For an example, see how the Writer function is implemented. [1] http://dave.cheney.net/2015/11/05/lets-talk-about-logging */ package log import ( "fmt" "io" "os" ) var ( // Stdout is os.Stdout wrapped as an Interface. Stdout = Writer(os.Stdout, "[debug]", "[info]") // Stderr is os.Stderr wrapped as an Interface. Stderr = Writer(os.Stderr, "[debug]", "[info]") // Default is a Log that writes to Stdout. Default = Log{Stdout} ) // Print writes to the default logger. Arguments are handled in the manner of fmt.Sprint. func Print(v ...interface{}) { Default.Print(fmt.Sprint(v...)) } // Printf writes to the default logger. Arguments are handled in the manner of fmt.Sprintf. func Printf(format string, v ...interface{}) { Default.Print(fmt.Sprintf(format, v...)) } // Println writes to the default logger. Arguments are handled in the manner of fmt.Sprintln. func Println(v ...interface{}) { Default.Print(fmt.Sprintln(v...)) } // Debug writes to the default logger. Arguments are handled in the manner of fmt.Sprint. func Debug(v ...interface{}) { Default.Debug(fmt.Sprint(v...)) } // Debugf writes to the default logger. Arguments are handled in the manner of fmt.Sprintf. func Debugf(format string, v ...interface{}) { Default.Debug(fmt.Sprintf(format, v...)) } // Debugln writes to the default logger. Arguments are handled in the manner of fmt.Sprintln. func Debugln(v ...interface{}) { Default.Debug(fmt.Sprintln(v...)) } // Log provides standard logging methods from a custom Interface. The zero value // uses Stdout. type Log struct { Interface } // Print writes to l.Interface, or Stdout if l.Interface is nil. Arguments are handled in the manner of fmt.Sprint. func (l Log) Print(v ...interface{}) { validInterface(l.Interface).Print(fmt.Sprint(v...)) } // Printf writes to l.Interface, or Stdout if l.Interface is nil. Arguments are handled in the manner of fmt.Sprintf. func (l Log) Printf(format string, v ...interface{}) { validInterface(l.Interface).Print(fmt.Sprintf(format, v...)) } // Println writes to l.Interface, or Stdout if l.Interface is nil. Arguments are handled in the manner of fmt.Sprintln. func (l Log) Println(v ...interface{}) { validInterface(l.Interface).Print(fmt.Sprintln(v...)) } // Debug writes to l.Interface, or Stdout if l.Interface is nil. Arguments are handled in the manner of fmt.Sprint. func (l Log) Debug(v ...interface{}) { validInterface(l.Interface).Debug(fmt.Sprint(v...)) } // Debugf writes to l.Interface, or Stdout if l.Interface is nil. Arguments are handled in the manner of fmt.Sprintf. func (l Log) Debugf(format string, v ...interface{}) { validInterface(l.Interface).Debug(fmt.Sprintf(format, v...)) } // Debugln writes to l.Interface, or Stdout if l.Interface is nil. Arguments are handled in the manner of fmt.Sprintln. func (l Log) Debugln(v ...interface{}) { validInterface(l.Interface).Debug(fmt.Sprintln(v...)) } // validInterface checks if i is nil. If it is, this returns // Stdout, otherwise it returns i. func validInterface(i Interface) Interface { if i == nil { return Stdout } return i } // Interface is the set of methods implemented by custom loggers for outputting data. An implementation // of Interface could, for instance, write Debug messages to a file and send Print statements both to a // file and to an IRC channel. type Interface interface { Print(s string) Debug(s string) } // Writer returns an Interface with the given debug and info prefixes that // write to w. func Writer(w io.Writer, debug, info string) Interface { return writerInterface{ debug: debug, info: info, wDebug: w, wInfo: w, } } // Writers returns an Interface with the given debug and info prefixes that // write to wDebug and wInfo respectively. func Writers(wDebug, wInfo io.Writer, debug, info string) Interface { return writerInterface{ debug: debug, info: info, wDebug: wDebug, wInfo: wInfo, } } type writerInterface struct { debug, info string wDebug, wInfo io.Writer } func (w writerInterface) Print(v string) { fmt.Fprint(w.wInfo, w.info, v) } func (w writerInterface) Debug(v string) { fmt.Fprint(w.wDebug, w.debug, v) }