You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
4.7 KiB

/*
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)
}